変奏現実

パソコンやMMORPGのことなどを思いつくまま・・・記載されている会社名・製品名・システム名などは、各社の商標、または登録商標です。

この画面は、簡易表示です

javascript

【javascript】Spread in destructuring

沢山の引数をまとめて渡す方法

すぐ思いつく方法としては、
自前の関数を

aaa({ a: 111,b:222, c:333, d:444});

そして、渡して関数の方も

function aaa(json) {
  console.log(json.a);
  ...
  console.log(json.d);
}

とすればいい。
しかし、関数の方は<script src=”http:…”>な感じの場合は書き換え不能だ。

調べてみると

function myFunction(x, y, z) { }
  var args = [0, 1, 2];
  myFunction.apply(null, args);

と書くのが普通らしい。IEでも動くそうだ。※動作未確認。
applyの最初のパラメータはthisで、 普通の関数ではnullになる。
2番目に引数リストを渡す。

今は、スプレッド構文「関数名(変数)な形式」で関数を呼び出す書き方もあった。

aaa(a,b,c,d) な感じの関数のパラメータをまとめて渡すには

var args =[a,b,c,d];

または

var  args = [];
args . push(a);
...
args.push(d);

で、配列に詰め込んで

aaa(...args);

難点を云えば、Edgeは動いたが、IEではダメらしい。



javascript

jQueryを使わなくてもCSSのセレクタの指定方法でDOMオブジェクトを取得できる。

dom-Object = document. querySelector (セレクタ)

セレクタの書式は、
#xxx で id属性
.xxxで class属性
xxxで 要素 (タグ )名
を指定できる
xxx yyy と空白で間を開けると、 xxxの子孫のyyyの意味
xxx>yyy と>で間を開けると、 xxxの直下のyyyの意味
xxx+yyy と+で間を開けると、 xxxの直後のyyyの意味
xxx, yyy とカンマで区切ると、xxxまたはyyyの意味

あと、xxx:yyyの書き方で、xxxの疑似要素または 擬似クラスyyyの意味

疑似要素には、
・要素名:first-line 要素の最初の一行
・要素名:first-letter 要素の最初の一文字
・要素名:before   要素の直前
・要素名:after    要素の直後

疑似クラスには、
・要素名:link 未訪問のリンク
・要素名:visited 訪問済のリンク
・要素名:hover カーソルが乗っている要素
・要素名:active クリック中の要素
・要素名:focus フォーカスされている要素
・要素名:lang 特定の言語を指定した要素
・要素名:first-child 要素内の最初の子要素

となるらしい。

要素.addEventListener( type, listener, option) でイベントを追加できる

type には
・ load Webページの読み込みが完了した時
・ DOMContentLoaded Webページが読み込みが完了した時
・ click マウスボタンをクリックした時
・ mousedown マウスボタンを押している時
・ mouseup マウスボタンを離した 時
・ mousemove マウスカーソルが移動した時
・ keydown キーボードのキーを押した 時
・ keyup キーボードのキーを離した 時
・ keypress キーボードのキーを押している時
・ change フォーム部品の状態が変更された時
・ submmit フォームのsubmitボタンを押した 時
・ scroll 画面がスクロールした時

listenerには function(..) { }で書く

optionには通常はfalseを指定するが、追加した listener を優先して処理する意味。

optionに、capture、once、passiveを指定するには連想リストで指定する。
{ passive: true }



prototype と static

javascriptでクラスっぽいものにしたい場合
メンバーをprototypeにメンバー関数を追加する。

sjis.prototype.xxx = function() {
alert("OK");
};

ところがこの宣言したメンバーをメンバーから参照すると

sjis.prototype.yyy = function() {
xxx();
alert("OK");
};

とundefinedとなってしまうことがある。
通常のfunction 定義は、jsファイルを読み切ってから実行するので参照先は後に書いても問題ないけど、
無名関数の場合は、その場で組み込んでしまうようで、参照するメンバーは先に記述しないとダメらしい。
 
クラス宣言っぽいことはできるけど
private、protected、staticなメンバーは作れないのも痛い。
それっぽいやり方はいくつか見つけたけど
基本は、prototype に入れる方法なのでチョット扱いが大変。
それくらいなら、
var   クラス名_STATIC_メンバー名=null;
と書いた方が楽。



