简体   繁体   中英

Prevent newly created click event from running

Here's a simplified example of the problem I'm having. Say I have this HTML:

<div id="test">Hello</div>

I have the following event handler attached to this div :

$("#test").on("click", function() {
    console.log("Clicked test!");

    $(document).one("click", function() {
        console.log("Clicked on document!");
    });
});

Here's a jsFiddle of this example.

If I click on "Hello", ideally I would only want "Clicked test!" to appear in my console, and for "Clicked on document!" to appear after I click a second time. However, both log messages appear, as the click event bubbles up to the document object and runs this new click event. Is there a way to prevent this from happening without using stopPropagation , which may have other unintended side effects?

My solution is kind of hacky, but it does work. If you set the document click handler asynchonously, the event doesn't bubble up:

$("#test").on("click", function(e) {
    console.log("Clicked test!");

    setTimeout(function(){
        $(document).one("click", function() {
            console.log("Clicked on document!");
        });
    }, 10);

    return true;
});

See the modified fiddle: https://jsfiddle.net/voveson/qm5fw3ok/2/

Or using on and off with selectors:

$(document).on("click", "#test", add_doc_click)

function add_doc_click() {
    console.log("Clicked test!");
    $(document).on("click", function (e) {

        console.log("Clicked on document!");
    })
    $(document).off("click", "#test", add_doc_click)

}

https://jsfiddle.net/y2q1gocu/

EDIT: to have test and clicked each time:

$(document).on("click", "#test", add_doc_click)

function add_doc_click() {
    console.log("Clicked test!");
    $(document).on("click", function (e) {

        console.log("Clicked on document!");

    })
    $(document).on("click", "#test", function (e) {

        console.log("Clicked test!");

    })
    $(document).off("click", "#test", add_doc_click)

}

https://jsfiddle.net/y2q1gocu/1/

Assuming nothing should happen on the third click, add these two lines at the end of the click handler:

$(this).off('click');
return false;

Fiddle

You can use a class that flags whether or not the element has been clicked on or not.

$("#test").on("click", function(e) {
    console.log("Clicked test!");

    if($(this).hasClass('clicked')){
        $(document).one("click", function(e) {
            console.log("Clicked on document!");
        });
    }else{
         $(this).addClass('clicked');   
    }
});

Incase you want to click Hello once and then remaining on document.

$( "div" ).one( "click", function() {
console.log("Clicked test!");
    event.stopPropagation();
});

 $(document).on("click", function() {
        console.log("Clicked on document!");
    });

https://jsfiddle.net/qm5fw3ok/3/

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM