8

为什么在这个小提琴中输入一些文本后第一次没有调用“点击”回调?

var app = {};

app.controller = function(){
    this.data = m.prop("");
    this.click = function(){
        alert("button clicked");
    };
};

app.view = function(ctrl){
    return m("html", [
        m("body", [
            m("div", [
                m("p", ctrl.data()),
                m("input[type=text]", { onchange: m.withAttr("value", ctrl.data) }),
                m("button", { onclick: ctrl.click }, "Click")
            ])
        ])
    ]);
};

m.module(document, app);
4

1 回答 1

12

输入的 onchange 事件在鼠标按下时触发,这会导致视图重绘,从而使按钮向下移动。单击事件在鼠标向上触发(尝试单击并按住鼠标按钮而不输入任何内容以了解我的意思)。由于鼠标按钮机械开关上的静止和按下位置之间的物理距离,通常快速单击在底层 onmousedown 和 onmouseup 事件之间有约 200 毫秒的间隙。

所以基本上,正在发生的事情是:

1 - 鼠标按钮被按下,触发 onchange

2 - 视图重绘,并向下移动按钮为文本腾出空间<p>

3 - 一段时间后,鼠标按钮未被按下,触发 onclick

4 - 事件查看鼠标的当前位置(在 now 之上<p>),因此它不会触发按钮上的事件

您可以通过键入一些内容,然后单击并按住鼠标按钮,然后再次将光标拖到按钮上来看到这种情况。

为了避免这个问题,您可以使用 onmousedown 代替 onclick,以便 onchange 和 onmousedown 在同一个动画帧内发生,或者如果 UI 允许,您可以移动<p>按钮下方。

于 2014-09-15T15:20:45.020 回答