2009-04-14 11 views
5

私はこれについて数多くの投稿を読んだことがありますが、確かな答えはありません。ここに私のコードは次のとおりです。setAttribute、onClick、クロスブラウザの互換性

// button creation 
onew = document.createElement('input'); 
onew.setAttribute("type", "button"); 
onew.setAttribute("value", "hosts"); 
onew.onclick = function(){fnDisplay_Computers("'" + alines[i] + "'"); }; // ie 
onew.setAttribute("onclick", "fnDisplay_Computers('" + alines[i] + "')"); // mozilla 
odiv.appendChild(onew); 

、(mozillaのコメント付き)のsetAttribute()メソッドは、Mozillaで正常に動作しますが、それはその上の行の後に来る場合にのみ。つまり、最後に設定されたものにデフォルト設定されているように見えます。 .onclickメソッド(つまりコメント付き)はどちらの場合でも動作しません。間違って使用していますか?

どちらの方法でも、私はIEでこの作業を行う方法を見つけることができません。 .onclickメソッドを使用するときに関数呼び出しを変更しました。アラート関数への単純な呼び出しを使用して正常に機能しました。これは、構文が正しくないと思われる理由です。

短い話ですが、IE/Mozilla間で一貫して動作するonclickパラメータを取得できません。

- ニコラス

答えて

6

私は通常のようなものを使用します。

+0

