如何传递参数addEventListener监听函数?

情况有点像

var someVar = some_other_function();
someObj.addEventListener("click", function(){
some_function(someVar);
}, false);

问题是someVar的值在addEventListener的侦听器函数中是不可见的,在那里它可能被视为一个新变量。

710232 次浏览

您编写的代码绝对没有任何问题。some_functionsomeVar都应该是可访问的,以防它们在匿名的上下文中可用

function() { some_function(someVar); }

被创建。

检查警报是否给了你一直在寻找的值,确保它可以在匿名函数的作用域内访问(除非你在addEventListener调用旁边有更多的代码操作相同的someVar变量)

var someVar;
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click", function(){
some_function(someVar);
}, false);

someVar值只能在some_function()上下文中访问,而不能从侦听器的上下文中访问。 如果你想让它在listener中,你必须这样做:

someObj.addEventListener("click",
function(){
var newVar = someVar;
some_function(someVar);
},
false);

并使用newVar代替。

另一种方法是从some_function()返回someVar值,以便在侦听器中进一步使用它(作为一个新的本地变量):

var someVar = some_function(someVar);

您可以通过将函数声明为变量来添加和删除带有参数的事件侦听器。

myaudio.addEventListener('ended',funcName=function(){newSrc(myaudio)},false);

newSrc是以myaudio为参数的方法 funcName是函数名变量

可以使用 myaudio.removeEventListener('ended',func,false); < / p >

也可以试试这些(IE8 + Chrome。我不知道FF):

function addEvent(obj, type, fn) {
eval('obj.on'+type+'=fn');
}


function removeEvent(obj, type) {
eval('obj.on'+type+'=null');
}


// Use :


function someFunction (someArg) {alert(someArg);}


var object=document.getElementById('somObject_id') ;
var someArg="Hi there !";
var func=function(){someFunction (someArg)};


// mouseover is inactive
addEvent (object, 'mouseover', func);
// mouseover is now active
addEvent (object, 'mouseover');
// mouseover is inactive

希望没有拼写错误:-)

使用

   el.addEventListener('click',
function(){
// this will give you the id value
alert(this.id);
},
false);

如果你想传递任何自定义值到这个匿名函数那么最简单的方法是

 // this will dynamically create property a property
// you can create anything like el.<your  variable>
el.myvalue = "hello world";
el.addEventListener('click',
function(){
//this will show you the myvalue
alert(el.myvalue);
// this will give you the id value
alert(this.id);
},
false);

在我的项目中完美地工作。希望这能有所帮助

为什么不直接从事件的目标属性获取参数呢?

例子:

const someInput = document.querySelector('button');
someInput.addEventListener('click', myFunc, false);
someInput.myParam = 'This is my parameter';
function myFunc(evt)
{
window.alert(evt.currentTarget.myParam);
}
<button class="input">Show parameter</button>

JavaScript is a prototype-oriented language, remember!

这个问题很老了,但我想我可以为后代提供一个使用ES5的.bind()的替代方案。:)

function some_func(otherFunc, ev) {
// magic happens
}
someObj.addEventListener("click", some_func.bind(null, some_other_func), false);

请注意,您需要设置listener函数,将第一个参数作为传递给bind(您的另一个函数)的参数,第二个参数现在是事件(而不是第一个,因为它本来就是)。

bind ()是将目标函数绑定到特定作用域并可选地在目标函数中定义this对象的方法。

someObj.addEventListener("click", some_function.bind(this), false);

或者捕获一些词法范围,例如在循环中:

someObj.addEventListener("click", some_function.bind(this, arg1, arg2), false);

最后,如果目标函数中不需要this形参:

someObj.addEventListener("click", some_function.bind(null, arg1, arg2), false);

你可以用'bind'绑定所有必要的参数:

root.addEventListener('click', myPrettyHandler.bind(null, event, arg1, ... ));

通过这种方式,你总是会得到eventarg1和其他传递给myPrettyHandler的东西。

http://passy.svbtle.com/partial-application-in-javascript-using-bind

其他替代方法,可能没有bind的使用那么优雅,但它对于循环中的事件是有效的

for (var key in catalog){
document.getElementById(key).my_id = key
document.getElementById(key).addEventListener('click', function(e) {
editorContent.loadCatalogEntry(e.srcElement.my_id)
}, false);
}

它已经测试了谷歌chrome扩展和可能e.srcElement必须替换为e.srcElement在其他浏览器

我发现这个解决方案使用Imatoria发布的评论,但我不能标记它为有用,因为我没有足够的声誉:D

下面的答案是正确的,但如果你使用yuiccompressor压缩js文件,下面的代码在IE8中不能工作。(事实上,大多数美国人仍然在使用IE8)

var someVar;
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click",
function(){
some_function(someVar);
},
false);

所以,我们可以修复上面的问题如下,它在所有浏览器工作良好

