Question

I am building a sidebar vertical menu that contains Main Menu items and one level of sub-menu items.

I am using Javascript and CSS so that when the user clicks a top-level menu item, its sub-menu items will toggle their visibility - i.e. Click a main item and its sub items will appear. Click the main item again and the sub items disappear.

To avoid the sub-menu from toggling when the user clicks a sub-menu item, I used the event.stopPropagation() method.

The desired result works in Chrome, Safari, and Dolphin, but does not work in Firefox 26.0 nor Android Firefox 26.0.1.

If you run this example (JSBin), you will notice that you can click Menu 2 and/or Menu 3 and a sub-menu will be displayed. That part is fine in all browsers.

However, if you click a sub-menu item (i.e. Menu 3.1) in Firefox, the sub-menu will disappear - which is not the desired effect I want. If you click a sub-menu item in Chrome/Safari, the sub-menu stays visible - which is what I want to occur.

I read on Mozilla Developer Network that the event.stopPropagation() is supported in Chrome, Firefox (Gecko), IE9, Opera, and Safari (WebKit). So, I'm confused as to why the stopProp method is not working in my case.

Can you take a look at my JS example and tell me what's up?

Here's the Javascript that I'm running (also at JSBIN):

function goTo(id) {
     event.stopPropagation();
     location.href = id;
 }

 function toggleChildDisplay(parentElement) {
     var children = parentElement.children;
     var displayStyle = "";
     for (var i = 0; i < children.length; i++) {
         displayStyle = children[i].style.display;
         if (displayStyle.toLowerCase() === "none" || displayStyle === "") 
             children[i].style.display = "list-item";
         else 
             children[i].style.display = "none";
     }
}

... and here's the HTML:

<ul class="level1">
    <li onclick="toggleChildDisplay(this)">Menu 1</li>
    <li onclick="toggleChildDisplay(this)">Menu 2
        <ul class="level2">
            <li onclick="goTo('#')">Menu 2.1</li>
            <li onclick="goTo('#')">Menu 2.2</li>
            <li onclick="goTo('#')">Menu 2.3</li>
        </ul>
    </li>
    <li onclick="toggleChildDisplay(this)">Menu 3
        <ul class="level2">
            <li onclick="goTo('#')">Menu 3.1</li>
            <li onclick="goTo('#')">Menu 3.2</li>
        </ul>
    </li>
</ul>

P.S. The environment that I'm developing on will not allow me to use jQuery.

Was it helpful?

Solution

You need to pass the event as an argument to your function.

goTo(event, '#')

Then you can do event.stopPropagation() and it knows what event is.

http://jsbin.com/OyUvUqa/2

OTHER TIPS

Javascript now..

inline javascript is not a proper way to write code

This example shows a 'innovative' solution to handle a menu.

it also shows you how to correctly handle the event and the event's target.

It uses:

  1. classList
  2. dataset
  3. one handler for multiple elements.
  4. css to display and hide thee elements.

function handler(e){
 e=e||window.event;
 var target=e.target||e.srcElement;
 var action=target.dataset['action']||'no action';
 !(action=='toggle')||(target.childNodes[1].classList.toggle('show'));
 !target.dataset['url']||alert(target.dataset['url']);
}
var firstUL=document.getElementsByTagName('ul')[0];
firstUL.addEventListener('click',handler,false);

DEMO

http://jsfiddle.net/Jj6FY/1/

the boring stuff is that you need to find the various elements with getEl...

but at the end you have more control over everything.

and here is a accordion function.

http://jsfiddle.net/YjCbM/1/

if you have any questions just ask.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top