Csati
Csati

Reputation: 1271

Onclick event not running on first button click in Mithril

Why does the "click" callback not invoked the first time after some text is entered into the input like in this fiddle?

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

Upvotes: 8

Views: 3595

Answers (1)

LeoHorie
LeoHorie

Reputation: 1320

The input's onchange event is triggered on mouse down, which causes the view to redraw, thus making the button move down. The click event is triggered on mouse up (try clicking and holding down the mouse button without typing anything to see what I mean). Usually a fast click has a ~200ms gap between the underlying onmousedown and the onmouseup events due to the physical distance between rest and pressed position on the mouse button's mechanical switch.

So basically, what's happening is:

1 - mouse button gets pressed, triggers onchange

2 - view redraws, and moves button down to make room for the text in the <p>

3 - some time later, the mouse button gets unpressed, triggering the onclick

4 - the event looks at the current position of the mouse (which is on top of the <p> now), so it does not trigger the event on the button

You can see that this is the case by typing something, then clicking and holding down the mouse button, then dragging the cursor over the button again.

In order to avoid this problem, you can use a onmousedown instead of a onclick so that both onchange and onmousedown happen within the same animation frame, or if the UI permits, you can move the <p> below the button.

Upvotes: 12

Related Questions