2013-03-22 40 views
41

Tôi đang tự hỏi làm thế nào để thêm một cuộc gọi phương thức khác cho sự kiện window.onload khi nó đã được gán một cuộc gọi phương thức đã được .thêm vào sự kiện window.onload?

đâu đó Giả sử trong kịch bản tôi có nhiệm vụ này ...

window.onload = function(){ some_methods_1() }; 

và sau đó vào trong kịch bản tôi có nhiệm vụ này

window.onload = function(){ some_methods_2() }; 

Khi đứng, chỉ some_methods_2 sẽ được gọi . Có cách nào để thêm vào cuộc gọi lại window.onload trước đó mà không hủy some_methods_1 không? (và cũng không bao gồm cả some_methods_1()some_methods_2() trong cùng một khối chức năng).

Tôi đoán câu hỏi này không thực sự là về window.onload mà là câu hỏi về javascript nói chung. Tôi KHÔNG muốn gán điều gì đó cho window.onload theo cách mà nếu một nhà phát triển khác làm việc trên tập lệnh và thêm một đoạn mã cũng sử dụng window.onload (mà không xem mã trước của tôi), anh ấy sẽ vô hiệu hóa sự kiện onload của tôi .

Tôi cũng tự hỏi điều tương tự về

$(document).ready() 

trong jquery. Làm thế nào tôi có thể thêm vào nó mà không phá hủy những gì đến trước, hoặc những gì có thể đến sau?

+1

'$ (document) .ready()' tích lũy. Sử dụng nó nếu jQuery trong tầm tay. –

Trả lời

28

Nếu bạn đang sử dụng jQuery, bạn không phải làm bất cứ điều gì đặc biệt. Xử lý thêm qua $(document).ready() không ghi đè lên nhau, nhưng thay vì thực hiện lần lượt:

$(document).ready(func1) 
... 
$(document).ready(func2) 

Nếu bạn không sử dụng jQuery, bạn có thể sử dụng addEventListener, như chứng minh bởi Karaxuna, cộng attachEvent cho IE < 9 .

Lưu ý rằng onload không tương đương với $(document).ready() - trước đây cũng chờ CSS, hình ảnh ..., trong khi lệnh chờ chỉ cho cây DOM. Các trình duyệt hiện đại (và IE kể từ IE9) hỗ trợ sự kiện DOMContentLoaded trên tài liệu, tương ứng với sự kiện jQuery ready, nhưng IE < 9 thì không.

if(window.addEventListener){ 
    window.addEventListener('load', func1) 
}else{ 
    window.attachEvent('onload', func1) 
} 
... 
if(window.addEventListener){ 
    window.addEventListener('load', func2) 
}else{ 
    window.attachEvent('onload', func2) 
} 

Nếu không có tùy chọn có sẵn (ví dụ, bạn đang phải đối phó với các nút DOM), bạn vẫn có thể làm được điều này (tôi đang sử dụng onload làm ví dụ, nhưng lựa chọn khác sẵn cho onload):

var oldOnload1=window.onload; 
window.onload=function(){ 
    oldOnload1 && oldOnload1(); 
    func1(); 
} 
... 
var oldOnload2=window.onload; 
window.onload=function(){ 
    oldOnload2 && oldOnload2(); 
    func2(); 
} 

hay, để tránh gây ô nhiễm không gian tên toàn cầu (và có khả năng gặp phải va chạm không gian tên), sử dụng mô hình IIFE nhập khẩu/xuất khẩu:

window.onload=(function(oldLoad){ 
    return function(){ 
    oldLoad && oldLoad(); 
    func1(); 
    } 
})(window.onload) 
... 
window.onload=(function(oldLoad){ 
    return function(){ 
    oldLoad && oldLoad(); 
    func2(); 
    } 
})(window.onload) 
+1

Ý của bạn là "document.attachEvent ('onload' ...)", không phải là 'load'. ;) –

+0

@ JamesWilkins bạn nói đúng. Cố định, cảm ơn –

+0

Bạn không nên sử dụng document.addEventListener ("load") (không hoạt động trên phiên bản firefox của tôi) mà thay vào đó là window.addEventListener ("load"). Xem http://stackoverflow.com/q/16404380/94102 –

42

Bạn có thể sử dụng attachEvent (IE8) và addEventListener thay

addEvent(window, 'load', function(){ some_methods_1() }); 
addEvent(window, 'load', function(){ some_methods_2() }); 

function addEvent(element, eventName, fn) { 
    if (element.addEventListener) 
     element.addEventListener(eventName, fn, false); 
    else if (element.attachEvent) 
     element.attachEvent('on' + eventName, fn); 
} 
+0

để làm cho nó tương thích với nhiều trình duyệt, tôi nên sử dụng cả hai? Ngoài ra, nếu sau này trong kịch bản, tôi đính kèm một cuộc gọi lại đến window.onload sau khi sử dụng addEventListener trước đây, có phải bất cứ điều gì tôi đã gán với addEventListener đều bị hủy không? – pepper

+3

@pepper câu trả lời cập nhật. Không, nó sẽ không bị hủy – karaxuna

6

Về cơ bản có hai cách

  1. cửa hàng giá trị trước đó của window.onload do đó, mã của bạn có thể gọi một handler trước nếu có trước hoặc sau khi mã của bạn thực hiện

  2. bằng cách sử dụng phương pháp addEventListener (tất nhiên là Microsoft không thích và yêu cầu bạn sử dụng một tên khác).

Phương pháp thứ hai sẽ cung cấp cho bạn an toàn hơn một chút nếu kịch bản khác muốn sử dụng window.onload và hiện nó mà không nghĩ đến sự hợp tác nhưng giả thiết chính cho Javascript là tất cả các kịch bản sẽ hợp tác như bạn đang cố gắng làm . Lưu ý rằng một tập lệnh không được thiết kế để làm việc với các tập lệnh không xác định khác sẽ luôn có thể phá vỡ một trang ví dụ bằng cách gây rối với các nguyên mẫu, bằng cách làm ô nhiễm không gian tên chung hoặc làm hỏng dom.

+0

điều này thật tuyệt! những gì về $ jquery (tài liệu) .ready() hoặc bind()? – pepper

+0

Bạn có nhận ra rằng jquery chỉ là Javascript, phải không? Tôi đã không kiểm tra nhưng tôi đoán là nó có thể sử dụng (2) nếu có hoặc (1) cho các trình duyệt cũ hơn. – 6502

+0

chắc chắn tất nhiên, tôi chỉ hỏi vì $ (tài liệu) .ready() khác một chút so với window.onload ... "Sự kiện sẵn sàng xảy ra sau khi tài liệu HTML đã được tải, trong khi sự kiện onload xảy ra sau, khi tất cả nội dung (ví dụ như hình ảnh) cũng đã được tải. " – pepper

1

này có thể không là một lựa chọn phổ biến, nhưng đôi khi kịch bản kết thúc được phân phối trong khối khác nhau, trong trường hợp đó tôi đã tìm thấy đây là một sửa chữa nhanh chóng

if(window.onload != null){var f1 = window.onload;} 
window.onload=function(){ 
    //do something 

    if(f1!=null){f1();} 
} 

sau đó ở một nơi khác. ..

if(window.onload != null){var f2 = window.onload;} 
window.onload=function(){ 
    //do something else 

    if(f2!=null){f2();} 
} 

này sẽ cập nhật các chức năng onload và chuỗi khi cần thiết

Các vấn đề liên quan