首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

JavaScript Image.onload 不觸發:EventUtil.addHandler 缺少實際綁定邏輯

     編輯:程式設計疑難解答

編寫通用事件工具類 `EventUtil` 時,若 `addHandler` 方法僅為空殼,`image.onload` 事件永遠不會被真正綁定,導致 `alert` 不彈出。本文剖析原因並給出跨瀏覽器相容的完整實現。

問題代碼

var EventUtil = {
    addHandler: function (element, type, handler) { /* 空實現 */ },
    // ... 其他方法
};
var image = document.getElementById("myImage");
EventUtil.addHandler(image, "load", function (event) {
    alert(EventUtil.getTarget(event).src);  // 永不執行
});

根因

`addHandler` 未呼叫 `element.addEventListener` / `element.attachEvent` / `element['on'+type]`,事件監聽器根本未註冊,圖片載入完成時無回調可執行。

標準跨瀏覽器實現

var EventUtil = {
    addHandler: function (element, type, handler) {
        if (element.addEventListener) {
            element.addEventListener(type, handler, false);  // DOM2 級標準
        } else if (element.attachEvent) {
            element.attachEvent('on' + type, handler);       // IE8 及以下
        } else {
            element['on' + type] = handler;                  // DOM0 級備援
        }
    },
    removeHandler: function (element, type, handler) {
        if (element.removeEventListener) {
            element.removeEventListener(type, handler, false);
        } else if (element.detachEvent) {
            element.detachEvent('on' + type, handler);
        } else {
            element['on' + type] = null;
        }
    },
    getEvent: function (event) {
        return event || window.event;
    },
    getTarget: function (event) {
        return event.target || event.srcElement;
    },
    preventDefault: function (event) {
        if (event.preventDefault) event.preventDefault();
        else event.returnValue = false;
    },
    stopPropagation: function (event) {
        if (event.stopPropagation) event.stopPropagation();
        else event.cancelBubble = true;
    }
};

圖片 onload 特別注意點

情況行為對策
圖片已快取部分瀏覽器不再觸發 onload綁定前先檢查 `image.complete`,若 true 手動呼叫 handler
src 相同重設不觸發 onload先設 `src=""` 再設真實 src,或加時間戳 `src + '?t=' + Date.now()`
跨域圖片載入失敗觸發 onerror同步綁定 onerror 處理

健壯的圖片載入封裝

function loadImage(url, onSuccess, onError) {
    var img = new Image();
    EventUtil.addHandler(img, 'load', function () {
        EventUtil.removeHandler(img, 'load', arguments.callee);
        EventUtil.removeHandler(img, 'error', onError);
        onSuccess(img);
    });
    EventUtil.addHandler(img, 'error', function () {
        EventUtil.removeHandler(img, 'load', onSuccess);
        EventUtil.removeHandler(img, 'error', arguments.callee);
        onError(new Error('圖片載入失敗: ' + url));
    });
    // 快取處理
    if (img.complete) {
        if (img.naturalWidth !== 0) onSuccess(img);
        else onError(new Error('圖片損壞: ' + url));
        return;
    }
    img.src = url;
    return img;
}

// 使用
loadImage('https://example.com/logo.png',
    function (img) { console.log('載入成功', img.src); },
    function (err) { console.error(err); });

補全 `EventUtil.addHandler` 的實際綁定邏輯,並注意圖片快取與跨域情況,即可讓 `image.onload` 可靠觸發。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved