我正在处理一种情况,我需要将jQuery事件绑定到页面以处理通过JSF生成的UI更新。唉,JSF糟透了,它坚持在所有事情上点击活动,这会抢占我的任何jQuery工作。
感谢SO的优秀人员,我找到了解决方案:
mixing my jQuery click events with existing object's onclick attribute
逻辑是:
onclick
属性并将它们存储在变量中。eval
原始的onclick:eval(onclickValueVariable)
这在我的所有虚拟onclick事件测试中都有用。
但是那个实时JSF页面失败了。问题是所有的onclick都以'return false'结束,这导致了这个错误:
return not in function
例如:
<div class="uglyJSFcreatedTag" onclick="console.log('hey');return false">
jQuery会解雇它:
var $jsfTag = $('.uglyJSFcreatedTag');
var cacheOnclick = $jsfTag.attr(onclick);
$jsfTag.removeAttr('onclick');
...bunch of logic here to decide if the inline onclick should fire and, if so...
eval(cacheOnclick)
问题是return false
。看起来在射击eval时无法返回任何内容。
有解决方案吗?我想我可以将值作为字符串并进行字符串解析以删除所有返回false,然后从脚本本身调用它。但这听起来有点混乱。有更优雅的解决方案吗?
如果没有,我应该在调用eval
之前过滤掉哪些特定的JS语句?
答案 0 :(得分:6)
两个选项:
1。使用当前的方法,只需在评估之前用函数包装onclick字符串。存储结果,并将其作为函数调用。请务必使用相应的this
上下文调用它:
var f = eval("(function(){ "+cacheOnclick+"})");
f.call($jsfTag[0]);
注意:函数声明周围的括号()
在eval中是 required 。这使得声明成为一个表达式(从语法上讲),从而使它在eval中合法化。
2。而不是抓取onclick 属性,从dom元素本身获取实际函数。另外,除非你需要对你的代码中的jsf处理函数做一些特别的事情,我建议你直接将JSF函数添加为jquery click处理程序,而不是从你的代码中明确地调用它:
var $jsfTag = $('.uglyJSFcreatedTag');
$jsfTag.bind('click', $jsfTag[0].onclick);
$jsfTag.removeAttr('onclick');
就个人而言,我会采用方法#2,但任何一方都应该工作。
更新:以下是选项#2的附加说明:
var $jsfTag = $('.uglyJSFcreatedTag');
这是你的例子 - 我们使用jquery来检索一个包含所有带有类名'uglyJSFcreatedTag'的元素的集合。
$jsfTag.bind('click', $jsfTag[0].onclick);
这将从集合($jsfTag[0]
)中获取第一个元素,并获取该元素对象的onclick
属性。 .onclick
是一个javascript属性,包含对浏览器根据“onclick”属性的字符串内容生成的已编译函数的引用。现在,由于我们有处理函数,我们可以使用jquery bind()
function将它直接绑定到jquery click事件。
$jsfTag.removeAttr('onclick');
最后,我们只删除该属性。这没关系,因为我们已经通过jquery绑定了这个函数。如果我们不将它从“旧式”onclick中删除,那么它将被调用两次。
注意:您可能已经注意到上述代码仅适用于所选集合中的第一个元素。对于你的集合包含多个元素的极有可能的情况,你需要循环遍历集合并分别处理每个元素。以下是您将如何做到这一点:
var $jsfTag = $('.uglyJSFcreatedTag');
$jsfTag.each( function(idx, element) {
$(element).bind('click', element.onclick).removeAttr("onclick");
});
如果你想跳过某些元素的jsf处理程序,那么在“each loop”中插入逻辑来测试它,并跳过调用以相应地绑定。
如果您必须继续从您的点击处理程序中调用jsf处理程序,那么至少考虑使用element.onclick
而不是$(element).attr('onclick')
。后者需要eval,而前者则不需要。
答案 1 :(得分:4)
我认为将代码包装在匿名函数中并立即调用它应该比过滤掉return语句更容易。
evalCode = "function() {" + evalCode + "}()";