在Javascript中,如何确定并调用继承的监听器?

发布于 2024-12-02 10:15:58 字数 2252 浏览 0 评论 0原文

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

上下文:使用 input 事件捕获 INPUT type='number' 项上的向上/向下更改,因为 change 不会捕获它们。

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

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 的回答 如何手动触发 onchange 事件?,这是解决方案:

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:addEventListeneruseCapture (第三个)参数是错误的 - 需要为 false,以便在之前调用项目触发器形式触发器。

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

If a change listener is attached to an item, it can be called with item.onchange(). But what if the change trigger emanates from a parent node?

The context: use a input event to capture up/down changes on an INPUT type='number' item since change does not capture them.

Theory of operation: use input to capture, but wait 500 ms before calling normal change listeners. Easy when the change listener is attached directly to the target element. The problem is needed to call inherited change triggers as well - how do I know if any exist, and how do I call them?

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);

The only way I see to do this is to manually go through ancestors, checking for existence and calling as I go. But that leads to the next problem: any one of these listener functions may have issued as e.stopPropagation, but I see now way of determining if this is indeed the case - which means climbing ancestors will not work.


as per @Andy E answer on How can I trigger an onchange event manually?, here is the solution:

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);

note 1: that the useCapture (third) arg to addEventListener was wrong - needs to be false so item triggers are called before form triggers.

note 2: this function would probably be better suited to 'click' than 'input' - the problem with 'click' is that focus and text positioning clicks need to be distinguished from click changing the value.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

梦途 2024-12-09 10:15:58

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

显然,change 事件仅对 inputtextareaselect 有效,并且不能嵌套。因此,当父级定义需要在子级事件处理程序之后触发的更改事件处理程序时,您不会遇到问题。

Using jQuery, $(e.target).change() should do the job, I believe. Or $(e.target).trigger(eventname), with eventname = 'change' in your case, and any other event name in general.

Apparently, change event is valid only on inputs, textareas and selects, which cannot be nested. So you cannot have a problem when parent defines change event handler that needs to be triggered after the child's one.

泪眸﹌ 2024-12-09 10:15:58

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

In the event listener, create reference to this object (for example, var that = this;). Then, you can use that.onchange(e); in the next's body.

无尽的现实 2024-12-09 10:15:58

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

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

A change even will not fire on "up/down" I make the assumption you mean arrow up/down?

If that is the case, you will need to capture the key event (key press, key up, key down etc) for those KEY events.

清欢 2024-12-09 10:15:58

按照 @Andy E 回答 如何手动触发 onchange 事件?,构建一个事件和调度。已在问题中提供详细信息。

顺便说一句,当且仅当通过 onchange 属性设置 change 触发器时,才会设置 onchange使用addEventListener('change',...)

as per @Andy E in answer to How can I trigger an onchange event manually?, build an event and dispatch. have put details in the question.

btw, onchange is set if and only if the change trigger was set through an onchange attribute, not with addEventListener('change',...)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文