2009-06-03 40 views
6

Đây là câu hỏi mà tôi đã gặp phải khi mở rộng sự kiện onchange của phần tử JavaScript. Tôi có một số yếu tố lựa chọn có điều kiện sẽ có một sự kiện onchange gắn liền với mỗi người trong số họ (khi họ thay đổi thành giá trị cụ thể, nó ẩn/bỏ ẩn các yếu tố nhất định). Tôi muốn có điều kiện thêm hoặc nối thêm vào một sự kiện onchange khác để chúng đặt một biến toàn cục nếu chúng thay đổi mà không sửa đổi hoặc vô hiệu hóa hàm trước đó đã được gắn với chúng. Có cách nào để "nối thêm" một chức năng bổ sung hoặc thêm nhiều chức năng hơn vào một chức năng đã tồn tại không?Cách mở rộng sự kiện trao đổi với JavaScript

Đây là những gì tôi tin rằng một ví dụ sẽ như thế nào:

<select id="selectbox1"> 
    <option>...</option> 
    <option>...</option> 
</select> 

if (<certain conditions>) { 
    document.getElementById("selectbox1").onchange = function() { 
     //hides elements to reduce clutter on a web form ... 
    } 
} 
.... 
if (<other conditions>) { 
    document.getElementById("selectbox1").onchange = function2() { 
     //set global variable to false 
    } 
} 

Ngoài ra tôi muốn chỉ cần thêm 1-liner "thiết lập biến toàn cầu false" với chức năng ban đầu.

+1

Tôi chỉ không thể hiểu lý do tại sao bạn không thể làm điều kiện chi nhánh ngay trong xử lý sự kiện thông thường, tại sao bạn cần phải mở rộng? –

+0

Nó không phải là tôi không thể làm điều đó, nó sẽ là một chút của một thiết kế lại. Câu hỏi này là nhiều hơn về cách nó sẽ có thể thêm chức năng bổ sung cho một chức năng. – Brian

Trả lời

9

Bạn có thể gian lận bằng cách đơn giản có chức năng tổng hợp gọi các chức năng khác.

document.getElementById("selectbox1").onchange = function() { 
    function1(); 
    function2(); 
} 

Bạn cũng có thể sử dụng mẫu quan sát, được mô tả trong sách Pro JavaScript Design Patterns. Tôi có một ví dụ về việc sử dụng nó trong một bài báo (here).

//– publisher class — 
function Publisher() { 
    this.subscribers = []; 
}; 

Publisher.prototype.deliver = function(data) { 
    this.subscribers.forEach(function(fn) { fn(data); }); 
}; 

//– subscribe method to all existing objects 
Function.prototype.subscribe = function(publisher) { 
    var that = this; 
    var alreadyExists = publisher.subscribers.some(function(el) { 
     if (el === that) { 
      return; 
     } 
    }); 

    if (!alreadyExists) { 
     publisher.subscribers.push(this); 
    } 
    return this; 
}; 
2

Bạn muốn nhìn vào addEventListener()attachEvent() chức năng (đối với các trình duyệt dựa trên Mozilla và IE tương ứng).

Hãy xem tài liệu cho addEventListener()attachEvent().

var el = document.getElementById("selectbox1"); 

try { //For IE 
    el.attachEvent("onchange", function(){ code here.. }); 
} 
catch(e) { //For FF, Opera, Safari etc 
    el.addEventListener("change", function(){ code here.. }, false); 
} 

Bạn có thể thêm nhiều người nghe vào từng phần tử, do đó nhiều chức năng có thể được gọi khi sự kiện kích hoạt.

2

Bạn có thể sử dụng jQuery không? Điều này sẽ cho phép bạn liên kết/thao tác/unbind sự kiện khá dễ dàng. Các hitch duy nhất là xử lý sự kiện được kích hoạt theo thứ tự chúng bị ràng buộc.

if (<certain conditions>) { 
    $("#selectbox1").bind("change", eventdata, function1); 
} 

if (<other conditions>) { 
    $("#selectbox1").bind("change", eventdata, function1); 
} 

Và bạn cũng có thể xem xét kích hoạt sự kiện tùy chỉnh nếu nhu cầu của bạn phức tạp. Ví dụ: thay vì "interpreting" onChange, có thể có cách để kích hoạt cụ thể các sự kiện tùy chỉnh. Xem last example trên trang của jQuery.

+0

Tôi có thể sử dụng jQuery nhưng tôi chưa bao giờ sử dụng nó trước đây. Tránh đường cong học tập ngay bây giờ nếu có thể. – Brian

+1

Có nhiều khả năng là một đường cong học tập để cố gắng tìm ra tất cả các trình duyệt chéo và các bộ phận khác nhau của JS và các trình duyệt. Và, jQuery là khá dễ dàng để chọn lên, và có giá trị đầu tư nhỏ ... – alphadogg