デスクトップに貼ったJSからSJISのCSVをダウンロードさせてみる 改訂2018/10/2

サーバーサイドでSJISにエンコードすること自体どうにでもなる。
しかし、デスクトップにHTMLとJavaScriptだけ貼ってローカルにあるテキストをCSVファイルとしてダウンロードさせようとすると、
JavaScriptのテキストはUnicode(16Bit)なので、そのまま出力するとEXCELで読むと文字化けする。
JavaScriptでは、SJISをUnicode(16Bit)に変換する機能はあるが、Unicode(16Bit)をSJISにする機能は無い。
JScriptならWindowsのドコかにStrSonvがあれば拾って来ればいいのかもしれない。
今風なら既に【外部のJSファイル(延々と長いコード表が載っている)】があるのだから、これを借りるのが普通。
しかし、今のブラウザは大抵のコードページならUnicode(16Bit)に変換できる能力を持っているのでコレを使って逆変換テーブルを作ってもいい。
SJISの文字の入ったバイナリーなイメージを作り、Readerに読ませ、Unicode(16Bit)に変換させた結果を、Unicode(16Bit)のコードをキーワードにSJISのコードを得られるArrayに詰め込めばいいハズだ。難しいのはUnicode(16Bit)しか使えないJavaScriptの上でどうやってSJISのイメージを作るのかというあたりと、SJISのコード表で有効な範囲だけイメージを作ること。
0x80など未定義になっている部分のイメージが混ざると・・・続くバイトを全角の2バイトと思って変換され文字化けてしまうし、また変換できなかった文字が空白に変換された場合、最後に変換できなかった文字がコード表の「空白」を上書きしてしまい派手な文字化けの原因になる。
それでも、MakeConvert16bitTable や file_reader.readAsText(b,”SJIS”); をゴニョればeuc-jpもできるはずだ。
16ビット領域の文字コード表を作るとループしまくるのでとても遅くなりそうな気がしたけど、今のパソコンならどうということはないらしい。
これでデータベース用のコード変換表もできるハズ。

