Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

onclick event not firing after onchange event

Tags:

javascript

Does anyone know how to make a simple JavaScript onclick event fire if the process of clicking the element causes an onchange event to fire elsewhere on the page? I've created a very simple page to demonstrate this problem:

<html>
    <body>
        <input type="text" name="test" id="test1" onchange="return change(event);" />
        <a href="#" id="test2" onclick="return bang();">Bang</a>
        <a href="#" id="test3" onclick="return boom();">Boom</a>
        <script type="text/javascript">
            function change(event) {
                alert("Change");
                return true;
            }

            function bang() {
                alert("Bang!");
                return true;
            }

            function boom() {
                alert("Boom!");
                return true;
            }
        </script>
    </body>
</html>

If you click the bang link you get the Bang! alert. Boom gives you the Boom alert. And if you enter text in the text field and tab out you get the Change alert. All well and good.

However, if you enter text in the text field and, without tabbing or clicking anything else first, click either Bang or Boom you get the Change alert and nothing else. I would expect to see the Change alert followed by either Bang or Boom.

What's going on here? My change event returns true. How can I ensure that my click event is fired?

like image 499
Robert MacGrogan Avatar asked Jul 16 '13 19:07

Robert MacGrogan


People also ask

Why is Onchange not working?

onchange is not fired when the value of an input is changed. It is only changed when the input's value is changed and then the input is blurred. What you'll need to do is capture the keypress event when fired in the given input. Then you'll test the value of the input against the value before it was keypressed.

What triggers Onchange event?

The onchange event occurs when the value of an element has been changed. For radiobuttons and checkboxes, the onchange event occurs when the checked state has been changed.

What is Onclick and Onchange?

So onclick is more of a cross browser solution. onchange happens only after the element lose focus. (You wont see a difference since you are calling alert and losing focus on every change). The pseudo code on MDC pretty much explains the element.

How click event works?

An element receives a click event when a pointing device button (such as a mouse's primary mouse button) is both pressed and released while the pointer is located inside the element.


2 Answers

Okay... So it seems like it's time for a bit of an explanation.

Explanation

You encounter this error because the onchange event is triggered as soon as focus is moved away from the element. In your example the action that takes focuse away from the input element is the mousedown event which triggers as you click down on the mouse. This means that when you mousedown on the link it fires off the onchange function and pops up the alert.

The onclick event on the other hand is triggered on the mouseup event (i.e. when you release the pressure on the mouse - prove this to yourself by click, hold/pause, release on a onlcick event). Back to your situation... Before the mouseup (i.e. onclick) happens the focus is moved to the alert triggered from your onchange function.

Fix

There are a couple of options to fix this. Most simple change from using onclick="...." to onmousedown="....".

Alternatively, you could use setTimeout like,:

function change() {
    setTimeout(function (){
        alert("Change event")
    }, 100)
}

I suggest the onmousedown method as preferred. The setTimeout method will fail if you click and hold on the link for more than the prescribed amount on the timeout.

like image 195
Steven Avatar answered Oct 31 '22 05:10

Steven


The problem is that the alert() function grabs the event chain somehow, test this:

<html>
<body>
    <input type="text" name="test" id="test1" onchange="return change(event);" />
    <a href="#" id="test2" onclick="return bang();">Bang</a> <a href="#" id="test3" onclick="return boom();">Boom</a>
    <script type="text/javascript">
        function change(event) {
          console.log("change");
            return true;
        }  

        function bang() {
            console.log("bang");
            return true;
        }

        function boom() {
            console.log("boom");
            return true;
        }
    </script>
</body>

As you'll see you'll get the expected behaviour in the console.

JSBin

like image 27
bitoiu Avatar answered Oct 31 '22 06:10

bitoiu