var someVar, eventListnerFunc;
someVar = some_other_function();
eventListnerFunc = some_function(someVar);
someObj.addEventListener("click", eventListnerFunc, false);

希望对在生产环境下压缩js文件的人有用。

祝你好运! !

所有函数中都有一个特殊的变量:参数。您可以将参数作为匿名参数传递,并通过参数变量访问它们(按顺序)。

例子:

var someVar = some_other_function();
someObj.addEventListener("click", function(someVar){
some_function(arguments[0]);
}, false);

这里还有另一种方法(它在for循环中工作):

var someVar = some_other_function();
someObj.addEventListener("click",


function(theVar){
return function(){some_function(theVar)};
}(someVar),


false);

下面的代码为我工作良好(firefox):

for (var i=0; i<3; i++) {
element = new ...   // create your element
element.counter = i;
element.addEventListener('click', function(e){
console.log(this.counter);
...            // another code with this element
}, false);
}

输出:

0
1
2

向eventListener的回调函数发送参数需要创建一个隔离函数并将参数传递给该隔离函数。

这里有一个很好的辅助函数。基于上面“hello world”的例子。)

还有一件事是维护对函数的引用,这样我们就可以干净地删除侦听器。

// Lambda closure chaos.
//
// Send an anonymous function to the listener, but execute it immediately.
// This will cause the arguments are captured, which is useful when running
// within loops.
//
// The anonymous function returns a closure, that will be executed when
// the event triggers. And since the arguments were captured, any vars
// that were sent in will be unique to the function.


function addListenerWithArgs(elem, evt, func, vars){
var f = function(ff, vv){
return (function (){
ff(vv);
});
}(func, vars);


elem.addEventListener(evt, f);


return f;
}


// Usage:


function doSomething(withThis){
console.log("withThis", withThis);
}


// Capture the function so we can remove it later.
var storeFunc = addListenerWithArgs(someElem, "click", doSomething, "foo");


// To remove the listener, use the normal routine:
someElem.removeEventListener("click", storeFunc);
    var EV = {
ev: '',
fn: '',
elem: '',
add: function () {
this.elem.addEventListener(this.ev, this.fn, false);
}
};


function cons() {
console.log('some what');
}


EV.ev = 'click';
EV.fn = cons;
EV.elem = document.getElementById('body');
EV.add();


//If you want to add one more listener for load event then simply add this two lines of code:


EV.ev = 'load';
EV.add();

一种方法是使用外部函数:

elem.addEventListener('click', (function(numCopy) {
return function() {
alert(numCopy)
};
})(num));

这种将匿名函数包装在圆括号中并立即调用它的方法称为IIFE(立即调用的函数表达式)。

你可以在http://codepen.io/froucher/pen/BoWwgz中检查一个有两个参数的例子。

catimg.addEventListener('click', (function(c, i){
return function() {
c.meows++;
i.textContent = c.name + '\'s meows are: ' + c.meows;
}
})(cat, catmeows));

下面的方法对我很有效。从在这里修改。

.
function callback(theVar) {
return function() {
theVar();
}
}


function some_other_function() {
document.body.innerHTML += "made it.";
}


var someVar = some_other_function;
document.getElementById('button').addEventListener('click', callback(someVar));
<!DOCTYPE html>
<html>
<body>
<button type="button" id="button">Click Me!</button>
</body>
</html>

我被困在这里,因为我在循环中使用它来查找元素并向它添加listner。如果你在循环中使用它,那么这将完美地工作

for (var i = 0; i < states_array.length; i++) {
var link = document.getElementById('apply_'+states_array[i].state_id);
link.my_id = i;
link.addEventListener('click', function(e) {
alert(e.target.my_id);
some_function(states_array[e.target.my_id].css_url);
});
}

你可以通过名为关闭的javascript特性通过值(而不是引用)传递somevar:

var someVar='origin';
func = function(v){
console.log(v);
}
document.addEventListener('click',function(someVar){
return function(){func(someVar)}
}(someVar));
someVar='changed'

或者你也可以写一个普通的换行函数,比如wrapEventCallback:

function wrapEventCallback(callback){
var args = Array.prototype.slice.call(arguments, 1);
return function(e){
callback.apply(this, args)
}
}
var someVar='origin';
func = function(v){
console.log(v);
}
document.addEventListener('click',wrapEventCallback(func,someVar))
someVar='changed'

这里wrapEventCallback(func,var1,var2)是这样的:

func.bind(null, var1,var2)

这是个老问题了,但我今天也遇到了同样的问题。我发现最干净的解决方案是使用局部套用。的概念

它的代码是:

someObj.addEventListener('click', some_function(someVar));


var some_function = function(someVar) {
return function curried_func(e) {
// do something here
}
}