//Unicode16 - SJIS文字コード表
var utf16Ar=null;
//画面表示直後(onload)に文字コード表を作るMakeSJISConvertの呼び出しが消えないオマジナイ
if( window.addEventListener ) {
  window.addEventListener( 'load', MakeSJISConvert, false );
} else if( window.attachEvent ) {
  window.attachEvent( 'onload', MakeSJISConvert );
} else {
  window.onload = MakeSJISConvert;
}
// Unicode を SJISに変換する
function UTF16toSJIS(utf16) {
  try{
    //コード表作成時に未定義文字をしていした時のオマジナイ
    utf16Ar[" "] = " ";
    //コード表作成時に未定義文字をしていした時のオマジナイ
    utf16Ar[undefined] = " ";
    var a = utf16.split('');
    var buf = new Uint8Array(a.length * 2);
    var j=0;
    for(var i=0; i< a.length; i++) {
      var ch = utf16Ar[a[i]];
      if(ch === undefined) {
        buf[j++] = (0x20);
      } else {
        var chH = ((ch>>8) & 0x0ff);
        var chL = ( ch     & 0x0ff);
        buf[j++] = chL;
        if( chH != 0) {
          buf[j++] = chH;
        }
      }
    }
    var rc = new Uint8Array(j);
    for(var i=0; i<j; i++) {
      rc[i] = buf[i];
    }
    return rc;
  } catch(e) {
    alert(e);
  }
}
//Unicode16 - SJIS文字コード表(utf16Ar)の作成
function MakeSJISConvert() {
  MakeConvert8bitTable();
  MakeConvert16bitTable();
}
//Unicode16 - SJIS文字コード表(utf16Ar)の16bit文字コード分の作成
function MakeConvert16bitTable() {
  //SJISで文字コードに指定している領域のみ作成すること
  MakeConvert16bitSubTable(0x0081,0x009f,0x0040,0x007e);
  MakeConvert16bitSubTable(0x00e0,0x00ef,0x0040,0x007e);
  MakeConvert16bitSubTable(0x0081,0x009f,0x0080,0x00fc);
  MakeConvert16bitSubTable(0x00e0,0x00ef,0x0080,0x00fc);
}
//変換処理の呼び出し回数
var callCount=0;
var transferCharCodeCount=0;
var undefined8BitCount=0;
var undefined16BitCount=0;
var throw16BitCount=0;
//Unicode16 - SJIS文字コード表(utf16Ar)の8bit文字コード分の作成
function MakeConvert8bitTable() {
  try {
    // 8bit area
    var buffer1 = new Uint8Array(256);
    for(var i=0; i<256; i++) {
      if(0x00<=i && i <= 0x1f) {
        switch(i) {
        case  9 : case 10 : case 13 ://制御コードはCSVで使用するTAB,CR,LFだけ登録
          buffer1[i] = i;
          break;
        default://制御コードはCSVで使用するTAB,CR,LF以外は空白として登録
          buffer1[i]=" ";
          break;
        }
      } else if(0x80<=i && i <=0xa0) {//CSVで使わないコードは空白にする
        buffer1[i]=" ";
      } else if(0xe0<=i && i <=0xff) {//CSVで使わないコードは空白にする
        buffer1[i]=" ";
      } else {
        buffer1[i] = i;
      }
    }
    var b = new Blob( [buffer1], {type: "application/octet-stream"});
    var file_reader = new FileReader();
    file_reader.onload = function(e) {
      var sjisAr = e.target.result;
      utf16Ar = new Array();
      for(var i=0;i<256;i++) {
        var utf16 = sjisAr.substr(i,1);
        if(utf16!==undefined){
          if( utf16Ar[utf16] != buffer1[i] ) transferCharCodeCount++;
          utf16Ar[utf16] = buffer1[i];
        } else {
          undefined8BitCount++;
        }
      }
    }
    file_reader.readAsText(b,"SJIS");
  } catch(e) {
    alert(e);
  }
}
//Unicode16 - SJIS文字コード表(utf16Ar)の8bit文字コード分の作成
function MakeConvert16bitSubTable(hiBegin,hiEnd,lowBegin,lowEnd) {
  try {
    // 16bit area
    callCount++;
    var sizeHi  = ( hiEnd  - hiBegin  + 1 );
    if(isNaN(sizeHi)) { alert("Nan sizeHi"); }
    var sizeLow = ( lowEnd - lowBegin + 1 );
    if(isNaN(sizeLow)) { alert("Nan sizeLow"); }
    var sizeAr  = sizeHi * sizeLow;
    if(isNaN(sizeAr)) { alert("Nan sizeHi,sizeHi("+sizeHi+") * sizeLow("+sizeLow+")"); }
    var buffer1 = new Uint16Array(sizeAr);
    var n1=0;
    var tx = "";
    for(var hi=hiBegin; hi<=hiEnd; hi++) {
      for(var low=lowBegin; low<=lowEnd; low++) {
        buffer1[n1++] = (hi & 0x0ff) + ((low <<8) & 0x0ff00);
      }
    }
    var b = new Blob( [buffer1], {type: "application/octet-stream"});
    var file_reader = new FileReader();
    file_reader.onload = function(e) {
      var sjisAr = e.target.result;
      var i=0;
      for(var hi=hiBegin; hi<=hiEnd; hi++) {
        for(var low=lowBegin; low<=lowEnd; low++) {
          var sjis = (hi & 0x0ff) + ((low <<8) & 0x0ff00);
          var utf16 = sjisAr.substr(i++,1);
          if(utf16!==undefined){
          try {//Unicode16で扱えない文字かどうかチェック
            if(utf16.charCodeAt(0).toString(16)!="3000") {
              var test = "【" + utf16 + "】" + utf16.charCodeAt(0).toString(16);
            }
            if( utf16Ar[utf16] != sjis ) transferCharCodeCount++;//登録した文字数を数えてる
            utf16Ar[utf16] = sjis;
          } catch(e) {//Unicode16で扱えない文字は無視
            alert(e+"sjis="+sjis);
            throw16BitCount++;
          }
          } else {
            undefined16BitCount++;
          }
        }
      }
    }
    file_reader.readAsText(b,"SJIS");
  } catch(e) {
    alert("MakeConvert16bitTable():"+e);
  }
}

CSVをダウンロードするコードは、

