1

I need to create a page that displays the number of times a click occurs anywhere on the page along with a list of where the click happened. Also I have a button that clears the list. The button does not clear. The button click is counted as a click on the page body and that is increasing the count and never clearing it.

HTML:

<p><h3>Click count:<span id="output">
                </span></h3></p>


                <h3>Click locations:</h3>
                <div id="clickLocations"></div> 
        <input id="btn" type="button" value="Validate">

<script>
$(document).ready(function() {
    var count = 0;
    $("body").click(function (event) {

        count += 1; //Count clicks when the body is clicked
        if (count > 0) {
            $("span#output").html(" " + count);
            $("div#clickLocations").append("<ul><li>" + event.pageX + ", " + event.pageY + "</li></ul>"); //Display the x,y location of the click

        }
        $('#btn').click(function () { //Clear text when the button is clicked
            $("div#clickLocations").html('');
            $("span#output").empty();

            event.stopPropagation();
        }); //End button.click 
    }); //End body.click
}); //End document.ready

</script>
Barmar
  • 741,623
  • 53
  • 500
  • 612

2 Answers2

2

You are binding your clicks to "body" which will not record clicks anywhere in the browser window, only within already generated DOM (so in your case it will not record clicks for example below Validate button). It is better to bind do 'document' which will capture clicks in the whole window.

If you do not want to count clicks on the button you need to check the click source and simply discount these clicks. You probably also want to reset the counter once you click validate.

here is the code

$(document).ready(function() {
    var count = 0;
    //note this will capture events everywhere in the window
    $(document).click(function (event) {

        //do not count the button click
        if (event.target.id=="btn") {
            $("div#clickLocations").html('');
            $("span#output").empty();
            //reset counter
            count = 0;
            event.stopPropagation();
        } else {
            count += 1; //Count clicks when the body is clicked
            if (count > 0) {
                $("span#output").html(" " + count);

                // Display the x,y location of the click
                $("div#clickLocations").append("<ul><li>" + event.pageX + ", "
                                   + event.pageY + "</li></ul>");
            }
        }
    }); //End body.click
}); //End document.ready

And the demo

Alexis Wilke
  • 19,179
  • 10
  • 84
  • 156
Michal
  • 13,439
  • 3
  • 35
  • 33
  • Note that the `if(count > 0)` is useless. `count` is set to zero, and incremented by 1 just before the test. So it will always be positive (especially because numbers are floating points in JavaScript so they don't wrap around like integers.) – Alexis Wilke May 08 '14 at 02:41
1

It's almost always wrong to bind one event handler inside another event handler. This causes multiple handlers to be added to the inner element, because you repeat it every time the outer handler fires. The other problem in your code is that event in the inner handler refers to the event that triggered the outer handler, because the inner handler doesn't have an event argument.

Try this:

$(document).ready(function() {
    var count = 0;
    $("body").click(function (event) {

        count += 1; //Count clicks when the body is clicked
        if (count > 0) {
            $("span#output").html(" " + count);
            $("div#clickLocations").append("<ul><li>" + event.pageX + ", " + event.pageY + "</li></ul>"); //Display the x,y location of the click

        }
    }); //End body.click
    $('#btn').click(function (event) { //Clear text when the button is clicked
        $("div#clickLocations").html('');
        $("span#output").empty();

        event.stopPropagation(); // Prevent button click from being counted
    }); //End button.click 
}); //End document.ready

DEMO

BTW, html('') and empty() do the same thing.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Note that your sample code attaches 2x `click` event handlers inside another event handler: `ready`. Just saying... 8-) Also same comment as the other entry, the `if(count > 0)` is not necessary. – Alexis Wilke May 08 '14 at 02:44
  • Since the `ready` handler only fires once, it's not an issue. – Barmar May 08 '14 at 02:49
  • And notice that I said "almost always". This is the obvious exception. I barely think of `ready` as an event handler, it's more boilerplate to ensure that the code is run at the correct time. – Barmar May 08 '14 at 02:50