Làm cách nào để chuyển các đối số cho các trình xử lý sự kiện trong jQuery?


Câu trả lời:


110

Cách đơn giản nhất là làm như vậy (giả sử bạn không muốn bất kỳ thông tin sự kiện nào được truyền vào hàm) ...

$("#myid").click(function() {
    myfunction(arg1, arg2);
});

jsFiddle .

Điều này tạo ra một hàm ẩn danh, được gọi khi clicksự kiện được kích hoạt. Điều này sẽ lần lượt gọi myfunction()với các đối số bạn cung cấp.

Nếu bạn muốn giữ nguyên ThisBinding(giá trị của thisthời điểm hàm được gọi, đặt thành phần tử đã kích hoạt sự kiện), thì hãy gọi hàm với call().

$("#myid").click(function() {
    myfunction.call(this, arg1, arg2);
});

jsFiddle .

Bạn không thể chuyển trực tiếp tham chiếu theo cách ví dụ của bạn trạng thái hoặc đối số duy nhất của nó sẽ là đối tượng jQueryevent .

Nếu bạn làm muốn vượt qua các tài liệu tham khảo, bạn phải tận dụng jQuery proxy()chức năng (mà là một trình duyệt wrapper chéo cho Function.prototype.bind()). Điều này cho phép bạn vượt qua đối số, mà đang bị ràng buộc trước khi các eventcuộc tranh cãi.

$("#myid").click($.proxy(myfunction, null, arg1, arg2));   

jsFiddle .

Trong ví dụ này, myfunction()sẽ được thực hiện với nó ThisBindingcòn nguyên vẹn ( nullkhông phải là một đối tượng, do đó bình thường thisgiá trị của phần tử đã kích hoạt sự kiện này được sử dụng), cùng với các đối số (theo thứ tự) arg1, arg2và cuối cùng là jQuery eventđối tượng mà bạn có thể bỏ qua nếu nó không bắt buộc (thậm chí không đặt tên nó trong các đối số của hàm).

Bạn cũng có thể sử dụng sử dụng eventđối tượng jQuery datađể truyền dữ liệu, nhưng điều này sẽ yêu cầu sửa đổi myfunction()để truy cập nó thông qua event.data.arg1(không phải là đối số hàm như câu hỏi của bạn đề cập) hoặc ít nhất là giới thiệu một hàm proxy thủ công như ví dụ trước đây hoặc một hàm được tạo bằng cách sử dụng ví dụ sau.


2
hãy nhớ rằng bạn sẽ mất ngữ cảnh jquery $ (this) trong my Chức năng (). Để duy trì, hãy gọi myfunction(this, arg1, arg2)từ trình xử lý ẩn danh. Sau đó, chức năng của bạn có thể làmmyfunction(el, arg1, arg2) { alert($(el).val()); }
lambinator

11
@geosteve: Nếu bạn muốn giữ nó, hãy sử dụng myfunction.call(this, arg1, arg2).
alex

1
Đó là không truyền các đối số cho hàm, như câu hỏi đặt ra. Nó đang gọi một hàm gọi một hàm khác. Lồng các hàm bên trong các hàm ẩn danh không phải là một ý kiến ​​hay vì bạn không thể hủy liên kết hàm ẩn danh một cách dễ dàng.
George Filippakos

1
@ geo1701 Bạn có thể nếu bạn sử dụng không gian tên tùy chỉnh và chỉ liên kết một lần với nó. Đối với hầu hết các mục đích, nó ổn. Nhưng bạn không làm mất lợi ích mà bạn đã đề cập.
alex

1
Đồng ý với @ geo1701, tôi đã phải xóa trình xử lý sự kiện và giải pháp của anh ấy chỉ có một giải pháp hiệu quả.
Pavel K

76
$("#myid").on('click', {arg1: 'hello', arg2: 'bye'}, myfunction);

function myfunction(e) {

    var arg1 = e.data.arg1;
    var arg2 = e.data.arg2;

    alert(arg1);
    alert(arg2);

}