//JavaScriptはUnicode(16bit)なので、
//htmlに<input type='button' onclick='exportData("漢字\tあいうえお\tカキクケコ\r\n")'>と書いて呼び出す。
//\tがデリミタとして判定されない場合は , に変える。
function exportData(unicode16CSV) {
  var sjis = UTF16toSJIS(unicode16CSV);
  var blob = new Blob([sjis], {type: "application/octet-stream"});
  var url = URL.createObjectURL(blob);
//ここはHTMLにダウンロード用のaタグを貼っておいて再利用した方がいい。
  var a = document.querySelector("#results");
  a.href = url;
  a.download = "シフトJISコードで作ったCSVファイル.csv";
  a.text="re-download";
  a.click();
}

日本語のファイル名でダウンロードするとファイル名が文字化けするブラウザもあるだろう
画面でCSVデータを編集してCSVにするサンプル
↑2018/10/2修正済(あるいは改悪済)
〇 FireFox(62.0.2 (64ビット)),Chrome(バージョン: 69.0.3497.100(Official Build) (64 ビット)),IE Ege(バージョン不明)で治ってるように見えた。
× IEではダウンロード不可だった。
ps.2018/1/4
今では文字化けしている。サロゲートペアを考慮していないせいだと思うけど・・・
※サロゲートペア:16ビット固定の文字表現であったUnicodeので未使用でだった0xD800~0xDBFFを上位サロゲート、0xDC00~0xDFFFを下位サロゲートとし、上位サロゲート+下位サロゲートの4バイトで文字を表現する文字を拡張したものがUTF-16らしい。
※2018/10/2 FireFoxで8ビットコードが化けまくっていたので以下修正。
おかしくなっていた原因は、
(1)16ビット文字のマップを作るつもりが、英字が半角文字に変換されていた。⇒マップに登録済みの文字は無視する。
⇒まだ、上位ビットがFF(1111)の文字だけ、うまく変換できない。
「a」(0xff41)は、なぜか成功するけど
「U」(0x0ff35)は「ガ」に、
「1」(0x0ff11)が「・」に
なってしまう」。
(2)nullコードは’\u0000’で判定しないとダメだった。
(3)ダウンロード用に作成したSJIS(バイナリー)データにnullが混じっていた⇒null部分はカット。

