Sử dụng đúng addEventListener () / attachmentEvent ()?


81

Tôi đang tự hỏi làm thế nào để sử dụng addEventListenertương ứng attachEventmột cách chính xác?

window.onload = function (myFunc1) { /* do something */ }

function myFunc2() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc2, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc2);
}

 // ...

hoặc là

function myFunc1() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc1, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc1);
}

function myFunc2() { /* do something */ }

if (window.addEventListener) {
  window.addEventListener('load', myFunc2, false);
} else if (window.attachEvent) {
  window.attachEvent('onload', myFunc2);
}

 // ...

?

Trình duyệt chéo này có an toàn không hay tốt hơn là tôi nên sử dụng thứ gì đó như sau:

function myFunc1(){ /* do something */ }
function myFunc2(){ /* do something */ }
// ...

function addOnloadEvent(fnc){
  if ( typeof window.addEventListener != "undefined" )
    window.addEventListener( "load", fnc, false );
  else if ( typeof window.attachEvent != "undefined" ) {
    window.attachEvent( "onload", fnc );
  }
  else {
    if ( window.onload != null ) {
      var oldOnload = window.onload;
      window.onload = function ( e ) {
        oldOnload( e );
        window[fnc]();
      };
    }
    else
      window.onload = fnc;
  }
}

addOnloadEvent(myFunc1);
addOnloadEvent(myFunc2);
// ...

VÀ: Giả sử myfunc2chỉ dành cho IE 7. Làm thế nào để sửa đổi phương pháp chính xác / ưu tiên cho phù hợp?


Bạn có thể không thích tôi nói điều này, nhưng tại sao bạn không sử dụng một khuôn khổ để giải quyết những vấn đề như vậy?
Pointy

Tôi sẽ nhưng tôi không thể trong trường hợp này. Vì vậy, bạn có thể giúp tôi với điều này, xin vui lòng?
ginny

@ginny Hãy xem câu trả lời của tôi. Hãy cho tôi biết nếu bạn cần giải thích gì thêm.
hitautodestruct

1
Ít nhất, bạn không nên thử nghiệm mô hình sự kiện mỗi khi bạn muốn đăng ký một sự kiện. Điều này có thể dễ dàng được tách thành một hàm chung, mà bạn chuyển phần tử , loại sự kiệntrình xử lý .
MrWhite

Câu trả lời:


132

Cách sử dụng của cả hai là tương tự nhau, mặc dù cả hai đều có cú pháp hơi khác nhau cho tham số sự kiện:

addEventListener ( tham chiếu mdn ):

Được hỗ trợ bởi tất cả các trình duyệt chính (FF, Chrome, Edge)

obj.addEventListener('click', callback, false);

function callback(){ /* do stuff */ }

Danh sách sự kiện cho addEventListener.

đính kèmEvent ( tham chiếu msdn ):

Được hỗ trợ bởi IE 5-8 *

obj.attachEvent('onclick', callback);

function callback(){ /* do stuff */ }

Danh sách sự kiện cho attachEvent.

Tranh luận

Đối với cả hai phương thức, các đối số như sau:

  1. Là loại sự kiện.
  2. Là chức năng gọi một khi sự kiện đã được kích hoạt.
  3. ( addEventListeneronly) Nếu đúng, cho biết rằng người dùng muốn bắt đầu chụp .

Giải trình

Cả hai phương pháp đều được sử dụng để đạt được cùng một mục tiêu là gắn một sự kiện vào một phần tử.
Sự khác biệt là nó attachEventchỉ có thể được sử dụng trên các công cụ kết xuất đinh ba cũ hơn ( IE5 + IE5-8 *) và addEventListenerlà một tiêu chuẩn W3 được triển khai trong phần lớn các trình duyệt khác (FF, Webkit, Opera, IE9 +).

Để hỗ trợ sự kiện trình duyệt chéo vững chắc bao gồm các chuẩn hóa mà bạn sẽ không nhận được với giải pháp Diaz, hãy sử dụng một khuôn khổ .

* IE9-10 hỗ trợ cả hai phương pháp để tương thích ngược.

Cảm ơn Luke Puplett đã chỉ ra rằng nó attachEventđã bị xóa khỏi IE11.

Triển khai trình duyệt chéo tối thiểu

Như Smitty đã khuyến nghị, bạn nên xem qua addEvent này của Dustin Diaz để triển khai trình duyệt chéo chắc chắn mà không cần sử dụng khung:

function addEvent(obj, type, fn) {
  if (obj.addEventListener) {
    obj.addEventListener(type, fn, false);
  }
  else if (obj.attachEvent) {
    obj["e"+type+fn] = fn;
    obj[type+fn] = function() {obj["e"+type+fn](window.event);}
    obj.attachEvent("on"+type, obj[type+fn]);
  }
  else {
    obj["on"+type] = obj["e"+type+fn];
  }
}

addEvent( document, 'click', function (e) {
  console.log( 'document click' )
})


@CamiloMartin Nó luôn luôn giá trị thời gian để đưa vào một câu trả lời tốt nếu bạn nhận được một lời nhận xét như thế này sau đó, Cảm ơn bạn :)
hitautodestruct

13
addEventListenercũng được hỗ trợ bởi IE9 +.
MrWhite

1
AttachEvent đã bị xóa trong IE11, vì vậy mã phát hiện IE và sử dụng API này giờ sẽ không thành công. Tôi vẫn chưa thấy điều này xảy ra nhưng tôi đã nhận thấy rằng việc giả mạo chuỗi tác nhân IE10 từ IE11 có thể gây ra lỗi tập lệnh.
Luke Puplett,

@LukePuplett Việc triển khai dustin diaz dựa trên phát hiện tính năng chứ không phải phát hiện trình duyệt. Có phải đó là những gì bạn đang đề cập đến?
hitautodestruct

7

Bất kỳ ai vẫn tham gia cuộc thảo luận này và không tìm thấy câu trả lời mà họ đang tìm kiếm, hãy kiểm tra:
http://dustindiaz.com/rock-solid-addevent

Đây là một trong những giải pháp thanh lịch nhất mà tôi tìm thấy cho những người trong chúng ta bị hạn chế về việc sử dụng các khuôn khổ.

function addEvent(obj, type, fn) {

    if (obj.addEventListener) {
        obj.addEventListener(type, fn, false);
        EventCache.add(obj, type, fn);
    } else if (obj.attachEvent) {
        obj["e" + type + fn] = fn;
        obj[type + fn] = function() {
            obj["e" + type + fn](window.event);
        }
        obj.attachEvent("on" + type, obj[type + fn]);
        EventCache.add(obj, type, fn);
    } else {
        obj["on" + type] = obj["e" + type + fn];
    }

}

var EventCache = function() {

    var listEvents = [];
    return {
        listEvents: listEvents,
        add: function(node, sEventName, fHandler) {
            listEvents.push(arguments);
        },
        flush: function() {
            var i, item;

            for (i = listEvents.length - 1; i >= 0; i = i - 1) {
                item = listEvents[i];
                if (item[0].removeEventListener) {
                    item[0].removeEventListener(item[1], item[2], item[3]);
                };

                if (item[1].substring(0, 2) != "on") {
                    item[1] = "on" + item[1];
                };

                if (item[0].detachEvent) {
                    item[0].detachEvent(item[1], item[2]);
                };

                item[0][item[1]] = null;
            };
        }
    };
}();

addEvent(window, 'unload', EventCache.flush);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.