Solved

Why do some of my JavaScript / CSS Sprites work and not others?

Posted on 2013-11-17
7
192 Views
Last Modified: 2013-11-18
I'm using this 3-level navigation menu that uses JavaScript to open/close the tree when the open/close icons are clicked.

The idea is that the buttons that open/close the tree will change on click using CSS sprites to show a '+' and a '-' icon.

It works fine for the top-level, but not for the second level. Any ideas why?

JavaScript:

<script type="text/javascript">
<!--
    function toggle(id) {
	   var ul = document.getElementById(id+"-ul");
	   var p = document.getElementById(id+"-p");
	   var c = document.getElementById(id+"-c");

       if(!ul.style.display || ul.style.display == "none"){
          ul.style.display = 'block';
		  p.style.backgroundPosition = '40px 0';
		  c.style.backgroundPosition = '40px 20px';
	   }
       else{
          ul.style.display = 'none';
		  p.style.backgroundPosition = '0 0';
		  c.style.backgroundPosition = '0 20px';
	   }
	}
//-->
</script>

Open in new window


CSS:

#nav{float:left;width:230px;overflow:hidden;}
#nav ul{float:left;width:230px;}
#nav li{float:left;width:210px;padding:10px;border-bottom:#CCC 1px solid;}
#nav li a{text-decoration:none;font-weight:bold;color:#777;font-size:14px;line-height:16px;}
#nav li div{float:left;width:16px;height:16px;background:url(../images/icons/icons.png) 0 0;margin:0 6px 0 0;cursor:pointer;}

#nav li ul{width:196px;padding:0 0 0 14px;display:none;}
#nav li ul li{width:196px;padding:10px 0 0 0;border:none;}
#nav li ul li a{font-size:12px;line-height:14px;}
#nav li ul li div{float:left;width:14px;height:14px;background:url(../images/icons/icons.png) 0 -19px;margin:0 4px 0 0;cursor:pointer;}
#nav li ul .none{width:178px;padding:10px 0 0 18px;}

#nav li ul li ul{width:182px;display:none;}
#nav li ul li ul li{width:172px;padding:10px 0 0 10px;}
#nav li ul li ul li a{font-weight:normal;}

Open in new window


HTML:

<div id="nav">
	<ul>  
    	<li><div id="nav-1-p" onClick="toggle('nav-1');"></div><a href="#">Parent 1</a>
        	<ul id="nav-1-ul">          
                <li class="none"><a href="#">Child 1.1</a></li>
                <li><div id="nav-12-c" onClick="toggle('nav-12');"></div><a href="#">Child 1.2</a>
                    <ul id="nav-12-ul">            
                        <li><a href="#">Grandchild 1.2.1 this is an example of multiple lines</a></li>   
                    </ul>
                </li>      
        	</ul>
    	<li><div id="nav-2-p" onClick="toggle('nav-2');"></div><a href="#">Parent 2</a>
        	<ul id="nav-2-ul">
                <li class="none"><a href="#">Child 1.1</a></li>
        	</ul>
    	</li>
    </ul>
</div>

Open in new window


I've attached the images being used as the sprite.

So in this example the buttons related to 'parent 1' and 'parent 2' correctly toggle. The icons related to 'child 1.2' do not change, but should.

Here is a working example as currently stands: http://www.alexjordan.co.uk/tests/nav/
icons.png
0
Comment
Question by:93jordanaj
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 4
  • 3
7 Comments
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 39654614
Basically the way you have it scripted, disables the CSS, but putting styling inline which overrides the CSS and renders the whole thing a glob of goo.

the proper way to do it is to declare separate classes for each state, and then all the scripting does is change the className.  Not only is it more reliable it is also more efficient to swap className.

Cd&
0
 
LVL 1

Author Comment

by:93jordanaj
ID: 39654638
Thanks for your feedback. I'll try and update based on selecting classes as you suggest.

What JavaScript would I use to implement and remove the classes? ...I started learning JavaScript yesterday, this is my first attempt :)
0
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 39654681
document.getElementById('someid').className
references the classname attribute of the specified element.

changing the class is as simple as:

document.getElementById('someid).className='newclass';

You might find this reference to DOM properties and methods[ helps.


Cd&
0
[Live Webinar] The Cloud Skills Gap

As Cloud technologies come of age, business leaders grapple with the impact it has on their team's skills and the gap associated with the use of a cloud platform.

Join experts from 451 Research and Concerto Cloud Services on July 27th where we will examine fact and fiction.

 
LVL 1

Author Comment

by:93jordanaj
ID: 39654693
I made a slight amendment to try to make use of classes as suggested (baby steps!), sadly it didn't work. Would you mind offering some feedback based on what I changed. The tree opens, but doesn't close with the following:

<script type="text/javascript">
<!--
    function toggle(id) {
	   var ul = document.getElementById(id+"-ul");
	   var p = document.getElementById(id+"-p");
	   var c = document.getElementById(id+"-c");

       if(!ul.style.display || ul.style.display == "none"){
          ul.className = "open";
		  p.style.backgroundPosition = '40px 0';
		  c.style.backgroundPosition = '40px 20px';		  
	   }
       else{
          ul.className = "";
		  p.style.backgroundPosition = '0 0';
		  c.style.backgroundPosition = '0 20px';
	   }
	}
//-->
</script>

Open in new window


.open is simply {display:block;} By default ul is {display:none;} as per my original post.
0
 
LVL 53

Expert Comment

by:COBOLdinosaur
ID: 39654704
There is not much I can do with it based in bits and pieces of code.  You need to post a link to the page so I can see what it is doing; and it is almost time for the football game.

Cd&
0
 
LVL 1

Author Comment

by:93jordanaj
ID: 39654715
http://www.alexjordan.co.uk/tests/nav/

Thanks for looking into this. I'm sure it's just a case of trying to grasp the basics. All I really need is for:

- ul to open and close when the respective '+' or '-' button is clicked
- '+' or '-' to swap on click
- The ability to have the tree automatically opened when on a child/grandchild page with the '+' or '-' set as appropriate

Wouldn't have thought it would have been too tricky, but the JavaScript side is something out of my current skillset.
0
 
LVL 53

Accepted Solution

by:
COBOLdinosaur earned 350 total points
ID: 39655436
The javascript is throwing errors in the console when you click on the second level icons because you are referencing elements that do not exist.  p and c do not exists for every place where you can click, and if you reference them it throws an uncaught error which aborts the script.

there is a nav-1-ul and nav-1-p but there is no nav-1-c
there is a nav-12-ul and nav-12-c but there is no nav-12-p

So when yo run the function you get errors when you reference p.style or c.style which do not exist as properties because the reference is through an element that is not in the document.

Cd&
0

Featured Post

Revamp Your Training Process

Drastically shorten your training time with WalkMe's advanced online training solution that Guides your trainees to action.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Nothing in an HTTP request can be trusted, including HTTP headers and form data.  A form token is a tool that can be used to guard against request forgeries (CSRF).  This article shows an improved approach to form tokens, making it more difficult to…
Originally, this post was published on Monitis Blog, you can check it here . In business circles, we sometimes hear that today is the “age of the customer.” And so it is. Thanks to the enormous advances over the past few years in consumer techno…
The viewer will learn the basics of jQuery, including how to invoke it on a web page. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery.: (CODE)
The viewer will learn the basics of jQuery including how to code hide show and toggles. Reference your jQuery libraries: (CODE) Include your new external js/jQuery file: (CODE) Write your first lines of code to setup your site for jQuery…
Suggested Courses

636 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question