不触发事件处理程序的情况下执行JavaScript事件

9
在我的最新代码中,我为textarea上的focus事件处理程序编写了一个事件处理器。当用户点击textarea时,该事件处理程序将触发,根据所选的textarea设置一些其他DOM状态。但是,在程序的其他地方,我希望以编程方式设置textarea的focus,而不触发该事件处理程序。我知道Backbone有一种静默执行操作的方法。
我唯一的伪解决方案是暂时设置一个变量:
var silence = true;

然后,在我的事件处理程序中,只有在silence为false时才执行逻辑。处理程序仍会被触发,但逻辑不会运行。

是否还有其他更好的策略?


你使用什么来绑定事件,jQuery吗? - Glenn Slaven
我实际上正在使用Meteor https://github.com/meteor/meteor来完成这个特定的项目,所以我主要对原生JS解决方案感兴趣,但jQuery也不错。 - bento
5个回答

5
你可以暂时解除事件绑定,像这样:unbind() 你有一个处理焦点事件的场景:
function focus_handler() {
   //focus handler code
   ...
   ...
}

$('#yourelement').bind('focus', focus_handler);

现在,当您想要以编程方式聚焦元素而不触发事件处理程序时,请参考以下代码部分:

$('#yourelement').unbind('focus');
$('#yourelement').focus();
$('#yourelement').bind('focus', focus_handler);

如果在解除监听器时发生了已发出的事件,可能会导致递归循环。这就是我目前在使用bootstrap-datetimepicker时遇到的问题。 - Barry Chapman

3
<input type="text" name="input" id="input" value="0">
<input type="text" name="input" id="input2" value="0">

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js" type="text/javascript"></script>
<script>
$(function() {

$('#input').focus(function(a,b) {
   if (b) alert('forced');
});

$('#input').trigger('focus', jQuery.Event("focus"));

});
</script>

当事件处理程序的b参数出现时,通过调用$('#input').trigger('focus', jQuery.Event("focus"));来触发事件。因此,您可以使处理程序函数根据正常焦点或强制焦点执行。


非常优雅的解决方案,我喜欢它! - Glenn Slaven
4
没有文件记录?这是在http://api.jquery.com/trigger/中使用extraParameters的用途。为什么不直接传递“true”,而要使用奇怪的“jQuery.Event(“focus”)”呢? - Pierre
这样行不通。当用户执行实际的焦点事件时会发生什么?处理程序不会被调用。 - B T

3
在jQuery中,trigger()可以接受一个事件命名空间。只有使用此命名空间绑定的事件以及默认行为将被触发。
例如:
$('#yourelement').trigger('focus.anyOldNonsense');

如果没有人将“anyOldNonsense”用作事件命名空间,那么应该可以解决问题。

编辑:这适用于1.7.2和1.8.3版本,但在1.9及以上版本中添加数据和命名空间到“focus”事件存在已知的bug


0

由于您无法阻止事件的发生,因此需要某种中介来决定是否发出事件。因此,您将使中介监听所有焦点事件,并告诉该中介是否重新发出事件。然后,您将在该中介上侦听而不是直接在DOM节点上侦听。


-1
<a href='javscript:void()' onClick="()=>myFunction(myParams)">click here</a>

尝试使用这个技巧来设置带参数的onClick函数,而不会在实例化时触发它们。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接