Duck in Custard
Duck in Custard

Reputation: 1103

Preventing event bubbling (for javascript onclick events)

I am using javascript to interact with a CMS which provides a button for users to add things to their basket. However, I am using the javascript to try and prevent the customer from doing so unless they have made a selection from a drop-down menu elsewhere on the page.

As there are many different buttons that could potentially get them to the basket (including the example below) and all of which have different methods for doing so, rather than write many lines of code to prevent each method and then re-enable that method when a selection is made I am trying to do a kind of 'catch-all' fix where I just cover any such buttons / links with another div so as to effectively 'mask' the button below it until they make a decision.

I first tried to use absolute positioned divs to do this which works beautifully until the user does something like re-size a textbox on the page and then suddenly my absolutely positioned div is in the wrong place!!

So I'm now using JQuery's .wrap() which solves this problem nicely.. BUT.. Now I can't use z-index to position the div above the required buttons as those buttons are within the mask not below it!

I have done a lot of reading about event bubbling but I am not sure whether I've not found the right information yet, or maybe I understand it correctly or possibly that event bubbling is leading me down the wrong path all together as I can't seem to take those concepts and apply them to this scenario.

so.....

given the following HTML structure:

<div class="btnMask">
    <div class="button">
        <a onclick="pageSubmit();return false;" href="#" id="addToBasket">
            <span>Add to Basket</span>
        </a>
    </div>
</div>

Plus the following JQuery:

$('.btnMask').click(function() {
    // prevent default actions and alert the customer to select something;
});

How do I go about stopping the tag firing when clicking the .btnMask div? and (in case the answer to that does not make the answer to my other question obvious...) How would I switch that on and off ? (I have a function that checks the drop-down onchange and sets the z-index to 99 / -99 so I would want to change this to incorporate this new method.)

Thank you in advance for your help.

<< EDIT >>

Using the initial answers to this I managed to solve the problems for links that take you away from the page using a regular href.

So I have now fixed the links where the HTML is like the following:

<div class="btnMask">
    <div class="button">
        <a id="nextPage" href="/link/toanotherpage.asp?id=667868465726122926234">
            <span>Click to go to Page 2</span>
        </a>
    </div>
</div>

However, like I said there are many methods being used to take people away from the page and and e.preventDefault(); and e.stopPropagation(); don't work for my original example (presumably because they use an onclick rather than a href ?).

Is there a way to do the same thing as e.preventDefault(); and e.stopPropagation(); are doing on my .btnMask div but will also deal with contained links that are being trigged by an onclick?

thanks

<< EDIT >>

Updated the question title to reflect the exact issue rather than just event bubbling on regular links.

Upvotes: 2

Views: 4759

Answers (3)

Dev Shangari
Dev Shangari

Reputation: 336

Your onclick handler is fired before your jquery click handler. You can do something like this

    function pageSubmit() {
        alert('pageSubmit');
    }
    var link = document.getElementById('addToBasket');
    var linkClickHandler = link.onclick;
    link.onclick = null;
    $('.button').data('linkClickHandler', linkClickHandler);

    $('.button').on('click', function(e){
        var clickHandler = $(this).data('linkClickHandler');
        var link = $(this).find('a').get(0);
        clickHandler.apply(link, [e]);
    });

    $('.btnMask').on('click', function(e){
        if (!$(this).hasClass('test')) {
            e.preventDefault();
            e.stopPropagation();
        }
    });

and the html as

<div class="button">
    <a onclick="pageSubmit();return false;" href="#" id="addToBasket">
        <div class="btnMask test">
            <span>Add to Basket</span>
        </div>
    </a>
</div>

If you remove the class test from btnMask div the pageSubmit handler will not be called, and when it is present the handler is called.

Upvotes: 0

Arun P Johny
Arun P Johny

Reputation: 388316

If you want to prevent event bubbling and cancel default action then you can return false from the event handler.

$('.btnMask').click(function() {
    return false;
});

Or use preventDefault and stopPropagation

$('.btnMask').click(function(e) {
    e.preventDefault();
    e.stopPropagation();
});

Upvotes: 1

alexP
alexP

Reputation: 3765

$('.btnMask').click(function(e) {
    e.stopPropagation();
});

Upvotes: 0

Related Questions