var utf16Ar;
function UTF16toSJIS(utf16) {
  try{
    var i = 0;
    var a = utf16.split('');
    //alert(a.length);
    var rc = new Uint8Array(a.length*2);
    var countSP=0;
    var ch16=null;
    var j=0;
    for(var i=0; i< a.length; i++) {
      var ch = a[i];
      if(utf16Ar[ch.charCodeAt(0)] === undefined)
        rc[j++] = (0x20);
      else
        ch16 = (utf16Ar[ch.charCodeAt(0)]);
      if((ch16 >> 8)==0) {
        rc[j++] = ch16;
        countSP++;
      } else {
        rc[j++] = ch16 & 0x0ff;
        rc[j++] = ch16 >> 8;
      }
    }
    var rc8 = new Uint8Array(j);
    for(var i=0; i< j; i++) {
      rc8[i] = rc[i];
    }
    return rc8;
  } catch(e) {
    alert(e);
  }
}
function MakeConvert8bitTable() {
  try {
    // 8bit area
    var buffer1 = new Uint8Array(256);
    for(var i=0; i<256; i++) {
      if(0x00<=i && i <= 0x1f) {
        switch(i) {
        case  9 : case 10 : case 13 :
          buffer1[i] = i;
          break;
        default:
        buffer1[i]=0;
          break;
        }
      } else if(0x80<=i && i <=0xa0) {
        buffer1[i]=0;
      } else if(0xe0<=i && i <=0xff) {
        buffer1[i]=0;
      } else {
        buffer1[i] = i;
      }
    }
    // download sjis code list file
    if(downloadSjisCodeList) {
      var b = new Blob( [buffer1], {type: "application/octet-stream"});
      var url = URL.createObjectURL(b);
      var a = document.querySelector("#results");
      a.href = url;
      a.download = "sjis8.txt";
      a.text="re-download";
      a.click();
    }
    var b = new Blob( [buffer1], {type: "application/octet-stream"});
    var file_reader = new FileReader();
    file_reader.onload = function(e) {
      var sjisAr = e.target.result;
      utf16Ar = new Array();
      for(var i=0;i<256;i++) {
        var utf16 = sjisAr.substr(i,1);
        if( utf16 != '\u0000' && utf16Ar[utf16.charCodeAt(0)] === undefined ){
          utf16Ar[utf16.charCodeAt(0)] = buffer1[i];
        }
      }
    }
    file_reader.readAsText(b,"SJIS");
  } catch(e) {
    alert(e);
  }
}
var callCount=0;
function MakeConvert16bitSubTable(hiBegin,hiEnd,lowBegin,lowEnd) {
  try {
    // 16bit area
    callCount++;
    var sizeHi  = ( hiEnd  - hiBegin  + 1 );
    if(isNaN(sizeHi)) { alert("Nan sizeHi"); }
    var sizeLow = ( lowEnd - lowBegin + 1 );
    if(isNaN(sizeLow)) { alert("Nan sizeLow"); }
    var sizeAr  = sizeHi * sizeLow;
    if(isNaN(sizeAr)) { alert("Nan sizeHi,sizeHi("+sizeHi+") * sizeLow("+sizeLow+")"); }
    var buffer1 = new Uint16Array(sizeAr);
    var n1=0;
    var tx = "";
    for(var hi=hiBegin; hi<=hiEnd; hi++) {
      for(var low=lowBegin; low<=lowEnd; low++) {
        buffer1[n1++] = (hi & 0x0ff) + ((low <<8) & 0x0ff00);
      }
    }
    // download sjis code list file
    if(downloadSjisCodeList) {
      var b = new Blob( [buffer1], {type: "application/octet-stream"});
      var url = URL.createObjectURL(b);
      var a = document.querySelector("#results");
      a.href = url;
      a.download = "sjis16(" + callCount + ").txt";
      a.text="re-download";
      a.click();
    }
    var b = new Blob( [buffer1], {type: "application/octet-stream"});
    var file_reader = new FileReader();
    file_reader.onload = function(e) {
      var sjisAr = e.target.result;
      var i=0;
      var count=0;
      for(var hi=hiBegin; hi<=hiEnd; hi++) {
        for(var low=lowBegin; low<=lowEnd; low++) {
          var sjis = (hi & 0x0ff) + ((low <<8) & 0x0ff00);
          var utf16 = sjisAr.substr(i++,1);
          try {
            if( utf16 != '\u0000' && utf16Ar[utf16.charCodeAt(0) ] === undefined ){
              utf16Ar[utf16.charCodeAt(0) ] = sjis;
            }
          } catch(e) {
            // invalidated char
          }
        }
      }
    }
    file_reader.readAsText(b,"SJIS");
  } catch(e) {
    alert(e);
  }
}

※2023/3/7 クラシック版エディタの記事だったので差替え



JavaScriptで壁を感じる時

Hyper Script が JavaScriptになって既に四半世紀が過ぎようとしていた。
大量の document.www.xxx.yyy.zzz の  getter と setter にマミれてたJavaScriptも
良好な document.getElementById(id-name) の発見により暫しの安寿を得た。
が、これを好機と捉えたMSがブラウザーのIE独自仕様変更紛争を仕掛け、これにより世界中のサイトが不意のWindowsUpdateにより、画面が崩壊する事態が発生する。
幾度のW3C勧告も虚しく仕様変更紛争は激化し無料のIE6がマーケットで伸びるなか、ActiveXやOLEによるクリティカルなセキュリティホールが多数出現する事態が続きMSの戦況は大きく傾き、ついには最終防衛ラインVB-Scriptの陥落により、MS独自路線は崩壊することとなる。
それにより、ブラウザごとに実装がバラバラで誰にも全く見向きもされなかったためロクなハッキングがなされなかったJavaScriptが脚光を浴びることになるが、仕様の齟齬ゆえに入力チェック程度の実装ですら行き詰まりとなり、多くのコードはサーバーサイドへと流れていった。
そして時が過ぎ、無名の多数の不屈の精神によって生み出されたprototype.jsやjquery.jsの様な汎仕様的なコードの出現により、JavaScriptのクライアントサイドへのコードの復帰を促す流れが生み出されたものの、それはJavaScriptをWEBのダークサイドに手招く悪魔の仕業であり、再びWEBは泥沼のセキュリティホールへと押し戻されるのであった。
戦況は膠着状態となり・・・今に至る。



javascript で DBM?

