【问题标题】:In Javascript, how to determine and call inherited listeners?在Javascript中,如何确定和调用继承的监听器?
【发布时间】:2011-08-31 13:27:44
【问题描述】:

如果change 侦听器附加到项目,则可以使用item.onchange() 调用它。但是,如果更改触发器来自父节点怎么办?

上下文:使用 input 事件来捕获 INPUT type='number' 项目的向上/向下变化,因为 change捕获它们。

操作原理:使用input进行捕获,但在调用普通change侦听器之前等待500毫秒。当change 侦听器直接附加到目标元素时很容易。这个问题也需要调用 inherited 更改触发器 - 我如何知道是否存在,以及如何调用它们?

HTML:

<form id='f'>
  <input type='number' id='i' />
</form>

Javascript:

// attach main onchange trigger to form
document.getElementById('f').addEventListener('change',changeFunc,true);

// if user "scrolls" number value, do same as change trigger after 500 ms
var inputCt = 0;
function inputToChange(e) {
   inputCt++;
   setTimeout( next, 500 );
   function next() {
      inputCt--;
      if( !inputCt ) {
         // if element has it's own change trigger, call it
         if( e.target.onchange ) e.target.onchange(e);
         // PROBLEM - how to call inherited change triggers
      }
   }
}
document.getElementById('f').addEventListener('input',inputChange,true);

我看到的唯一方法是手动检查祖先,检查存在并在我去的时候调用。但这导致了下一个问题:这些侦听器函数中的任何一个都可能以e.stopPropagation 发出,但我现在看到了确定是否确实如此的方法——这意味着攀登祖先将不起作用。


根据@Andy E 对How can I trigger an onchange event manually? 的回答,解决方案如下:

Javascript:

// attach main onchange trigger to form
document.getElementById('f').addEventListener('change',changeFunc,false);

// if user "scrolls" number value, do same as change trigger after 500 ms
var inputCt = 0;
function inputToChange(e) {
   inputCt++;
   setTimeout( next, 500 );
   function next() {
      inputCt--;
      if( inputCt ) return;
      var change = var change = document.createEvent("Event");
      change.initEvent('change',true,true);
      e.target.dispatchEvent(change);
   }
}
document.getElementById('f').addEventListener('input',inputChange,false);

注意 1:useCapture(第三个)arg 到 addEventListener 是错误的 - 需要为 false,因此在表单触发器之前调用项目触发器。

注意 2:这个函数可能更适合“点击”而不是“输入”——“点击”的问题是需要将焦点和文本定位点击与点击更改值区分开来。

【问题讨论】:

  • "我怎么知道是否有退出"你的意思是退出还是存在?在这种情况下完全不同。
  • @Mark Schultheiss - “存在” - 谢谢
  • 您正在处理事件。您不需要在祖先上“调用”事件,他们应该有事件处理程序来“处理”事件,尽管您可能会考虑“触发”这些事件 - 该事件的作者出于某种原因存在 stopPropagation,因此我会预见到适合父元素处理的“新”事件的触发器,尽管在这里我更愿意看到事件气泡并重构事件传播。
  • @Mark Schultheiss - 我想我们有点绕圈子了。你知道如何为我们创建一个聊天 - 也就是说,如果你愿意花时间吗?

标签: javascript html input dom-events


【解决方案1】:

使用 jQuery,$(e.target).change() 应该可以完成这项工作,我相信。或$(e.target).trigger(eventname),在您的情况下使用eventname = 'change',以及任何其他事件名称。

显然change事件只对inputs、textareas和selects有效,不能嵌套。因此,当父母定义需要在孩子之后触发的更改事件处理程序时,您不会有问题。

【讨论】:

  • 使用 javascript - 打开 jQuery 源代码并复制它们触发事件的方式。为什么不使用 jQuery?
  • 虽然change事件在FORM级别无效,但可以应用在窗体级别,然后窗体中的所有ITEM都会使用它
  • 就我个人而言,我对 js 作为一门语言及其抽象级别非常满意。我个人并不关心 jQuery 对我的隐藏功能,我也不觉得它的符号在美学上令人愉悦。我意识到这是一份少数报告,可能只有像我这样的其他白胡子人士才会喜欢。
  • 好的,不要使用 jQuery。看看他们如何触发事件并窃取它。
  • 如果您不喜欢使用 jQuery,请不要在任何地方使用它——您的所有脚本仍然可以工作。仅在这种特殊情况下使用它来缓解您的生活。为什么不呢?
【解决方案2】:

在事件监听器中,创建对this 对象的引用(例如,var that = this;)。然后,您可以在next 的正文中使用that.onchange(e);

【讨论】:

  • 我完全不理解你。据我所知,this 在活动中是window
  • @cc young 不是。如果您使用addEventListener,则事件处理程序中的this 对象指的是“拥有”处理程序的元素(在您的情况下为document.getElementById('f'))。
  • 在这种情况下,处理函数是 Render 类的一部分。在函数中,this 引用该类,而不是 document.getElementById('f')
【解决方案3】:

更改甚至不会在“向上/向下”时触发我假设您的意思是向上/向下箭头?

如果是这种情况,您将需要为这些 KEY 事件捕获键事件(按键、向上、向下等)。

【讨论】:

  • 例如,在 chrome 中,输入框右侧有向上/向下箭头 - 单击这些递增/递减值。可以使用click 捕获活动,但似乎问题仍然存在。
  • 查看我关于事件、事件触发器等问题的注释。
  • 仅供参考,如果您不想使用图书馆,您可能希望从参考页面开始,例如:quirksmode.org/dom/events/index.html
  • 感谢对 quirksmode 的引用 - 我和那个页面是非常好的朋友。最近发现help.dottoro.com/lagstsiq.php/#Event,这是一个很好的参考。我正在研究的是一个没有外部依赖项的库。
【解决方案4】:

根据@Andy E 对How can I trigger an onchange event manually? 的回答,构建一个事件并分派。已在问题中提供了详细信息。

顺便说一句,onchange 被设置当且仅当change 触发器是通过onchange 属性设置的,不是addEventListener('change',...)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-13
    • 2018-08-25
    • 2013-02-22
    • 1970-01-01
    相关资源
    最近更新 更多