通过命名curry函数,可以调用Object。removeEventListener在以后的执行时间取消注册eventListener。

你需要:

newElem.addEventListener('click', {
handleEvent: function (event) {
clickImg(parameter);
}
});

这个解决方案可能很好看

var some_other_function = someVar => function() {
}


someObj.addEventListener('click', some_other_function(someVar));

或者绑定变量也不错

如果我没有弄错的话,使用bind调用函数实际上创建了一个由bind方法返回的新函数。这将在以后给你带来问题,或者如果你想删除事件监听器,因为它基本上就像一个匿名函数:

// Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', myCallback);
someObject.removeEventListener('event', myCallback);


// Not Possible:
function myCallback() { /* code here */ }
someObject.addEventListener('event', function() { myCallback });
someObject.removeEventListener('event', /* can't remove anonymous function */);

记住这一点。

如果你正在使用ES6,你可以按照建议做,但更干净一点:

someObject.addEventListener('event', () => myCallback(params));
    $form.addEventListener('submit', save.bind(null, data, keyword, $name.value, myStemComment));
function save(data, keyword, name, comment, event) {

这就是我如何正确地传递事件。

不错的一行选择

element.addEventListener('dragstart',(evt) => onDragStart(param1, param2, param3, evt));
function onDragStart(param1, param2, param3, evt) {


//some action...


}

可能不是最优的,但对于那些不精通js的人来说已经足够简单了。将调用addEventListener的函数放到它自己的函数中。通过这种方式,传递给它的任何函数值都保持自己的作用域,并且您可以尽可能多地迭代该函数。

示例我与文件读取,因为我需要捕捉和渲染图像和文件名的预览。在使用多文件上传类型时,我花了一段时间来避免异步问题。尽管上传了不同的文件,我还是会意外地在所有渲染中看到相同的“名称”。

最初,所有的readFile()函数都在readFiles()函数中。这导致了异步作用域问题。

    function readFiles(input) {
if (input.files) {
for(i=0;i<input.files.length;i++) {


var filename = input.files[i].name;


if ( /\.(jpe?g|jpg|png|gif|svg|bmp)$/i.test(filename) ) {
readFile(input.files[i],filename);
}
}
}
} //end readFiles






function readFile(file,filename) {
var reader = new FileReader();


reader.addEventListener("load", function() { alert(filename);}, false);


reader.readAsDataURL(file);


} //end readFile

如果有人正在添加一个将复选框更新到事件侦听器的函数,你将不得不使用event.target而不是this来更新复选框。

2019年,很多api发生了变化,最好的答案不再有效,没有修复错误。

分享一些工作代码。

受到以上所有答案的启发。

 button_element = document.getElementById('your-button')


button_element.setAttribute('your-parameter-name',your-parameter-value);


button_element.addEventListener('click', your_function);




function your_function(event)
{
//when click print the parameter value
console.log(event.currentTarget.attributes.your-parameter-name.value;)
}
我的方法非常简单。这可能对其他人有用,就像它帮助了我一样。 它是…… 当多个元素/变量被赋给同一个函数时,你想传递引用,最简单的解决方案是…

function Name()
{


this.methodName = "Value"


}
< p >就是这样。 这对我很管用。 那么简单。 < / >强

因为你的事件监听器是'click',你可以:

someObj.setAttribute("onclick", "function(parameter)");

一个简单的方法就是这样

    window.addEventListener('click', (e) => functionHandler(e, ...args));

对我有用。

我建议你这样做:

var someVar = some_other_function();
someObj.addEventListener("click", (event, param1 = someVar) => {
some_function(param1);
}, false);

另一个解决方法是使用数据属性

function func(){
console.log(this.dataset.someVar);
div.removeEventListener("click", func);
}
    

var div = document.getElementById("some-div");
div.setAttribute("data-some-var", "hello");
div.addEventListener("click", func);

jsfiddle

完美的解决方案是像这样使用闭包:

function makeSizer(size) {
return function () {
document.body.style.fontSize = `${size}px`;
};
}


//pass parameters here and keep the reference in variables:
const size12 = makeSizer(12);
const size24 = makeSizer(24);
const size36 = makeSizer(36);


document.getElementById('size-12').addEventListener("click", size12);
document.getElementById('size-24').addEventListener("click", size24);
document.getElementById('size-36').addEventListener("click", size36);


document.getElementById('remove-12').addEventListener("click", ()=>{
document.getElementById('size-12').removeEventListener("click", size12);
alert("Now click on 'size 12' button and you will see that there is no event listener any more");
});
test<br/>
<button id="size-12">
size 12
</button>


<button id="size-24">
size 24
</button>


<button id="size-36">
size 36
</button>


<button id="remove-12">
remove 12
</button>

因此,基本上你将一个函数包装在另一个函数中,并将其分配给一个变量,你可以注册为事件侦听器,但也可以取消注册!