FireFoxに入っているSQLiteはデータベースをファイルロックで競合管理しているので、何かと使いにくいので、
ブラウザのLocalStorageをDataBase代わりに使えないかなぁ?と
phpMyAdminでINFORMATION_SCHEMAを見ながら
チョコチョコとJavaScriptに焼直してます。
Select A.fld1, B.fld2 From XXX A Left Outer Join YYY B On A.key = B.key Where A.fldX = xxxxx
とか使えたらいいな。
一通り動いたら、LocalStorage用サーバー・パッケージとJScriptやJDKのツールでNode.jsっぽく動くサーバー・パッケージに分離して、どこでもデータベース化できたらいいな。できれば1つのスキーマを別々のパソコンに分散できたらいいな。
 



JavaScriptでクラス定義

JavaScriptにclassというモノは無いけど、
クラスっぽくていいから使いたい時もある。
参考1(Google流)参考2参考3
コンストラクタは 普通に関数の文法で

function aaaa (param) {
this.p = param;
}

と書いてもいいけど、
ドコかで名前aaaが重なると、かなり厄介なことになるので、

var aaa = function (param) {
this.p = param;
}

と、後でパッケージする気が起きやすい書き方にした方が良さそうだ。
クラスの継承に関しては、function を作成すると 自動生成される function の prototype を使って
Object.setPrototypeOf(子クラス.prototype, 親クラス.prototype);
※2015/04/09 現在、リンク先はまだ和訳されていません。
が良さそう。
 
 



【JavaScript】 IFRAME

うかつに使うとCSSやコードページが設定できず痛い思いをするIFRAME。
サンプル
urlを打ち込んで【Add IFRAME】ボタンを押すと小窓が開く。
urlが空ならTextAreaが出てくる。
localStrageでurlもTextAreaの中身も覚えるので便利に見えるかもしれない。
かといって、いつまでの残っていると困るので、All IFRAME erase で全部忘れる。



【JavaScript】Selectors API

