Tag: JavaScript



2011 8月24日

とあるスクリプトで最初の実行時には正常に動作するのだけれど、同一ページを再訪問(リロードではなく)した時に不具合が出た。

webkit系のブラウザで不具合が確認できたのだけれど、どうやらgetElementById()でnullが帰っている様子。

ググってみると同じような現象で悩んでいる人もいるみたい。DOM構築前だとnullが帰る事もあるのが原因のようだ。

onLoadイベントとかはjQuery使っているのなら簡単に実装できるのだけれど、純粋JSで書いているスクリプトだし、他所様に配信するスクリプトなので解決方法を探る。

jQuery使っているのなら、$.ready(function(){…}) でいいのだろうけど、そうはいかない。じゃあ、onLoadイベントに登録すればいい。いいのだけど、onLoadイベントは1つしか実行できないので工夫が必要になる。

  • Javascript onloadが複数ある場合の対処法 ~FancyZoomとCubeブログシールを共存させる : ブログ・カスタマイズ徒然記
  • ここら辺の記事を参考に How to use multiple window.onload events with external scripts – Javascript FAQ – Tek-Tips にある addOnloadEvent を組み込んで対処する。

    処理的には document.write() でかいたHTML中にあるIDが付いたタグの中に別処理で作成したHTMLを放り込むもの。

    実行したい関数には引数を指定しているので、
    addOnloadEvent(function(){ print_image(hoge,fuga) });
    みたいな感じにすればonLoadイベントとして実行してくれる。

    そうすることで、getElementById()でnullが帰らなくなる。







    2011 6月12日

    とあるスクリプトで javascriptでiframeを書き、そのフレームをさらに書き換える・・・というものがあるのですが、スクリプトをページ内に複数設置すると、chromeでエラーになってしまうので回避策。

    今までは

    document.write('<IFRAME id="フレーム名" name="フレーム名" ....></IFRAME>');

    で描写して、ターゲットとなるiframeを

    var target_iframe = frames[フレーム名];

    で取得していたのですが、これが2度目以降の実行時にundefinedとなってしまう。

    var target_iframe = document.getElementById(ifrname).contentWindow;

    でもやはり取得できず。
    他のブラウザでは問題ないので気が付かなかったのだけれど、chromeのみ症状が出た。

    DOMでiframeを追加

    解決策としてはDOMでiframeを追加する事で望んだ結果が得られた。

    var iframe = document.createElement('IFRAME');
    iframe.setAttribute('id', 'フレーム名');
    iframe.setAttribute('name', 'フレーム名');
    ...
    document.body.appendChild(iframe);

    …つづきを読む







    2010 5月20日

    自動でSSLページへ移動させるJavaScript

    ログインページ等でSSLのみのアクセスにしたいページがある場合、リンクをhttpsから始まるURL にしなくてはならないのでちょっと面倒。

    仮想パス(../aaa/bbb/ccc.html)やフルパス(/aaa/bbb.html)で既にサイトを公開している場合には、どこかしらで修正を見逃す場合もある。

    それならhttp でアクセスされた場合はhttps へ移動させればよさそう。
    head内とかに以下のJavascript を設置するだけでOK.

    <script><!-- change ssl protocol
      if (document.location.protocol==="http:")
      {location.replace('https://'+window.location.host+window.location.pathname);}
    //--></script>

    今までのパスを変更しないで済むので多少楽・・・かな。







    2010 2月6日

    location.URLなどから取得するのではなく、例えば下記ページのような事を行う関数。

    javascriptでURLクエリで、変数を受け取ることはできないでしょうか?
    http://q.hatena.ne.jp/1179844292

    <script src=”sample.js?key1=value1&key2=value2″></script>

    などでクエリー(Javascriptではそう呼ばない??)を取得する。
    注意点としては日本語等マルチバイトの文字をvalueにセットするには、URLエンコードしないとだめかも。
    (呼び出し元のHTMLがUTF-8だとうまくいったけど。。。)

    var getQueryStrings = function (){
    
        // scriptタグからリクエストされたURIを取得し、クエリー(?以降の部分)を抜き出す
        var script = document.getElementsByTagName( 'script' );
        var request = script[script.length-1].src;
        var query =( request.match(/\?(.+)$/) )[1]; //配列に代入されるため[1]の要素を代入
    
        //
        var pairs = query.split(/&/);
        var form={};
        for (var i in pairs){
            var val = pairs[i].split(/=/);
            form[decodeURI(val[0])] = decodeURI(val[1]);
        }
    return form;
    };

    使い方は
    var form = getQueryStrings();
    とするとform にハッシュとして代入される。

    form["key1"]やform["key2"]のように。
    だいたい form.key1 form.key2 でも大丈夫だと思うけど、key1が数字の場合うまくいかないので注意。
    例)sample.js?1=val1&2=val2

    なんでこんな事するのかというと、以前はCGIでJavascriptを書き出していたので perl.cgi?k=aaa&〜 と、していた。そのスクリプトをJavascriptとして置き換えるのにURIの変更を(ほぼ)せずに行いたかったので。
    こうしないとパラメーターを渡すのにscriptタグの変更が必要なので。







    2009 8月24日

    IEでだけ動作しない事が多いようなのでメモ

    JSON(JSONP)で

    name(
        {
          'data' :[
                        ['あいう','せそ'],
                        ['かきく','けこ'],
                        ['さしす','せそ']
                  ]
        }
    );

    こんな感じのものを使おうとすると
    ‘]’がありませんというようなエラーが出る。

    cgi等スクリプトで出力する場合はレスポンスヘッダを明示的に指定する必要がある。

    perlなら

    print “Content-type: application/json; charset=UTF-8;\n\n”;

    のように。

    charsetは’utf8‘ではダメで’UTF-8‘か’utf-8‘とハイフンが必要のようだ。

    Content-typeも application/json とするのが良いらしい。

    参考:

    追記:

    どうやら呼び出す時に<script>タグで指定すれば(静的ファイルでも)動作する模様。
    動的に育成しない場合はレスポンスヘッダの付加は難しいし使えるかも。


    例)<script type=”text/javascript” src=”../json.js” charset=”utf-8″></script>

    この場合、type は text/javascript でのみ動作した。(win XP,IE8)
    application/json や application/javascript では動作しなかった。