情况有点像 -
var someVar = some_other_function();
someObj.addEventListener("click", function(){
some_function(someVar);
}, false);
问题是someVar
的值在addEventListener
的监听器函数中是不可见的,它可能被视为一个新变量。
你写的代码绝对没有错。 some_function
和someVar
都应该是可访问的,以防它们在匿名的情况下可用
function() { some_function(someVar); }
创建了。
检查警报是否为您提供了您一直在寻找的值,确保它可以在匿名函数的范围内访问(除非您有更多代码在someVar
调用旁边的相同addEventListener
变量上运行)
var someVar;
someVar = some_other_function();
alert(someVar);
someObj.addEventListener("click", function(){
some_function(someVar);
}, false);
使用
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);
在我的项目中完美运作。希望这会有所帮助
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);
还试试这些(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
希望没有拼写错误:-)
向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);
一种方法是使用外部函数执行此操作:
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));
我被困在这里,因为我在循环中使用它来查找元素并添加列表器。如果你在循环中使用它,那么这将完美地工作
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);
});
}
如果我没有错误地使用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));
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。
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>
以下答案是正确的,但如果假设您使用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文件的人来说,它会很有用。
祝好运!!
为什么不从事件的target属性中获取参数?
例:
var someInput = document.querySelector('input');
someInput.addEventListener('click', myFunc, false);
someInput.myParam = 'This is my parameter';
function myFunc(evt)
{
window.alert( evt.target.myParam );
}
JavaScript是一种面向原型的语言,请记住!
所有函数中都有一个特殊变量:arguments。您可以将参数作为匿名参数传递,并通过arguments变量访问它们(按顺序)。
例:
var someVar = some_other_function();
someObj.addEventListener("click", function(someVar){
some_function(arguments[0]);
}, 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
你需要:
newElem.addEventListener('click', {
handleEvent: function (event) {
clickImg(parameter);
}
});
这个解决方案可能有助于寻找
var some_other_function = someVar => function() {
}
someObj.addEventListener('click', some_other_function(someVar));
或绑定变量也会很好
$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...
}
可能不是最优的,但对于那些不是超级精明的人来说足够简单。将调用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
其他替代方案,可能不如使用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);
}
它已针对谷歌浏览器扩展进行了测试,并且在其他浏览器中,e.srcElement可能必须由e.source替换
这个问题已经过时了,但我认为我会提供另一种使用ES5的.bind() - 替代后代。 :)
function some_func(otherFunc, ev) {
// magic happens
}
someObj.addEventListener("click", some_func.bind(null, some_other_func), false);
请注意,你需要设置你的侦听器函数,第一个param作为你传递给bind的参数(你的另一个函数),第二个param现在是事件(而不是第一个,就像它本来的那样) 。
您可以通过将函数声明为变量来添加和删除带参数的eventlisteners。
myaudio.addEventListener('ended',funcName=function(){newSrc(myaudio)},false);
newSrc
是myaudio的方法,因为参数funcName
是函数名变量
您可以使用myaudio.removeEventListener('ended',func,false);
删除侦听器
相当古老的问题,但今天我遇到了同样的问题。我发现最干净的解决方案是使用currying.的概念
代码:
someObj.addEventListener('click', some_function(someVar));
var some_function = function(someVar) {
return function curried_func(e) {
// do something here
}
}
通过命名curried函数,它允许您调用Object.removeEventListener以在稍后的执行时取消注册eventListener。
你可以用'bind'绑定所有必要的参数:
root.addEventListener('click', myPrettyHandler.bind(null, event, arg1, ... ));
通过这种方式,你将总是得到event
,arg1
和其他传递给myPrettyHandler
的东西。
http://passy.svbtle.com/partial-application-in-javascript-using-bind
你可以通过一个名为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)
someVar
值只能在some_function()
上下文中访问,而不是来自听众。如果你想在监听器中使用它,你必须做以下事情:
someObj.addEventListener("click",
function(){
var newVar = someVar;
some_function(someVar);
},
false);
并使用newVar
代替。
另一种方法是从someVar
返回some_function()
值,以便在侦听器中进一步使用它(作为一个新的局部变量):
var someVar = some_function(someVar);
这是另一种方式(这个在for循环中工作):
var someVar = some_other_function();
someObj.addEventListener("click",
function(theVar){
return function(){some_function(theVar)};
}(someVar),
false);