これは完璧に動作しますが、でも機能fnDisplay_Computersしかし、「新機能」((と、それを設定する理由を説明することができます)」 –

+0

私はそれが関係するデータ型の問題であり、新しいonclickメソッドに関連した "新しい関数"への参照だと思っています...しかし、私は本当に正確な答えを知らない、申し訳ありません! –

+0

美しい!ありがとうございました!IE7の問題が完全に解決しました。 –

1

Mozillaベースのブラウザのためtype引数、およびIEのためのsEvent引数として「onclick」とのattachEvent()機能のために、「click」とaddEventListener()機能を使用します。私はそれが最善例えば、のtry/catchステートメントを使用することを見つける:これはIE電子Firefoxで両方を動作するはず

onew.onclick = new Function("fnDisplay_Computers('" + alines[i] + "')"); 

try { 
    onew.attachEvent("onclick", //For IE 
        function(){fnDisplay_Computers("'" + alines[i] + "'"); }); 
} 
catch(e) { 
    onew.addEventListener("click", //For Mozilla-based browsers 
        function(){fnDisplay_Computers("'" + alines[i] + "'"); }, 
        false); 
} 
15

onew.setAttribute( "type"、 "button");

HTMLドキュメントでは、setAttributeを使用しないでください。 IEは、多くの場合、それはひどく間違って取得し、DOM-HTMLのプロパティが短い、より速く、より簡単に読むために:

onew.type= 'button'; 

onew.onclick =機能(){fnDisplay_Computers( "'" + ALINES [I ] + "'"); }; // ie

「アインズ」とは何ですか?なぜそれを文字列に変換し、一重引用符で囲んでいるのですか?文字列内のコードを評価することを含む凶悪なことをやろうとしているようです(これは 'onew.setAttribute'バージョンで以下に行っています)。文字列のJavaScriptコードを評価することは、ほとんどの場合、間違ったことです。それをペストのように避けてください。上記の場合、IEはFirefoxと同じように動作するはずです。動作しません。

'alines [i]'が文字列の場合、JavaScriptで元の文字列に評価されるコード文字列を作成することによってその文字列を覚えていると思います。しかし:

"'" + alines[i] + "'" 

が不十分です。 'alines [i]'にアポストロフィやバックスラッシュがあるとどうなりますか?

'O'Reilly' 

あなたには構文エラーとセキュリティホールがあります。文字列をエスケープしようとする

"'" + alines[i].split('\\').join('\\\\').split("'").join("\\'") + "'" 

が、それは醜いだと他のデータ型では動作しません。今、あなたは骨の折れるなど迷惑な何かを行うことができます。

uneval(alines[i]) 

しかし、すべてのオブジェクトを評価可能なJavaScriptソース文字列に変換することすらできない場合もあります。基本的に全面的なアプローチは失敗する運命にある。

あなただけのonclickのコールバックは、パラメータで関数をコールしたい場合行うには、通常のものは簡単な方法でコードを書くことである:

onew.onclick= function() { 
    fnDisplay_Computers(alines[i]); 
}; 

一般的に、これは動作し、あなたが望むものであるだろう。しかし、あなたがここでヒットしている可能性があるわずかなシワがあります。これは、あなたが文字列の不気味なアプローチを検討するのを混乱させるかもしれません。

つまり、この場合の 'i'が 'for'ループを囲む変数である場合、 'alines [i]'への参照はあなたが思うようにはなりません。 「i」は、クリックが発生したときにコールバック関数によってアクセスされます。は、ループが終了した後にです。この時点で、 'i'変数にはループの終わりにあった値が残っているので、 'alines [i]'は、 'onew'がクリックされたかどうかにかかわらず、常に 'alines'の最後の要素になります。

(例えば参照してください。このいくつかの議論のためのHow to fix closure problem in ActionScript 3 (AS3)。それは、JavaScriptとPythonの両方で閉鎖との混乱の最大の原因の一つだし、実際にいくつかの日言語レベルで固定してください。)

することはでき

function callbackWithArgs(f, args) { 
    return function() { f.apply(window, args); } 
} 

// ... 

onew.onclick= callbackWithArgs(fnDisplay_Computers, [alines[i]]); 

とJavaScriptの以降のバージョンでは、あなたは、単に言うことができるでしょう:

onew.onclick= fnDisplay_Computers.bind(window, alines[i]); 
0このように、独自の機能でクロージャをカプセル化することによって、ループ問題を回避

あなたが今日のブラウザで「Function.bindを()」を使用できるようにしたい場合、あなたはPrototypeフレームワークから実装を取得、または単に使用することができます。

if (!('bind' in Function.prototype)) { 
    Function.prototype.bind= function(owner) { 
     var that= this; 
     var args= Array.prototype.slice.call(arguments, 1); 
     return function() { 
      return that.apply(owner, 
       args.length===0? arguments : arguments.length===0? args : 
       args.concat(Array.prototype.slice.call(arguments, 0)) 
      ); 
     }; 
    }; 
} 
+1

すごく嬉しいですが、幸いなことに、文字列はすべてaline [x]が参照される前に消されています。とにかくそこに心配する必要はありません。 –

+0

次のように言っても安全ですか?onclickは属性ではなくイベントハンドラであるため、属性として設定すると少なくともIEの下で動作するために必要なイベントハンドラは作成されません。 –

+1

はい。実際には、ネイティブスクリプトのイベントハンドラプロパティ(Functionタイプ)*とドキュメントタイプの属性(Stringタイプ)ですが、IE <8では属性の動作方法が理解できないため、イベントハンドラをそれからコンパイルされた関数の代わりに文字列を返しますが、これはうまくいきません。 – bobince

0

私は#3 protestethすぎだと思います。多くの状況で私はテーブルを動的に構築しており、コールバック関数にパラメータを渡す必要があります。変数parmは問題のテーブル行の整数インデックスなので、タイプセーフな問題ではありません。ここでクロスブラウザ対応のようです変数と固定パラメータの両方を持つコードは次のとおりです。

for (i = 0; i < arrTableData.length; i++) { 
    eleTR = objTable.insertRow(i + 1); 
    cell = eleTR.insertCell(0); 
    cell.width = "21"; 
    var myElement = document.createElement('img'); 
    myElement.setAttribute('src', 'images/button_down.gif'); 
    myElement.setAttribute('alt', 'Move item down'); 
    myElement.onclick = new Function('moveItem(' + i + ',0)'); 
    cell.appendChild(myElement); 
} 
関連する問題