当更改事件同时触发时,单击“事件未触发”

Click event not fired when change event fired simultaneously

本文关键字:事件 事件未触发 单击      更新时间:2023-09-26

我有一个问题,我不知道是与事件的流星实现或Javascript事件有关。

我有一个文本框附加到"更改"事件。在它旁边,我有一个附加到"click"事件的按钮。

当我对文本框进行更改并单击按钮时,单击事件不会触发(只有更改事件触发)。所以我必须点击按钮两次,点击事件才会触发。

在Firefox中,如果我将mousedown事件而不是单击事件附加到按钮上,则可以正常工作。在Chrome中,这两种方式都不起作用。

重现问题的最小代码:

JAVASCRIPT: testevent.js

if (Meteor.isClient) {
  Session.set("something", "something");
  Template.hello.foo = function() {
    return Session.get("foo");
  };
  Template.hello.something = function() {
    return Session.get("something");
  }
  Template.hello.events({
    'click .buttonid' : function () {
      console.log("click !");
    },
    'change  .textid' : function (e,t) {
      console.log("change !");
      var bar = e.target.value;
      Session.set("foo",bar);
    }
  });
}
if (Meteor.isServer) {
  Meteor.startup(function () {
    // code to run on server at startup
  });
}

HTML: testevent.html

<head>
  <title>testevent</title>
</head>
<body>
  {{> hello}}
</body>
<template name="hello">
  <input type="text" class="textid" value="{{foo}}"/>
  <input type="button" class="buttonid" value="{{something}}" />
</template>

当我用id替换class时,点击事件触发,但是当我有多个具有相同id的字段时,事件只在一个字段上工作。

这个问题与hello.foo有关:

Template.hello.foo = function() {
  return Session.get("foo");
};

foo的值被用来被动地填充文本输入的事实。如果您删除hello.foo函数,一切都像预期的那样工作。当用户单击该按钮时,将触发change事件,该事件将设置"foo"会话变量,从而导致模板重新呈现。我认为渲染过程会清除剩余的事件队列,因此click处理程序永远不会触发。

有几种方法可以解决这个问题。一种简单(但粗糙)的方法是在更改事件处理程序中延迟设置会话变量。例如:

Meteor.setTimeout(function(){Session.set("foo", bar);}, 100);

显然你需要选择一个适当的延迟,这可能取决于浏览器/数据。或者,您可以将文本输入放在它自己的模板中。例如:

<template name="hello">
  {{> helloText}}
  <input type="button" class="buttonid" value="{{something}}" />
</template>
<template name="helloText">
  <input type="text" class="textid" value="{{foo}}"/>
</template>

将事件正确地绑定到这个新模板后,您将发现helloText将与hello分开呈现,因此您的事件将被保留。