8

私は次のことを行うライブラリを作成しようとしています。

ライブラリがヘッドに含まれている場合、HTMLImageElement プロトタイプが変更され、ユーザーがたまたま HTML で使用したイメージ タグ、または JavaScript で動的に作成したイメージ タグが、ライブラリで定義されたデフォルトの onerror 関数を持つようになります。

この結果、ユーザーの画像のいずれかが不適切な URL を指しているために読み込みに失敗した場合、私のライブラリはそれを適切に処理します。

私は実験として次のことを試みています、

var img = document.createElement('img');
  img.__proto__.onerror = function() {
    alert('hi');
  };
  document.body.innerHTML = '<img id="foo" src="bar.png"/>'

ファイル bar.png が存在せず、機能しません。

ただし、次のようなことをすると

  document.body.innerHTML = '<img id="foo" src="bar.png" ' +
    'onerror="this.src = MODIT.getImage(\'blackTile\').src;"/>';

それはうまくいきます。ここで MODIT.getImage() は画像要素を返す関数です。ここでこのコードを試すことができます: https://mod.it/ciR_BxqJ/

私がやろうとしていることは可能ですか?または、すべての 403 GET エラーをグローバルにキャッチし、何らかの方法で JavaScript で処理する方法はありますか?

ありがとう!

4

2 に答える 2

7
window.addEventListener("error", function(e) {
    if ( e && e.target && e.target.nodeName && e.target.nodeName.toLowerCase() == "img" ) {
        alert( 'Bad image src: ' + e.target.src);
    }
}, true);

参照: http://jsfiddle.net/Vudsm/

于 2013-08-09T17:54:06.127 に答える
2

重要な注意: Vlad のソリューションは間違いなく簡単です! ただし、イベント バブリングを使用せずに、新しく追加された要素にイベント リスナーをアタッチする (イベント リスナーをドキュメントにアタッチする) 場合は、このまま読み進めてください。


次の質問を読んだ後、まったく別のソリューションに切り替えました。

イベントリスナーをオーバーライドできないようです(これまで調査した限り)。

実際の解決策: DOM ミューテーション イベント

MutationObserverを作成した後、追加されたノードをリッスンし、それらがイメージであるかどうかをチェックし、エラー ハンドラを動的に追加します。

jsフィドル

function imgError() {
    alert("Failed to load image!");
}

var MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver;

var config = {
    childList: true
};

var observer = new MutationObserver(function (mutations) {
    mutations.forEach(function (mutation) {
        var addedNodesCount = mutation.addedNodes.length;
        for (var i=0; i<addedNodesCount; i++) {
            var node = mutation.addedNodes.item(i);

            if (node.tagName == "IMG") {
                node.addEventListener("error", imgError);
            }
        }
    });
});

// pass in the target node, as well as the observer options
observer.observe(document.body, config);

document.body.innerHTML = '<img id="foo" src="bar.png"/>'

IE 9 でもサポートされている古い イベントを使用することもできます。DOMNodeInserted

jsフィドル

function imgError() {
    alert("Failed to load image!");
}

document.body.addEventListener("DOMNodeInserted", function (evt) {
    if (evt.target.tagName == "IMG") {
        evt.target.addEventListener("error", imgError);
    }
});

document.body.innerHTML = '<img id="foo" src="bar.png"/>'
于 2013-08-09T17:43:21.533 に答える