有没有办法在focusOut中使用event.preventDefault? 如果没有,为什么?

我想阻止focusOut (或blur )事件的默认事件,并将焦点设置为特定的输入字段。

这是我已经尝试过的:

  • 在函数的开头和结尾使用event.preventDefault() (用于测试目的,而不是样式)

  • return false; 防止传播

  • 将焦点直接设置回元素中的元素(但我发现焦点仍然会切换,因为在.on()函数执行执行焦点切换。我知道我可以使用setTimeout ,但我想避免它并弄清楚问题的核心。)

  • 使用blur而不是focusOut

我的代码是这样的:

  _triggerEventHide: function(inst, eventType) { inst.$target.on(eventType, function(event) { event.preventDefault(); if (!$.suggestBox.$divCont.hasClass($.suggestBox.mouseOverClassName)) { $.suggestBox.$divCont.css({display: 'none'}); //reposition Suggestbox } else { inst.target.focus(); } event.preventDefault(); return false; }); } 

请注意, $target表示jQuery包装的元素, target表示本机DOM元素。

我做了一些研究,已经发现了一些与我的问题相关的文章,但没有一个回答这个问题。

  1. preventDefault对焦点事件不起作用 – 这里给出的答案是使用任何类型的事件操作的替代路径。

  2. 如果没有必要的值 ,将焦点reflection回文本框 – 这里,解决方案是使用setTimeout()将焦点设置回原始元素,这很好 ,但我想了解问题的核心,为什么preventDefault()不能在这里工作。

  3. jQuery preventDefault()不工作 – 我尝试了一些可能的解决方案来自这个线程,比如使用event.stopImmediatePropagation()event.stop() ,但一切都没有用。

我很感激任何时候,知识和解决方案(包括尝试)在这个问题上的贡献。 我真的想学习……

这是一个jsFiddle ,向您展示问题…随意玩它并尝试不同的解决方案。

经过一些研究后,我发现只有某些事件是“可取消的”。

  • 引用自http://help.dottoro.com/ljwolcsp.php

    您可以检查是否可以使用所有浏览器中的cancelable属性取消事件,但在版本9之前的Internet Explorer中除外。虽然Firefox中存在cancelable属性,但无论事件的可取消状态如何,它都会返回true。 无法确定是否可以在版本9之前的Internet Explorer中取消事件。

    请注意,对不可取消事件使用preventDefault方法和returnValue属性不会导致错误。 当事件处理程序返回false时,该事件将被取消。 您可以使用它而不是preventDefault方法和returnValue属性。 参见下面的实施例2。

  • Javascript中的每个事件都有一个可取消的属性,如果可以阻止该事件,则定义为“true”;如果无法取消该事件,则定义为“false”。 参考: http : //help.dottoro.com/ljeosnqv.php

  • 演示此属性的http://help.dottoro.com/ljeosnqv.php示例脚本可以在jsFiddle上找到(节省空间)。 请注意代码中有关Firefox如何始终为事件对象中的cancelable属性返回true的注释。

一般原则是:

  $('selector').on(eventType, function (event) { alert(('cancelable' in event)); //will return true alert(event.cancelable); //will return true if event can be cancelled //NOTE: Firefox mistakenly always returns true }); 
  • 事件具有预设的发生顺序,具体取决于具体情况。 例如,如果单击鼠标按钮,则eventTriggers的顺序为:mousedown,mouseup和click。 参考:www.w3.org/TR/DOM-Level-2-Events/events.html#Events-Event-initMouseEvent

  • 引自http://www.w3.org/TR/2003/NOTE-DOM-Level-3-Events-20031107/events.html#Events-flow-cancelation

    “可取消事件”是与默认操作相关联的事件,允许在DOM事件流期间取消该操作。 在事件流期间的任何阶段,触发的事件侦听器都可以选择取消默认操作或允许默认操作继续。 对于浏览器中的超链接,取消操作将导致不激活超链接。 并非本规范中定义的所有事件都是可取消事件。

  • 有时,事件序列使得DOM默认操作将在您要取消的事件出现之前显示,在这些情况下,您无法取消默认操作,因为它已经发生。 也就是说默认操作发生事件发送之前


我的解决方案

话虽如此,我确实找到了解决我的问题的方法,并且或多或少地解决了这个问题。 基本上我有一个eventListener已经有一个focusin元素,我希望这个元素保持焦点。

 
$('#idBox').on('focusin', function () { $('#div').append('focused'); //do something }

最初我点击时尝试使用setTimeout事件,但我发现这并不好,因为它再次触发了我的focusin事件。 所以我们需要的是在DOM切换焦点的默认操作之前调度的事件。 我确实发现有一个事件符合这个要求,但只适用于IE …典型。 您的信息是: “onbeforedeactivate” ,可以取消 。 但是,由于跨浏览器兼容性很重要,我们不应该使用此eventTrigger。 相反,我发现事件mousedown发生在DOM开始其焦点改变行为之前。

所以我们能做的是:

 $(document).on('mousedown', function(event) { target = event.target; // the element clicked on myTarget = document.getElementById("idBox"); // the element to keep focus if (target !== myTarget) { event.preventDefault(); //prevent default DOM action event.stopPropagation(); //stop bubbling return false; // return } }); 

还有很多其他方法可以解决这个问题。 我个人不喜欢将eventListener设置为整个文档,而是为了演示它的用途。


脚注:阅读Javascript中有关事件处理的更多信息的好文章是http://help.dottoro.com/ljtdqwlx.php我偶然发现了一个令人惊奇的资源。

我们知道导致问题的是点击function。 因此,在像chrome这样的普通资源管理器中,你可以删除mousedown事件然后阻止默认。

但这在ie中不起作用,但我们可以使用beforedeactivate事件而不是http://msdn.microsoft.com/en-us/library/windows/apps/jj569321.aspx 。 它可以被确定,即焦点在变化时。 所以只是防止它。

代码是这样的:

  $inp.on('blur', function(){ self.hide(); }); isIE && $inp.on('beforedeactivate', function(evt){ mousedown && evt.preventDefault(); }); $holder.on('mousedown', function(evt){ evt.preventDefault(); mousedown = 1; }); 
 inst.$target.on("blur", function() { if (!$.suggestBox.$divCont.hasClass($.suggestBox.mouseOverClassName)) { $.suggestBox.$divCont.css({'display': 'none'}); //reposition Suggestbox return true; } inst.target.focus(); return false; }); 

需要看你的HTML。 我认为你没有正确地调用EX:

$.suggestBox我认为应该是$(".suggestBox") ,但我不知道你看到你的htnl