//call method directly:
myfunction({
    arg1: 'hello agian', 
    arg2: 'bye again'
});

Cũng cho phép bạn liên kết và hủy liên kết các trình xử lý sự kiện cụ thể bằng cách sử dụng các phương pháp bật và tắt.

Thí dụ:

$("#myid").off('click', myfunction);

Thao tác này sẽ hủy liên kết trình xử lý chức năng khỏi #myid


Đó là không truyền đối số cho hàm, như câu hỏi đặt ra.
alex

4
Đó là cách bạn truyền các đối số (bạn bọc chúng bên trong một đối tượng).
George Filippakos

Đó là cách bạn truyền dữ liệu, nhưng việc gọi chúng là các đối số của hàm là một điều khó khăn.
alex

6
Đó là một giải pháp tốt hơn cho câu trả lời được chấp nhận vì nó sử dụng mẫu người nghe ràng buộc và không liên kết được khuyến nghị bằng cách sử dụng các phương pháp Bật / Tắt.
George Filippakos

7
Nếu bạn nghĩ việc hủy liên kết là khá hiếm thì bạn phải có kinh nghiệm rất hạn chế. Xin đừng poo poo đóng góp từ người khác - đây là một nền tảng kiến ​​thức tập thể không phải là một cuộc thi. Không có câu trả lời đúng hay sai.
George Filippakos

12

trong khi bạn chắc chắn nên sử dụng câu trả lời của Alex, phương thức "ràng buộc" của thư viện nguyên mẫu đã được chuẩn hóa trong Ecmascript 5 và sẽ sớm được triển khai trên các trình duyệt nguyên bản. Nó hoạt động như thế này:

jQuery("#myid").click(myfunction.bind(this, arg1, arg2));

2
Sẽ thisđược đặt thành ngữ cảnh khác nếu bạn sử dụng phương thức này, ví dụ: nhập bind()nó vào thistrong ngữ cảnh đó (toàn cục) có thể dẫn đến việc xử lý nhấp chuột đó có windowđối tượng thistrái ngược với tham chiếu đến #myidphần tử?
alex

2
@alex bạn nói khá đúng. jQuery sẽ liên kết phần tử #myid với 'this' trong trình xử lý sự kiện của nó và việc sử dụng phương thức liên kết sẽ ghi đè phần tử đó. Tôi đã viết bài này vài năm trước, có vẻ như rất khó để nói những gì tôi đang nghĩ vào thời điểm đó. Tôi đoán tôi chỉ giả định rằng những người đọc câu trả lời của tôi đủ thông minh để tự mình tìm ra những chi tiết này.
Breton

12
Đó là một giả định rất nguy hiểm.
Travis

@Travis Tính đến thời điểm viết bài này, (gần 11 năm sau câu trả lời của Breton), caniuse.com báo cáo Ecmascript 5 được 98,87% trình duyệt hỗ trợ . (xem caniuse.com/#search=ECMAScript%205 )
Stephan

@Stephan Nhận xét của tôi nhằm vào @Breton vì giả định people reading my answers are smart enough to figure these details out themselves, không phải về Ecmascript.
Travis

6

Chủ đề cũ, nhưng dành cho mục đích tìm kiếm; thử:

$(selector).on('mouseover',...);

... và xem thông số "data": http://api.jquery.com/on/

ví dụ:

function greet( event ) {
  alert( "Hello " + event.data.name );
}
$( "button" ).on( "click", {name: "Karl"}, greet );
$( "button" ).on( "click", {name: "Addy"}, greet );

4

Đã có những câu trả lời tuyệt vời rồi, nhưng dù sao, đây là hai xu của tôi. Bạn cũng có thể dùng:

$("#myid").click({arg1: "foo", arg2: "bar"}, myfunction)

Và người nghe sẽ trông giống như:

function myfunction(event){ alert(event.data.arg1); alert(event.data.arg2); }


2

Đơn giản:

$(element).on("click", ["Jesikka"],  myHandler);

function myHandler(event){
   alert(event.data);     //passed in "event.data"
}
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.