How can I stop a JavaScript function from affecting a child element?
I have looked around for a solution to this problem, but it's so wonky that I doubt many people have considered it. A web application that I've recently inherited as a web administrator runs on Drupal (version 6). Unfortunately, I am unable to edit the Drupal install or create a custom theme until May due to other obligations that must be tended to first.
First off, I realize and whole-heartedly agree that there are more efficient (and elegant) ways of solving this problem, but for the time being, t开发者_StackOverflow中文版his is what the client wants and is comfortable with implementing.
Anyways, the old administrator was using Drupal to develop the site's navigation. The code that Drupal spits out on the HTML page is:
<ul class="menu">
<li class="expanded first"><a href="/" title="">Housing</a>
<ul class="menu">
<li class="leaf first"><a href="/housing_roster" title="" class="active">Housing Roster</a></li>
<li class="leaf"><a href="/my_floor" title="">My Floor</a></li>
<li class="leaf"><a href="/photoviewer" title="">Photo Viewer</a></li>
<li class="leaf last"><a href="/maintenance_viewer" title="">Building Maintenance</a></li>
</ul>
</li>
<li class="expanded"><a href="/" title="">Reports</a>
<ul class="menu">
<li class="leaf first"><a href="/node/add/fr" title="">Build Floor Report</a></li>
<li class="leaf"><a href="/node/add/ir" title="">Submit Incident Report</a></li>
<li class="leaf last"><a href="/lockout" title="">Submit Lockout</a></li>
</ul>
</li>
<li class="expanded"><a href="/" title="">Office</a>
<ul class="menu">
<li class="leaf first"><a href="/node/add/pack-in" title="">Check In Package</a></li>
<li class="leaf"><a href="/node/add/pack-out" title="">Check Out Building Package</a></li>
<li class="leaf"><a href="/node/add/package-out-all-blgds" title="">Check Out Campus Package</a></li>
<li class="leaf last"><a href="/node/add/equipment-out" title="">Check Equipment Out</a></li>
</ul>
</li>
<li class="expanded"><a href="/" title="">Staff</a>
<ul class="menu">
<li class="leaf first"><a href="/node/add/preprogram" title="">Pre Programs</a></li>
<li class="leaf"><a href="/node/add/program" title="">Post Program</a></li>
<li class="leaf"><a href="/programs/semester" title="">Programming Database</a></li>
<li class="leaf last"><a href="/downloads" title="">Staff Downloads</a></li>
</ul>
</li>
<li class="leaf"><a href="/users/twinchester">My account</a></li>
<li class="leaf last"><a href="/logout">Log out</a></li>
The biggest concern I have with this output is that there is a ul element with the class attribute of "menu" nested inside of another ul element with the class attribute of "menu."
The goal of the JavaScript function that I am writing is to
- Allow for jQuery to expand and collapse the child ul element whenever the respective li element with a class of "expanded" is clicked
- Change the href attribute of ONLY the li elements with a class of "expanded" to "javascript:void(null)" so that they don't redirect the user to any page
Here is the JavaScript function that I've got going so far:
<script type="text/javascript">
$(function() {
//Hide the nested lists
$('ul.menu li.expanded ul.menu').hide();
//Change the destination of the header links
$('ul.menu li.expanded a').attr("href", "javascript:void(null)");
//Toggle the display of the nested lists
$('ul.menu li.expanded a').click(function() {
$(this).next().slideToggle('normal');
});
});
</script>
This works just fine, except it changes the href attribute of the nested li elements to "javascript:void(null)" as well. Is there a way that I can alter my JavaScript function to make sure that it applies the new href attribute ONLY to the li elements with a class of "expanded" and not to the li elements with a class of "leaf?"
At this point, I'm really only interested in an alteration of my JavaScript function. Like I said, I know and agree that there are better methods (such as altering the html output of the Drupal theme to begin with), but if I can get a quick fix in as a temporary solution while I rebuild the entire application, that would be awesome!
Please let me know if you have any suggestions!!!
THANKS!!!
Use a more specific selector:
$('ul.menu > li.expanded > a').attr( ...
The >
matches only immediate children instead of all children.
If you're just trying to prevent the browser from following the href, you don't need the "javascript:void(null)". What you want to do instead is to stop the event from propagating:
$("ul.menu li.expanded > a").click(function(event) {
event.stopPropagation();
...
});
You could try
$('ul.menu li.expanded>ul.menu').hide();
This makes it apply only to the next element.
Another way would be to use
$('ul.menu li.expanded ul.menu:first').hide();
You can use the direct child selector ">". e.g:
<script type="text/javascript">
$(function() {
//Hide the nested lists
$('ul.menu li.expanded ul.menu').hide();
//Change the destination of the header links
$('ul.menu li.expanded > a').attr("href", "javascript:void(null)");
//Toggle the display of the nested lists
$('ul.menu li.expanded > a').click(function() {
$(this).next().slideToggle('normal');
});
});
</script>
精彩评论