Posts Tagged ‘Tips’

[jQuery]Uncaught TypeError: Property ‘submit’ of object が出た時のTips


2012
02.08

ちょっとハマったのでメモ。

 

静的な項目をチェックするなら jquery.validate.js で一発OKなのですが、動的に項目が増減するフォームで入力チェックをしたい時は自作しなきゃならない事がまま有ります。

今回複数ページに渡りそう言うフォームになっていて、一つ手前のページでは行けるのに次のページでは Uncaught TypeError: Property ‘submit’ of object と言うエラーが出てしまう。

 

どうやらその関数は既に有るから重複したものは作らないでくださいよー

 

と言うコンフリクト系のエラーらしい。

いや、でも一つ前のページでは機嫌良く動いてるじゃないですかやだー。と言う状態で少しハマったが、解決出来ました。

 

再現方法

javascript

1
2
3
4
5
6
$(function() {
    $('#submit').click(function() {
        /*  小難しい処理とか色々 */
        $('#form').submit();
    });
});

html

1
2
3
4
<form name="form" id="form" action="hoge.php" method="post">
    <input type="text" name="hoge" id="hoge" value="" />
    <img src="path/button.gif" id="submit" />
</form>

これで少なくとも webkit 系のブラウザなら再現します。

 

ちなみに「onsubmit 使えよ!」と言われるかも知れませんが、私が今作成しているフォームはサブミットしなければならないボタンが同一フォーム上に3つ以上あります。

なので type に submit や image は使えなくて、img や button に関数を割り当てて各々パラメータ変更してから submit() してやると言う仕組みなんですね。

 

さてさて、google 先生に聞いても有効な回答が得られなかったので自分で考えてみます。

まずこのエラーはコンフリクト系のエラーと言う事は解ったので、ソースを見直して見る。

JS 側は動いているページが有るので問題無いはずなので、html に注目。

ああ、ひょっとして form 内から実行してるからか…?怪しいので html を変更。

 

html(訂正版)

1
2
3
4
<form name="form" id="form" action="hoge.php" method="post">
    <input type="text" name="hoge" id="hoge" value="" />
</form>
<img src="path/button.gif" id="submit" />

 

直りました。

 

要するに #submit が form 内に入っていると form 自体が持っている function submit を継承か何かするようで、そこで submit() を実行するとエラーになる。と言う事らしい。

外に放りだした事により、親要素(書いてないけど)の div は funciton submit を持っていないからエラーが無くなった。やったね!

 

変な所でハマると時間気になって精神衛生上宜しく無いですよね。

 

[IE6|IE7|IE8]cloneNodeで複製したエレメントのidをjQueryから参照出来ない時のTips


2011
05.23

皆さんこんにちわ、なんだか冷えますね。

 

さて、皆大好き IE ブラザーズのお茶目な仕様で少々ハマりましたので仕様解説と解決策の TIPS です。

実は基本的な事かもしれませんが、仕様を理解しておくのに越した事は無いでしょう。

リッチコンテンツ制作時にちょこちょこ問題になる可能性が高いので、便利な関数も作ってみました。改良して使ってもらえればよろしいかと思います。

 

出くわした状況

メニューをスライドしたい時に数がギリギリなので、一番端の要素を予め逆側に複製しておいてスライドした後に複製したエレメントを消去しようとした。

 

症状

IE だけスライドした後に複製元となったエレメントが動き出して、思い通りの動きをしなかった。

 

元ソース

■html

1
2
3
4
5
<ul id="listBox">
    <li id="list1">hoge</li>
    <li id="list2">moge</li>
    <li id="list3">foo</li>
</ul>

■javascript

1
2
3
4
5
6
7
var content = document.getElementById('listBox');
var clone = document.getElementById('list1').cloneNode(true);
clone.id = 'temp';
clone.style.position = 'absolute';
clone.style.left = '600px';
content.appendChild(clone);
$('#temp').animate({left: 400});

 

cloneNode して、id を書き換えて親要素に appendChild して動かそうとした訳です。

IE 以外のブラウザはこれで問題無く動きます、IE 以外は。

IE だけは #temp を呼ぶと複製元である #list1 を参照して、そちらを動かそうとします。ちなみにリスナを仕掛けたり、setTimeout でぐるぐる回してフラグを監視して、存在確認をした後に命令しても一切を無視して複製元を動かします。
更に jQuery から attr を使って id を変えても駄目です、凄い頑固ちゃんです。

 

早速原因を追求していくと、どうにも困った事になっていました。

 

IE は同一プロセス内で cloneNode(複製)されたエレメントは、別プロセスから呼ばれない限り複製元の id を参照する。

 

え、なんで!?と言う仕様ですよね、cloneNode(複製)したプロセスとは別にボタンを用意して、適当に命令を書いた関数を呼び出すと思い通りの動きをします。

もしかしたらちょっと違うのかもしれませんが、大体こんな感じの挙動になる筈です。

 

 

非常に気持ち悪いです。

 

 

ともあれ fix していきましょう、要は cloneNode(複製)したエレメントの挙動がおかしいのならば新規でエレメントを生成して、複製元のエレメントもしくは複製したばかりのエレメントから欲しい情報を新規エレメントに移してから appnedChild すれば良いのです。

 

改良版ソース

■javascript

1
2
3
4
5
6
7
8
9
10
11
12
13
var content = document.getElementById('listBox');
var clone = document.getElementById('list1').cloneNode(true);
var elm = document.createElement('li');
content.appendChild(getCloneNode(clone, elm, 'temp'));
$('#temp').animate({left: 400});

function getCloneNode(clone, elm, id) {
    elm.id = id;
    elm.style.position = 'absolute';
    elm.style.left = '600px';
    elm.innerHTML = colne.innerHTML;
    return elm;
}

 

 

こうやると意図した動きになるはずです、なんだか回りくどいけど。

これは複製したエレメントから新規エレメントに要素を移していますが、多分複製せずに直接突っ込んでも上手く行きそうですね。別処理との兼ね合いで content を外で作ってますが、全部関数内でやっちゃった方が綺麗にかけそうですね。

 

そこはお好みで。

 

なんか悔しかったから複製してやっただけですし。

 

それではまた。

 

[IE7|IE8] jQueryのfadeIn/fadeOutした時にpng画像が変になる時のTips


2011
04.22

悪名高き IE6 がついに Yahoo さんからも干されてデベロッパー歓喜!となってから、それなりに時間が過ぎましたね。

あなたの会社では IE6 のサポート状況は如何なものでしょう?当社では Yahoo さんもこうしていますよ、せめて IE7 にしましょ?ね?ね?と言う地道な活動を続けて、それなりに効果が出ています。

実際 IE6 をサポートしなければ CSS がシンプルに書けたり、png のアルファチャンネルをプラグイン無しで描画出来…で、き…

 

出来てないじゃん!

 

と言う訳で今回は IE7 と IE8 で再現を確認したアルファチャンネルの描画バグをフィックスします、症状は下記のような感じ。

  • 普通に img 要素で描画する分には問題無い
  • 既に描画されている要素の opacity を弄るとアルファチャンネル部分が黒くなる

普通にサイトを作っていて、png ファイルの要素の opacity を弄るなんて事はまず無さそうですが、最近はスタイリッシュにファッファさせたくなるじゃないですか?マウスオーバーしたらメニューが、みたいな。

それをお手軽に使いたい時はなんと言っても jQuery の fadeIn / fadeOut ですよね、例えば fadeIn は要素の opacity を一旦 0 にしてから display:block 状態に、そこから opacity を 1 になるまで加算すると言う処理を勝手にやってくれます。

つまり opacity 弄っちゃってます、IE7 と IE8 はここにアルファチャンネルが含まれた png 画像が描画されていると残念な黒い何かが出てしまうと言う訳です。

M$さんは「png ファイルのアルファチャンネルに対応しました(笑)」って言ってたのにね。

 

それではサクッとフィックスしましょう、解決法は AlphaImageLoader を引き続き使う。これで良いと思います、IE 自慢の独自フィルターだし。そもそも IE しかこの症状出ないから、自己解決させるのが最上の手段でしょう。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
$(function() {
    if(navigator.userAgent.indexOf("MSIE") != -1) {
        $('img').each(function() {
            if($(this).attr('src').indexOf('.png') != -1) {
                $(this).css({
                    'filter': 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' +
                    $(this).attr('src') +
                    '", sizingMethod="scale");'
                });
            }
        });
    }
});

ページの読み込みが完了したらブラウザ判定、どうやら IE だなとなれば html 上の img 要素全てを each して、src 属性に “.png” が含まれていたら AlphaImageLoader をかける。

 

これで IE7 と IE8 で思う存分ファッファ出来るようになる、IE6 は多分これだと駄目だと思うけど。

Yahoo さんの非推奨ブラウザなので今回は無視する方向で、Yahoo さんいつもスケープゴートになってくれてありがとう。

 

それではまた。