たまにjQueryを使うようになると、画面の中の必要なデータをJSON形式にまとめて送信するのが一番楽で、初期表示もJSON形式にまとまったデータを展開する方が簡単だ。こうなると、servletとJavBeanとJSPとタグライブラリィを使って器用にHTMLをでっち上げるMVPなんて「手間がかかる無駄飯食い(GUI)」でしかない。
MVPってホスト全盛だった前世期の『構造化プログラミング』であって、今風のアジャイルな思い付きの「変更後しか画面に出てなかったけど、変更前と変更後の内容を併記する」という様な、ネストの差替えが伴う仕様変更には滅法弱い。
Beanは丸ごと下位のクラスに押し出して、元のクラスのメンバーにし、servletは丸ごとリファクタリングしてループすればいいけど
画面に直結するJSPはサクっと直すとダラダラと長いコードにしかならないので書き直すしかないのは、ホスト全盛だった前世期と同じだ。
jQueryは、IEを使うと、JavaScriptでデータを展開した結果のHTMLを見るのは難しいけど、FireFoxでCtrl+Aで全画面を選択し右クリックで「選択した部分のソースを表示(E)」すれば見れる。
しかし、JUnit系のテストツールでは、HttpRequestが送ったHTMLコードを保存する様で、画面に展開した後のHTMLはファイルとして残らない。
ところが、jQueryを使えば、「classごとにイベントをまとめて登録することが常識」と云うことで押し切れる世の中であるが、何でもかんでも「classごとにイベントをまとめて登録すること」になってしまうところが『常識』の恐ろしい処でもある。(笑
そのjQueryを使わなくても、ブラウザのSelectors APIで十分になったらしい。
既存のAPIとの違いと云えば、 APIに渡すパラメータに疑似クラス名が使え、API で返される内容がリストからイテレータになっている様で、~. style.bold = true;  参照すれば、要素の分だけ、勝手にループしてくれるので、簡単なことは簡単に書ける。
但し、boldもitalicもunderscoreもfontのポイントも変えたいとか色々変える場合は不向きな感じがするから、cssを絡めクラス名を差し替える様な「短いコード」にした方がいいだろう。
「短いコード」で十分なら、jQueryも特に使わなくても良さそうだ。※非同期通信は使用しない条件付きで…
そうすることで、FireFoxでオブジェクトを選択してソースを見れば、classの内容で、仕様通りのクラス名に変わっているハズなので、デバッグが捗るというものだ。
振り返ってみると、Java系WEB Serverの仕様って、本当に「黒歴史」ばかりなのには・・・驚きを隠せない。



[JavaScript] LocaleStrageのサンプル

長らくブラウザのクライアントで記録するものと云えばクッキー(cookie)しかなかった。
記憶容量も4KBぐらいまでだった。
今ではLocalStrageという変数がdocumentのurlのドメインごとに記憶してくれる。
でも5MBぐらいまでらしい。
なので、サンプル(あて名書き)を作ってみた。 あて名を書くだけのメモ。
※htmlファイルをパソコンの同じフォルダにダウンロードしても使用可能。ただウチでは「iden_bs.js」というファイルが混入してくる。
先のJSFIDDLEも、一見サーバーに保持している様に思えるが、実はLocalStrageでセルの値や式を保存している。
パソコンの方で情報を記憶しているので、ネットが繋がらなくても、暫くの間は記憶してくれる。
でも、いつ何時消えてしまうか判らないので、この手のモノは皆CSVの出力と読込みは必須な気がするのでCSVの出力と読み込みも付けてみた。
CSVを読込むとLocalStrageを全部設定しなおすので列名は好きに替えられるので使い道は案外あるのかもしれない。
とは云え、LocalStrageのセキュリティ上の安全性はよく解りません。
大切な情報のメモには使えませんね。(大笑
また、CSVをSJISで出力するにはコード変換テーブルを組み込まないと無理というのが定説らしいけど、コード変換テーブルさえ作れれば何とかなる。それが あて名書き2 だ。
トンでもなく量のコード表をjsファイルに埋込むのが嫌で、JavaScriptでUint8ArrayとUint16ArrayでSJISのコード表を作ってみた。
これをBlob形式にして JavaScriptのFileReader .readAsText(b,”SJIS”) で読取らせれば 何気にUTF16テキストに変換してくれるので、元のSJISコード順さえ覚えているなら、Key:UTF16コード、Value:SJISコードなマップを作れる。
うん、readAsTextで指定できる文字エンコーディングには

<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />

のcharsetで指定できるものなら使えるらしいので、EUC や JIS も使えそう。
先のマップを使ってUTF16のテキストをUint16Arrayに変換すれば、バイナリーデータをダウンロードするコードでSJISコードページのテキストファイルに保存できる。但し、文字サイズが16ビット固定になってしまうハズなので・・・MS Office 365のEXCELで読めるけど古いバージョンでも読めるのかは不明。
またCSVのデリミタはタブ(\t)からカンマ(、)に変えてある。
しかし、数万回ループするので、ローコストなパソコンやスマフォでは、あて名書き2 は開かない方がいいかもしれない。
一応、SJISコード表をダウンロードするコードも残して置いたのでPopupWindowに挿しこんで自動的に読むようにしてみたり、コード表をLocalStrage に保存しておけば、2度目に開いた時は遅くないかもしれない。
SJISは、使用不可な文字領域が多いので、8ビット版 と 2区画(8140~9ffc  、e040~effc、下位バイトが7fの場合を除く )の 16ビット版 で作成したけど、足りないのかもしれない!(大笑
追加
あて名書き3

  • IFRAMEにテーブルを収めてみた。※関連ソースは思いっきりFireFox系なのでIEやChromeでは動かなさそう。
  • ダウンロード用のコード変換部分をsjis.jsに分離。

document.createElementでIFRAMEにタグを書いても
IFRAMEの中は
<html><head></head><body></body></html>
という文字列にしかならなかったので、

iframe.contentDocument.open();
iframe.contentDocument.write(' ');
iframe.contentDocument.close();

でHTMLの基本的なタグを作ってもらう。
でも、dummy.htmlの<link rel=”stylesheet” href=”atenagaki.css” type=”text/css” /> が無駄になり、JavaScriptでまんま追記する。

var link = document.createElement('link');
link.rel='stylesheet';
link.href='atenagaki.css';
link.type='text/css';
iframe.contentDocument.querySelector('head').appendChild(link);

無駄すぎる。

  • 半角文字が空白+半角のままだったので、無駄な空白を取った。
  • CSV読み込み時、CSVのデリミタ(カンマかタブ)、改行(CrLf,Lf,Cr)を判定。

後はUTF8やSJIS、EUCを自動判定できればいいかな。




top