+0

jQuery sẽ là dự án tiếp theo của tôi cho chắc chắn! Tôi muốn cố gắng để nhặt nó lên trong một hoặc hai tháng tới, nhưng trước khi COB ngày hôm nay tôi muốn có một giải pháp. – Brian

2

Nếu bạn sử dụng jQuery bạn sẽ có một cái gì đó giống như

<select id="selectbox1"> 
    <option>...</option> 
    <option>...</option> 
</select> 

if (<certain conditions>) { 
    $("#selectbox1").change(function() { 
     //hides elements to reduce clutter on a web form ... 
    }); 
} 
.... 
if (<other conditions>) { 
    $("#selectbox1").change(function() { 
     //set global variable to false 
    }); 
} 

này chủ yếu sẽ chăm sóc của trình duyệt tương thích là tốt.

1

Hiện tại có ba phương pháp khác nhau để xác định trình xử lý sự kiện (một hàm được kích hoạt khi phát hiện một sự kiện nhất định): phương pháp truyền thống, phương pháp W3C và phương pháp Microsoft.

phương pháp truyền thống

Trong phương pháp truyền thống, xử lý sự kiện được định nghĩa bằng cách thiết lập trên kiện sở hữu của một phần tử trong Javascript (như bạn đang làm trong mã ví dụ của bạn), hoặc bằng cách thiết lập trên sự kiện thuộc tính trong thẻ HTML (chẳng hạn như <select onchange="...">). Mặc dù đây là phương pháp đơn giản nhất để sử dụng, nhưng việc sử dụng nó thường bị cau mày, bởi vì như bạn đã phát hiện, nó khá cứng nhắc - không dễ dàng thêm và loại bỏ các trình xử lý sự kiện vào một phần tử đã có trình xử lý sự kiện. Ngoài ra, nó không được coi là thực hành thích hợp nữa để kết hợp javascript với HTML, nhưng thay vào đó nó phải được chứa bên trong hoặc được tải thông qua một thẻ <script>.

W3C/Microsoft phương pháp

W3C (World Wide Web Consortium) và Microsoft vừa xác định mô hình sự kiện riêng của họ. Hai mô hình hoạt động cơ bản theo cùng một cách, nhưng sử dụng các cú pháp khác nhau. Mô hình Microsoft được sử dụng trong Internet Explorer và mô hình W3C được sử dụng trong các trình duyệt khác (Firefox, Opera, Safari, Chrome, v.v.). Trong cả hai mô hình này, có các hàm được cung cấp để thêm các trình xử lý sự kiện (addEventListener cho W3C, attachEvent cho Microsoft) và loại bỏ các trình xử lý sự kiện (removeEventListener/detachEvent). Điều này cho phép bạn tự động thêm và loại bỏ các trình xử lý cụ thể cho một phần tử; trong trường hợp của bạn, bạn có thể thêm trình xử lý đầu tiên dựa trên điều kiện đầu tiên và điều thứ hai dựa trên điều kiện thứ hai. "Vấn đề" với các phương pháp này là có hai trong số đó, và do đó cả hai phương pháp cần được sử dụng để đảm bảo trình xử lý sự kiện của bạn sẽ được đăng ký trong tất cả các trình duyệt (cũng có một vài khác biệt nhỏ giữa hai mô hình, nhưng những khác biệt đó không quan trọng đối với phạm vi của câu hỏi này). Trong thực tế, nếu bạn nhìn, bạn sẽ tìm thấy một số lượng lớn các hàm "addEvent" sử dụng cả hai phương thức khi cần thiết (và thường quay trở lại phương thức truyền thống cho các trình duyệt cũ). Ví dụ, một cuộc thi đã được chạy trên blog QuirksMode vào năm 2005 để xây dựng hàm "addEvent" tốt nhất, kết quả của nó (cùng với hàm thắng) bạn có thể thấy here.

Đồng thời, nếu bạn sử dụng thư viện javascript như Prototype hoặc jQuery, chúng đi kèm với chức năng xử lý sự kiện được xây dựng trong đó sẽ xử lý các điều trên cho bạn.

1

Tôi cảm thấy như thể tôi có thể thiếu điều gì đó quan trọng về câu hỏi của bạn, nhưng giải pháp đơn giản hơn này có hiệu quả với bạn không?

Chỉ cần kiểm tra các điều kiện bên trong của sự kiện onChange và thực hiện các hành động như mong muốn. Nó sẽ là nhiều dễ dàng hơn vì phải động lại thêm/xóa eventListeners

document.getElementById("selectbox1").onchange = function() { 
    if (<certain conditions>) {  
    //hides elements to reduce clutter on a web form ... 
    } 
    if (<other conditions>) { ... } 
} 
Các vấn đề liên quan