javascript 添加和删除带参数的事件监听器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15088010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Adding and Removing Event Listeners with parameters
提问by tomturton
I am writing a vanilla JavaScripttool, that when enabled adds event listeners to each of the elements passed into it.
我正在编写一个普通的JavaScript工具,启用后会向传递给它的每个元素添加事件侦听器。
I would like to do something like this:
我想做这样的事情:
var do_something = function (obj) {
// do something
};
for (var i = 0; i < arr.length; i++) {
arr[i].el.addEventListener('click', do_something(arr[i]));
}
Unfortunately this doesn't work, because as far as I know, when adding an event listener, parameters can only be passed into anonymous functions:
不幸的是,这不起作用,因为据我所知,在添加事件侦听器时,参数只能传递给匿名函数:
for (var i = 0; i < arr.length; i++) {
arr[i].el.addEventListener('click', function (arr[i]) {
// do something
});
}
The problem is that I need to be able to remove the event listener when the tool is disabled, but I don't think it is possible to remove event listeners with anonymous functions.
问题是我需要能够在工具被禁用时删除事件侦听器,但我认为不可能删除具有匿名函数的事件侦听器。
for (var i = 0; i < arr.length; i++) {
arr[i].el.removeEventListener('click', do_something);
}
I know I could easily use jQuery to solve my problem, but I am trying to minimise dependencies.jQuery must get round this somehow, but the code is a bit of a jungle!
我知道我可以轻松地使用 jQuery 来解决我的问题,但我正在尝试将依赖关系最小化。jQuery 必须以某种方式解决这个问题,但是代码有点像丛林!
采纳答案by marekful
This is invalid:
这是无效的:
arr[i].el.addEventListener('click', do_something(arr[i]));
The listener must be a function reference. You cannot specify parameters at the time of listener assignment. A handler function will always be called with the event
being passed as the first argument. To pass other arguments, you can wrap your listener into an anonymous function like so:
侦听器必须是函数引用。您不能在分配侦听器时指定参数。处理程序函数将始终被event
作为第一个参数传递的被调用。要传递其他参数,您可以将您的侦听器包装到一个匿名函数中,如下所示:
elem.addEventListener('click', function(event) {
do_something( ... )
}
To be able to remove via removeEventListener
you just name the handler function:
为了能够通过removeEventListener
您删除,只需命名处理程序函数:
function myListener(event) {
do_something( ... );
}
elem.addEventListener('click', myListener);
To have access other variables in the handler function, you can use closures. E.g.:
要访问处理程序函数中的其他变量,您可以使用闭包。例如:
function someFunc() {
var a = 1,
b = 2;
function myListener(event) {
do_something(a, b);
}
elem.addEventListener('click', myListener);
}
回答by Sandeep
To pass arguments to event handlers bind
can be used or handler returning a function can be used
bind
可以使用将参数传递给事件处理程序,也可以使用返回函数的处理程序
// using bind
var do_something = function (obj) {
// do something
}
for (var i = 0; i < arr.length; i++) {
arr[i].el.addEventListener('click', do_something.bind(this, arr[i]))
}
// using returning function
var do_something = obj => e {
// do something
}
for (var i = 0; i < arr.length; i++) {
arr[i].el.addEventListener('click', do_something(arr[i]))
}
But in both the cases to remove the event handlers it is not possible as bind
will give a new referenced function and returning function also does return a new function every time for loop is executed.
但是在这两种情况下,删除事件处理程序都是不可能的,因为bind
每次执行 for 循环时都会给出一个新的引用函数,并且返回函数也确实返回一个新函数。
To handle this problem we need to store the references of the functions in an Array
and remove from that.
为了解决这个问题,我们需要将函数的引用存储在 an 中Array
并从中删除。
// using bind
var do_something = function (obj) {
// do something
}
var handlers = []
for (var i = 0; i < arr.length; i++) {
const wrappedFunc = do_something.bind(this, arr[i])
handlers.push(wrappedFunc)
arr[i].el.addEventListener('click', wrappedFunc);
}
//removing handlers
function removeHandlers() {
for (var i = 0; i < arr.length; i++) {
arr[i].el.removeEventListener('click', handlers[i]);
}
handlers = []
}
回答by whitneyit
This can be done quite easily, just not as you have it right now.
这可以很容易地完成,只是不像你现在那样。
Instead of trying to add and remove random anonymouse functions, you need to add or remove a function that handles the execution of your otherfunctions.
您需要添加或删除处理其他函数执行的函数,而不是尝试添加和删除随机匿名函数。
var
// Here we are going to save references to our events to execute
cache = {},
// Create a unique string to mark our elements with
expando = String( Math.random() ).split( '.' )[ 1 ],
// Global unique ID; we use this to keep track of what events to fire on what elements
guid = 1,
// The function to add or remove. We use this to handler all of other
handler = function ( event ) {
// Grab the list of functions to fire
var handlers = ( cache[ this[ expando ] ] && cache[ this[ expando ] ][ event.type ] ) || false;
// Make sure the list of functions we have is valid
if ( !handlers || !handlers.length ) {
return;
}
// Iterate over our individual handlers and call them as we go. Make sure we remeber to pass in the event Object
handlers.forEach( function ( handler ) {
handler.call( this, event );
});
},
// If we want to add an event to an element, we use this function
add = function ( element, type, fn ) {
// We test if an element already has a guid assigned
if ( !element[ expando ] ) {
element[ expando ] = guid++;
}
// Grab the guid number
var id = element[ expando ];
// Make sure the element exists in our global cache
cache[ id ] = cache[ id ] || {};
// Grab the Array that we are going to store our handles in
var handlers = cache[id ][ type ] = cache[ id ][ type ] || [];
// Make sure the handle that was passed in is actually a function
if ( typeof fn === 'function' ) {
handlers.push( fn );
}
// Bind our master handler function to the element
element.addEventListener( type, handler, false );
};
// Add a click event to the body element
add( document.body, 'click', function ( event ) {
console.log( 1 );
});
This is just a cut down version of what I've written before, but you can get the gist of it I hope.
这只是我以前写过的内容的精简版,但我希望你能得到它的要点。
回答by Mohit S. Kushwaha
To 'addEventListener
' with some parameters, you can use the following code:
要将' addEventListener
' 带一些参数,可以使用以下代码:
{
myButton.addEventListener("click",myFunction.bind(null,event,myParameter1,myParameter2));
}
And the function 'myFunction
' should be something like this:
函数 ' myFunction
' 应该是这样的:
{
function myFunction(event, para1, para2){...}
}