情况有点像——
var someVar = some_other_function();
someObj.addEventListener("click", function(){
some_function(someVar);
}, false);
问题是 someVar
的值在 addEventListener
的侦听器函数中不可见,它可能被视为新变量。
为什么不直接从事件的目标属性中获取参数呢?
例子:
const someInput = document.querySelector('button'); someInput.addEventListener('click', myFunc, false); someInput.myParam = '这是我的参数';函数 myFunc(evt) { window.alert(evt.currentTarget.myParam); }
JavaScript 是一种面向原型的语言,请记住!
您编写的代码绝对没有问题。 some_function
和 someVar
都应该是可访问的,以防它们在匿名的上下文中可用
function() { some_function(someVar); }
被创建。
检查警报是否为您提供了您一直在寻找的值,确保它可以在匿名函数的范围内访问(除非您有更多代码在对 addEventListener
的调用旁边的同一 someVar
变量上运行)
var someVar;
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click", function(){
some_function(someVar);
}, false);
.bind()
方法创建 bound function
将解决循环问题 developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
这个问题很老,但我想我会提供一个使用 ES5 的 .bind()
的替代方案 - 供后代使用。 :)
function some_func(otherFunc, ev) {
// magic happens
}
someObj.addEventListener("click", some_func.bind(null, some_other_func), false);
请注意,您需要使用第一个参数设置您的侦听器函数作为您传递给绑定(您的其他函数)的参数,而第二个参数现在是事件(而不是第一个,因为它本来是) .
Function.prototype.bind()
你不能 remove the event listener,最好使用柯里化函数(见@tomcek112 答案)
some_other_func
是一个变量,您可以将任何值传递给 some_func
。
相当老的问题,但我今天遇到了同样的问题。我找到的最干净的解决方案是使用 currying. 的概念
代码:
someObj.addEventListener('click', some_function(someVar));
var some_function = function(someVar) {
return function curried_func(e) {
// do something here
}
}
通过命名 curried 函数,它允许您调用 Object.removeEventListener 在稍后的执行时间取消注册 eventListener。
currying function
和一个 curried function
。您应该添加和删除 currying 函数作为 evente 侦听器。在 @tomeck112 的示例中,即 some_function
你可以用'bind'绑定所有必要的参数:
root.addEventListener('click', myPrettyHandler.bind(null, event, arg1, ... ));
这样,您将始终将 event
、arg1
和其他内容传递给 myPrettyHandler
。
http://passy.svbtle.com/partial-application-in-javascript-using-bind
.bind()
但没有 null 作为第一个参数。这没有用。
null
,它适用于 .bind(event, arg1)
,至少适用于 VueJS。
不错的单线替代品
element.addEventListener('dragstart',(evt) => onDragStart(param1, param2, param3, evt));
function onDragStart(param1, param2, param3, evt) {
//some action...
}
removeEventListener
,如果您需要它...
您可以通过将函数声明为变量来添加和删除带有参数的事件监听器。
myaudio.addEventListener('ended',funcName=function(){newSrc(myaudio)},false);
newSrc
是以 myaudio 作为参数的方法 funcName
是函数名变量
您可以使用 myaudio.removeEventListener('ended',func,false);
删除侦听器
myaudio.removeEventListener('ended',funcName,false);
funcName 而不是 func 删除侦听器 :) 我无法编辑您的帖子,因为编辑必须至少有 6 个字符...
您可以通过称为 closure 的 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)
Function.prototype.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);
这是另一种方式(这个在 for 循环中工作):
var someVar = some_other_function();
someObj.addEventListener("click",
function(theVar){
return function(){some_function(theVar)};
}(someVar),
false);
someVar
值应该只能在 some_function()
上下文中访问,而不是从侦听器的上下文中访问。如果您想在侦听器中使用它,则必须执行以下操作:
someObj.addEventListener("click",
function(){
var newVar = someVar;
some_function(someVar);
},
false);
并改用 newVar
。
另一种方法是从 some_function()
返回 someVar
值,以便在侦听器中进一步使用它(作为新的本地变量):
var someVar = some_function(someVar);
利用
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);
在我的项目中完美运行。希望这会有所帮助
for
循环内保持了预期的范围。
$form.addEventListener('submit', save.bind(null, data, keyword, $name.value, myStemComment));
function save(data, keyword, name, comment, event) {
这就是我正确传递事件的方式。
如果我没记错的话,使用 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));
removeEventListener('event', someDifferentBoundedFunction)
2019 年,大量 api 更改,最佳答案不再有效,没有修复 bug。
分享一些工作代码。
受到以上所有答案的启发。
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;)
}
一种简单的执行方法可能是这样
window.addEventListener('click', (e) => functionHandler(e, ...args));
为我工作。
一种方法是使用外部函数执行此操作:
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));
向 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);
storeFunc
的第 4 个参数应该是您的 ref 变量。将您的侦听器删除放在这样的 useEffect 中,您就可以开始了:useEffect(() => { return () => { window.removeEventListener('scroll', storeFunc, false); } }, [storeFunc])
所有函数内部都有一个特殊变量:参数。您可以将参数作为匿名参数传递,并通过 arguments 变量访问它们(按顺序)。
例子:
var someVar = some_other_function();
someObj.addEventListener("click", function(someVar){
some_function(arguments[0]);
}, false);
当我在循环中使用它来查找元素并向其添加侦听器时,我陷入了困境。如果您在循环中使用它,那么这将完美地工作
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);
});
}
也试试这些(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
希望没有错别字:-)
以下答案是正确的,但如果假设您使用 yuicompressor 压缩了 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 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();
以下方法对我来说效果很好。从 here 修改。
函数回调(theVar) { 返回函数() { theVar(); } } 函数 some_other_function() { document.body.innerHTML += "成功了。"; } var someVar = some_other_function; document.getElementById('button').addEventListener('click', callback(someVar));
由于您的事件侦听器是“点击”,您可以:
someObj.setAttribute("onclick", "function(parameter)");
以下代码对我来说很好(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
你需要:
newElem.addEventListener('click', {
handleEvent: function (event) {
clickImg(parameter);
}
});
可能不是最佳的,但对于那些不精通 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
来更新复选框。
我有非常简单的方法。这可能对其他人有用,因为它帮助了我。它是......当您为多个元素/变量分配了相同的功能并且您想要传递引用时,最简单的解决方案是......
function Name()
{
this.methodName = "Value"
}
而已。它对我有用。很简单。
evt.currentTarget.myParam
吗?如果 'someInput' 内有另一个元素,则evt.target
可能是指内部元素。 (jsfiddle.net/qp5zguay/1)addEventListener
用于document
,则evt.target.myParam
对我不起作用。我不得不改用evt.currentTarget.myParam
。