[解決済み] Firefoxで開発したJavascriptがIEで失敗する典型的な理由は何ですか?[クローズド]
質問
私は、最近の Firefox と Safari でうまく動作する、いくつかの javascript で強化されたページを開発しました。私は Internet Explorer で確認するのを忘れ、そして今、私は IE 6 と 7 (今のところ) でページが動作しないことを発見しました。スクリプトはなぜか実行されず、いくつかのjavascriptは実行されるものの、ページはjavascriptが存在しないかのように表示されます。YUI 2からYUI-LoaderとXML-http-Requestを使用し、1つのページでJQueryに依存する"psupload"を使用して、ドム操作の独自のライブラリを使用しています。
Office XPからMicrosoft Script Editorをインストールし、これからデバッグを行います。また、私は今、特定のテストを書きます。
IEの代表的な不具合箇所はどこでしょうか?どのような方向に目をつむればいいのか。
こんなページがありました。 癖のあるモード
あなたの経験から、最初に見るべき典型的なものを挙げていただけますか?
私はまた、後で特定のタスクのためにここでより多くの質問をするでしょうが、今のところ、私はなぜ IE が Firefox でうまく実行されるスクリプトで通常失敗するのか、あなたの経験に興味があります。
編集します。 たくさんの素晴らしい回答をありがとうございました
その間に、私はInternet Explorerでも動作するようにコード全体を適応させました。私は jQuery を統合し、その上に独自のクラスを構築しました。これは私の基本的なミスで、最初からすべてのものを jQuery 上で構築しませんでした。今はそうしています。
また、JSLintも私を大いに助けてくれました。
そして、異なる回答からの多くのシングルイシューが役に立ちました。
どのように解決したのですか?
エラー/省略などがあれば、このリストを更新してください。
注意してください。
IE9では以下の問題の多くが修正されているため、この多くはIE8以下と、ある程度癖のあるモードのIE9にしか当てはまりません。たとえば、IE9 は SVG をサポートしています。
<canvas>
,
<audio>
と
<video>
はネイティブですが
標準準拠モードを有効にする
を有効にする必要があります。
##一般的なこと
-
部分的に読み込まれたドキュメントに関する問題。 JavaScript を
window.onload
などのイベントにJavaScriptを追加するのが良いでしょう。IEは部分的にロードされたドキュメントでの多くの操作をサポートしていません。 -
異なる属性 : CSSでは
elm.style.styleFloat
であるのに対し、IEではelm.style.cssFloat
を Firefox で使用した場合。で<label>
タグはfor
属性にアクセスするにはelm.htmlFor
でアクセスするのに対して、IE ではelm.for
は Firefox のものです。なおfor
は IE で予約されているのでelm['for']
はIEが例外を発生させないようにするためのより良いアイデアでしょう。
##ベースとなるJavaScriptの言語です。
-
文字列中の文字にアクセスする :
'string'[0]
は、本来のJavaScriptの仕様にないため、IEではサポートされていません。使用する'string'.charAt(0)
または'string'.split('')[0]
を使用するよりも、配列内のアイテムへのアクセスが大幅に高速化されることに注意してください。charAt
を使うよりもはるかに高速です (ただし、IE でsplit
が最初に呼び出されたときに、若干のオーバーヘッドが発生します)。 -
オブジェクトの末尾にカンマを入れる。 例
{'foo': 'bar',}
はIEでは使用できません。
##要素固有の問題
-
を取得する
document
IFrameの :-
FirefoxとIE8+。
IFrame.contentDocument
(IEはこれをサポートし始めました はバージョン8から .) -
IEです。
IFrame.contentWindow.document
-
(
IFrame.contentWindow
はwindow
を両ブラウザで表示します)。
-
FirefoxとIE8+。
-
キャンバスです。 IE9 より前のバージョンの IE は
<canvas>
要素をサポートしていません。IE は VML をサポートしていますが、これは類似の技術であり エクスプローラキャンバス のインプレースラッパーを提供することができます。<canvas>
要素のインプレースラッパーを提供できます。標準準拠モードの IE8 は、VML を使用する場合、癖のあるモードのときよりも何倍も遅く、多くの不具合があることに注意してください。 -
SVGです。 IE9 は SVG をネイティブでサポートしています。IE6-8 は SVG をサポートしますが、その場合は 外部プラグイン が必要で、そのうちのいくつかは JavaScript 操作をサポートしています。
-
<audio>
そして<video>
: はIE9でのみサポートされています。 -
ラジオボタンを動的に作成する。 IE <8 にはバグがあり、ラジオボタンを
document.createElement
で作成されたラジオボタンがチェックできなくなるバグがあります。また Javascriptで、すべてのブラウザで動作するラジオボタンを動的に作成する方法は? を参照してください。 -
でのJavaScriptの埋め込み
<a href>
タグとonbeforeunload
の競合が IE で発生します。 にJavaScriptが埋め込まれている場合href
の部分にa
タグの一部(例えば<a href="javascript: doStuff()">
と記述すると、IE は常にonbeforeunload
から返されたメッセージを表示します。onbeforeunload
ハンドラが事前に削除されていなければなりません。また タブを閉じるときに確認を求める . -
<script>
タグのイベント差分です。onsuccess
とonerror
は IE ではサポートされていないため、IE 固有のonreadystatechange
に置き換えられ、ダウンロードが成功したか失敗したかに関係なく実行されます。また JavaScript の狂気 を参照してください。
##要素のサイズ/位置/スクロールとマウスの位置。
-
要素のサイズ/位置の取得
要素の幅や高さは、時々
elm.style.pixelHeight/Width
でなく、IE ではelm.offsetHeight/Width
の方が良いのですが、IE ではどちらも信頼できず、特に癖のあるモードでは、どちらかが他よりも良い結果を出すことがあります。
elm.offsetTop
そして
elm.offsetLeft
はしばしば正しく報告されないため、要素の位置が正しくなくなり、ポップアップ要素などが多くの場合、数ピクセルずれているのはそのためです。
また、要素 (または要素の親) に
display
の
none
の場合、IE は size/position 属性にアクセスすると例外を発生させ、代わりに
0
を返すのではなく、Firefox のように例外を発生させます。
-
画面サイズを取得する (画面の表示可能な領域を取得する)。
-
Firefox。
window.innerWidth/innerHeight
-
IE標準モードです。
document.documentElement.clientWidth/clientHeight
-
IE の癖のあるモード。
document.body.clientWidth/clientHeight
-
Firefox。
-
ドキュメントのスクロール位置/マウス位置 : これは実はw3cで定義されていないため、Firefoxでも非標準となっています。を見つけるには
scrollLeft
/scrollTop
のdocument
:-
FirefoxとIEの癖のあるモード。
document.body.scrollLeft/scrollTop
-
IE を標準モードで表示します。
document.documentElement.scrollLeft/scrollTop
-
NOTE 他のいくつかのブラウザでは
pageXOffset
/pageYOffset
も同様です。function getDocScrollPos() { var x = document.body.scrollLeft || document.documentElement.scrollLeft || window.pageXOffset || 0, y = document.body.scrollTop || document.documentElement.scrollTop || window.pageYOffset || 0; return [x, y]; };
マウスカーソルの位置を取得するために
evt.clientX
とevt.clientY
でmousemove
イベントは、ドキュメントからの相対的な位置を与えます。 にスクロール位置を追加することなく ということで、前の関数を組み込む必要があります。var mousepos = [0, 0]; document.onmousemove = function(evt) { evt = evt || window.event; if (typeof evt.pageX != 'undefined') { // Firefox support mousepos = [evt.pageX, evt.pageY]; } else { // IE support var scrollpos = getDocScrollPos(); mousepos = [evt.clientX+scrollpos[0], evt.clientY+scrollpos[1]]; }; };
-
##セレクション/レンジ
-
<textarea>
そして<input>
選択 :selectionStart
とselectionEnd
は IE では実装されておらず、代わりに独自の "ranges" システムを使用しています。 テキストエリア内のキャレット列(ピクセルではない)の位置を最初から文字単位で取得するにはどうすればよいですか? . -
ドキュメント内で現在選択されているテキストを取得する。
-
Firefoxです。
window.getSelection().toString()
-
IEです。
document.selection.createRange().text
-
Firefoxです。
##IDで要素を取得する。
-
document.getElementById
を参照することもできます。name
属性を参照することもできます (どちらが先に定義されているかはドキュメントに依存します)。name
とid
. これはid
が w3c 標準でなかった頃にさかのぼります。document.all
( は、IE 固有のプロパティである ) よりも大幅に高速です。document.getElementById
を常に優先してしまうという問題があります。name
よりも先にid
. 私は個人的にこのコードを使っていますが、念のため追加のチェックでフォールバックしています。function getById(id) { var e; if (document.all) { e = document.all[id]; if (e && e.tagName && e.id === id) { return e; }; }; e = document.getElementById(id); if (e && e.id === id) { return e; } else if (!e) { return null; } else { throw 'Element found by "name" instead of "id": ' + id; }; };
##読み取り専用のinnerHTMLの問題点。
-
IE は をサポートしない の innerHTML を設定することができません。
col
,colGroup
,frameSet
,html
,head
,style
,table
,tBody
,tFoot
,tHead
,title
そしてtr
といった要素があります。ここでは、テーブル関連要素のためにそれを回避する関数を紹介します。function setHTML(elm, html) { // Try innerHTML first try { elm.innerHTML = html; } catch (exc) { function getElm(html) { // Create a new element and return the first child var e = document.createElement('div'); e.innerHTML = html; return e.firstChild; }; function replace(elms) { // Remove the old elements from 'elm' while (elm.children.length) { elm.removeChild(elm.firstChild); } // Add the new elements from 'elms' to 'elm' for (var x=0; x<elms.children.length; x++) { elm.appendChild(elms.children[x]); }; }; // IE 6-8 don't support setting innerHTML for // TABLE, TBODY, TFOOT, THEAD, and TR directly var tn = elm.tagName.toLowerCase(); if (tn === 'table') { replace(getElm('<table>' + html + '</table>')); } else if (['tbody', 'tfoot', 'thead'].indexOf(tn) != -1) { replace(getElm('<table><tbody>' + html + '</tbody></table>').firstChild); } else if (tn === 'tr') { replace(getElm('<table><tbody><tr>' + html + '</tr></tbody></table>').firstChild.firstChild); } else { throw exc; }; }; };
また、IE では
<tbody>
に<table>
を追加する前に<tr>
を追加し、その<tbody>
要素で作成した場合document.createElement
を使って作成する場合、例えばvar table = document.createElement('table'); var tbody = document.createElement('tbody'); var tr = document.createElement('tr'); var td = document.createElement('td'); table.appendChild(tbody); tbody.appendChild(tr); tr.appendChild(td); // and so on
##イベントの違い
-
を取得する
event
変数を取得します。 DOM イベントは IE では関数に渡されず、アクセスできるのはwindow.event
. イベントを取得する一般的な方法として、例えば
elm.onmouseover = function(evt) {evt = evt||window.event}
で、デフォルトはwindow.event
もしevt
が未定義である場合。 -
主なイベントコードの違い。 キーイベント・コードは実にさまざまです。 奇数モード または JavaScript マッドネス のように、IEに特化したものではありませんし、SafariやOperaはまた別物です。
-
マウスイベントの違い。 その
button
属性は、一度に複数のマウスボタンを許可するビットフラグです。-
左です。
1 (
var isLeft = evt.button & 1
) -
右です。
2 (
var isRight = evt.button & 2
) -
センターです。
4 (
var isCenter = evt.button & 4
)
W3C モデル (Firefox でサポート) は、IE モデルよりも柔軟性に欠け、left で一度に許可されるボタンは 1 つだけで、left は
0
として、右は2
で、中央は1
. なお、Peter-Paul Koch のように に言及しています。 として、これは非常に直感に反しています。0
は通常「ボタンがない」ことを意味するからです。offsetX
そしてoffsetY
は 問題あり であり、IEでは避けた方が無難でしょう。より確実な方法としてoffsetX
とoffsetY
は、IEでは 位置を取得する を取得し、相対的に配置された要素のclientX
とclientY
.また、IEでダブルクリックを取得するために
click
イベントでダブルクリックを取得するにはclick
とdblclick
イベントを関数に変換します。Firefox はclick
と同様にdblclick
をダブルクリックした場合、IE 固有の検出が必要です。 -
左です。
1 (
-
イベント処理モデルの違い。 IE 独自のモデルと Firefox のモデルは、どちらもイベントを下から上に処理することをサポートしています。
<div><span></span></div>
の両方の要素にイベントがある場合、イベントはspan
では そのdiv
という順番ではなく、従来の例えばelm.onclick = function(evt) {}
が使われた場合の順序ではありません。"Capture" イベントは一般に Firefox などでサポートされているのみで、このイベントは
div
が発生しspan
のイベントをトップダウンで表示します。IEではelm.setCapture()
そしてelm.releaseCapture()
は、マウスイベントをドキュメントから要素にリダイレクトするためのものです (elm
にリダイレクトするためのものですが、パフォーマンスやその他の問題があるため、おそらく避けるべきでしょう。-
Firefoxです。
添付ファイル :
elm.addEventListener(type, listener, useCapture [true/false])
切り離す :elm.removeEventListener(type, listener, useCapture)
(type
は、例えば'mouseover'
がなければon
) -
IEです。 IEでは、ある要素に与えられたタイプのイベントは1つしか追加できません。同じタイプのイベントが複数追加された場合、例外が発生します。また
this
はwindow
を参照します(従って、あまり有用ではありません)。アタッチ :
elm.attachEvent(sEvent, fpNotify)
切り離す :elm.detachEvent(sEvent, fpNotify)
(sEvent
は、例えば'onmouseover'
)
-
-
イベント属性の違い。
-
他のリスニング関数でイベントが処理されるのを止める :
Firefoxです。
evt.stopPropagation()
IEです。evt.cancelBubble = true
-
キーイベントで文字の挿入を止めたり、チェックボックスのチェックを止めたりと。
Firefox。
evt.preventDefault()
IEです。evt.returnValue = false
注 を返すだけでfalse
でkeydown
,keypress
,mousedown
,mouseup
,click
とreset
もデフォルトを防止します。 -
イベントを発生させた要素を取得します。
Firefoxです。
evt.target
IEです。evt.srcElement
-
マウスカーソルが離れた要素を取得する。
evt.fromElement
はIEではevt.target
である場合、Firefox ではonmouseout
イベント内であればevt.relatedTarget
-
マウスカーソルが移動した要素の取得。
evt.toElement
はIEではevt.relatedTarget
である場合、Firefox ではonmouseout
イベント内であればevt.target
-
注意
evt.currentTarget
(イベントがバインドされた要素)はIEでは等価ではありません。
-
関連
-
Uncaught TypeError: 未定義のプロパティ 'length' を読み取れませんでした。
-
[解決済み] JavaScriptで "use strict "は何をするのか、その根拠は?
-
[解決済み] JavaScriptでメールアドレスを検証するのに最適な方法は何ですか?
-
[解決済み] JavaScriptでオブジェクトをディープクローンする最も効率的な方法は何ですか?
-
[解決済み] とは何ですか! (not not)演算子とは何ですか?
-
[解決済み] JavaScriptで現在のURLを取得する?
-
[解決済み] HTMLマークアップのどこに<script>タグを記述すればよいですか?
-
[解決済み] CSSでFirefoxだけをターゲットにする
-
[解決済み] jQueryのn番目の要素を取得する方法
-
[解決済み】JavaScript版sleep()とは?)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] jQuery.ajaxでmultipart/formdataを送信する。
-
[解決済み] jQueryでPUT/DELETEリクエストを送信する方法は?
-
[解決済み] .on('click') と .click() の違いについて
-
[解決済み] 変更イベントでradioを使用するには?
-
[解決済み] チェックボックスがチェックされた場合のjQuery
-
[解決済み] ドロップダウンのアイテムの選択値をjQueryで取得する
-
[解決済み] jQueryでフォームフィールドをクリアする
-
[解決済み] jQuery .onとhoverの使い分けは可能ですか?
-
[解決済み] jQueryのn番目の要素を取得する方法
-
[解決済み] テキストエリア内のキャレットの列(ピクセルではない)位置を最初から文字単位で取得するにはどうしたらよいですか?