SitePoint Sponsor

User Tag List

Results 1 to 4 of 4
  1. #1
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,208
    Mentioned
    456 Post(s)
    Tagged
    8 Thread(s)

    Stopping defaults and/or propagation

    Noob alert! I was playing around with writing a simple script that would cause a kind of lightbox popup; on clicking a link, a div with several links overlies the page. It's probably full of bad coding, but at least I got something to work.

    The main problem I had was that, if an overlay link was clicked, it also triggered the closing of the overlay. I played around with preventDefault(), but that didn't work. Then I stumbled on stopPropagation(), which seems to do the trick.

    So here's what I have so far:

    Code:
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="utf-8">
    
    <style media="all">
    .hide {display: none;}
    .view {position: absolute; background: rgba(0,0,0,0.4); text-align: center; top:0; bottom: 0; left: 0; right:0; display: table; width: 100%; height: 100%;}
    .view div {display: table-cell; vertical-align: middle;}
    #buttons a {display: inline-block; color: white; background: #30353b; text-decoration: none; padding: 10px; border-radius: 10px;}
    #buttons a:hover, #buttons a:focus {background: black; color: #e7e7e7;}
    #buttons span {display: block; margin-top: 20px; cursor: pointer;}
    </style>
    </head>
    <body>
    
    <p><a id="share" href="#buttons">Share</a></p>
    
    <div id="buttons" class="hide">
    	<div>
    		<a href="http://facebook.com">Facebook</a>
    		<a href="http://twitter.com">Twitter</a>
    		<a href="http://google.com">Google</a>
    
    		<span>Exit</span>
    	</div>
    </div>
    
    <script>
    (function () {
    	"use strict";
    	var d, share, buttons, links, i;
    	d = document;
    	var share = d.querySelector('#share');
    	var buttons = d.querySelector('#buttons');
    
    	share.addEventListener('click', function(event) {
    		event.preventDefault();
    		buttons.className = 'view';
    	}, false);
    
    	buttons.addEventListener('click', function() {
    		buttons.className = 'hide';
    	}, false);
    
    	links = d.querySelectorAll('#buttons a');
    	for(i=0; i<links.length; i++) {
    		links[i].addEventListener('click', function(event) {
    			event.stopPropagation();
    		}, true);
    	}
    }());
    </script>
    </body>
    </html>
    Is there a better way to do this than with stopPropagation()? I don't really understand what it's doing, so if anyone can explain, that would be great. And of course, if there's a better way to go about all this, I'd be happy to know. This is mainly an excuse to learn a bit of JS, although I'm eventually aiming to use this in a project. It's not an essential feature, so in the end, my plan is to create everything in JS and insert it into the HTML. (If JS is off or doesn't fire for some other reason, I'd prefer to have nothing in the HTML.)

    PS—I've purposely left out support for older browsers that don't understand modern JS. Eventually I'll add a test for older browsers and just abort the script if they don't understand it.

  2. #2
    Programming Team silver trophybronze trophy
    Mittineague's Avatar
    Join Date
    Jul 2005
    Location
    West Springfield, Massachusetts
    Posts
    17,191
    Mentioned
    191 Post(s)
    Tagged
    2 Thread(s)
    I'm too sleepy to study the code sample now, but it sounds like a "bubbling" vs. "capturing" thing.
    http://www.quirksmode.org/js/events_order.html
    http://api.jquery.com/event.stoppropagation/
    https://developer.mozilla.org/en-US/...topPropagation

    If @paul_wilkins ; @felgall ; or some other javascript savvy member desn't solve by the time I get some ZZZZZZZ's I look into it more.

  3. #3
    Programming Since 1978 silver trophybronze trophy felgall's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, NSW, Australia
    Posts
    16,836
    Mentioned
    25 Post(s)
    Tagged
    1 Thread(s)
    preventDefault() stops any default action from occurring - for example code triggered by clicking on a link - the default acrion is to go to where ever the href attribute points to. By using preventDefault() you allow the JavaScript to run but without loading the new page specified in the href.

    When you trigger an event listener the third parameter specifies whether you want the event processing to occur in capture mode or bubbling mode. With capture mode the processing starts at the body tag and moves inward tag by tag to the one closest to the point in the page where the click occurred. Bubbling mode then moves outward again from that point back out to the body tag. Where calling stopPropagation() comes in is that the capture/bubbling of the event terminates early at the time of that call so that subsequent tags that might have the same event attached to them will not have the code attached to those tags run unless the spot that triggers the event is outside of the tag that has the stopPropogation() in it.

    So with the preventDefault() in the first event listener clicking on the link when JavaScript is enabled will not jump to <div id="buttons">

    The stopPropagation() means that when one of the <a> tags inside of the <div id="buttons"> is clicked that the event listener handling clicks on that <div> tag will not be run during bubbling because the bubbling will end at the <a> tag where the stopPropogation() is run rather than continuing to run any click event listeners all the way out to the <body> tag (with this code the only such listener is the one on the div tag.

    So stopPropogation() as you have it is exactly the right way to achieve that desired result.
    Stephen J Chapman

    javascriptexample.net, Book Reviews, follow me on Twitter
    HTML Help, CSS Help, JavaScript Help, PHP/mySQL Help, blog
    <input name="html5" type="text" required pattern="^$">

  4. #4
    It's all Geek to me silver trophybronze trophy
    ralph.m's Avatar
    Join Date
    Mar 2009
    Location
    Melbourne, AU
    Posts
    24,208
    Mentioned
    456 Post(s)
    Tagged
    8 Thread(s)
    Quote Originally Posted by felgall View Post
    stopPropogation() as you have it is exactly the right way to achieve that desired result.
    Cool, thanks for the explanation, Stephen. There are plenty of lightbox scripts around, but they all seem to use jQuery, so it's harder to dig in to see how they handle this sort of thing.

    Thanks for your links too, Allan. I'll check them out.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •