Do something on hover if sibling element hasClass - javascript

I have a list, which all include a link and an image each. Some of the images have a class which others do not.
<ul>
<li>
<a>link 1</a>
<img src="http://foo.com/" />
</li>
<li>
<a>link 2</a>
<img src="http://foo.com/" />
</li>
<li>
<a>link 3</a>
<img src="http://foo.com/" class="myClass" />
</li>
</ul>
I want to do something on hover of those links, but only if the associated image has that class.
This is what I'm currently trying:
$('ul li a').hover(
function() {
if ($(this).siblings('img').hasClass('.myClass')) {
console.log('it has the class');
}
});
What is the correct syntax for this?

You should not pass . to the hasClass method, remove it.
if ($(this).siblings('img').hasClass('myClass')) {
In case that classes are not added/removed dynamically, you can also use .filter() method:
$('ul li a').filter(function() {
// return $(this).siblings('img').hasClass('myClass');
return this.nextElementSibling.className.indexOf('myClass') > -1;
}).hover(function(){
// ...
});
Or + adjacent selector.

Related

how do i add an active class on the parent li when i select an item on it. using javascript

$(function() {
var pgurl = window.location.href.substr(window.location.href
.lastIndexOf("/") + 1);
$("#nav ul li a").each(function() {
if ($(this).attr("href") == pgurl || $(this).attr("href") == '')
$(this).addClass("active");
});
});
here is the js that I am using to put active class on the li.
it works fine, but when I am selecting an item (the child) inside my sorta like dropdown list. it will get an active class, but i also want the parent li to get an active class also.
<%#include file="header.jsp"%>
<div id="nav">
<ul>
<li class="headerFont"><b>HOME</b></li>
<li class="headerFont"><a href="link.jsp"><b>HOW TO
DONATE</b></a></li>
<li class="headerFont"><a class="tangina" href="#"><b>DONATE</b></a>
<ul>
<li class="headerFont"><a href="link2.jsp"><b>DONATION
CENTER <img id="arrow" src="img/arrow.png" />
</b></a></li>
<li class="headerFont"><a href="link3.jsp"><b>HOW ELSE
CAN I DONATE? <img id="arrow" src="img/arrow.png" />
</b></a></li>
</ul></li>
<li class="headerFont"><b>GET DONORS</b></li>
<li class="headerFont"><b>ABOUT BLOOD</b>
<ul>
<li class="headerFont"><a href="Bfacts.jsp"><b>BLOOD
FACTS <img id="arrow" src="img/arrow.png" />
</b></a></li>
<li class="headerFont"><a href="news.jsp"><b>NEWS <img
id="arrow" src="img/arrow.png" /></b></a></li>
<li class="headerFont"><a href="faqs.jsp"><b>FAQS <img
id="arrow" src="img/arrow.png" /></b></a></li>
</ul></li>
<li class="headerFont"><b>ABOUT US</b></li>
<li class="headerFont"><b>LOG IN</b>
<ul>
<li class="headerFont"><a href="#"><b>REGISTER <img
id="arrow" src="img/arrow.png" /></b></a></li>
</ul></li>
</ul>
</div>
<div class="triangle"></div>
<div class="triangle2"></div>
Change this line
$(this).addClass("active");
to
$(this).closest('li').addClass('active');
The closest operator tells jQuery to look for the nearest li in the DOM tree. In this case, the nearest parent.
A better href string slicing method:
**Here's a fiddle
And here's a better (read: more accurate) string slicing function:
/* start of code...*/
var pgurl = sliceString(window.location.href);
/*... rest of code */
function sliceString(s) {
s = s.split("").reverse().join("");
if (s.indexOf('/') === 0){
s = s.substring(1);
}
s = s.substring(0, s.indexOf('/'));
return s.split("").reverse().join("");
}
This will remove any trailing / character, and more accurately select the end-of-string url you're looking for.
Edit, the second:
Alright, if you want all parents to be selected then you can use the parents() selector like so:
$(this).parents('li').addClass('active');
Another fiddle example
Final edit:
The third solution I provided does select the li that has the a element which was clicked, as well as all its parent li elements. Keep in mind that the top-level li (headerFont in your provided example) contains all the child li items as well, not just the one that was clicked. If you only want the text selected for DONATE, then add that to your CSS like
nav > ul > li.active b,
nav > ul > li > ul li.active {
/* ACTIVE STYLES */
}
Those two CSS selectors combined will select the top-level b element in your nav, as well as an non-top-level li element that was clicked.
$(this).parent().addClass('active');

Refer to nested HTML elements with jQuery

I have some extensive HTML element in the following (simplified) format:
<div id="firstdiv" class="container">
<ul>
<li id="4"> <a title="ID:4">Tree</a>
<ul>
<li id="005"> <a title="ID:005">Leaf Tree</a>
<ul>
<li id="10"> <a title="ID:10">Fruit Tree</a>
<ul>
<li id="0050338"> <a title="ID:0050338">Apple Tree</a>
<ul>
<li id="399"> <a title="ID:399">Green Apple Tree</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</li>
<li id="005"> <a title="ID:005">Conifer</a>
<ul>
<li id="10"> <a title="ID:10">Pine Tree</a>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
I want to access the value of the title attributes of all a-tags inside the div-container with the id="firstdiv" on click.
I tried the following jQuery function but it didn't work:
$("#firstdiv").children("a").on('click', function () { /*some code here*/ });
Any ideas what I'm doing wrong?
children() only goes one deep try find()
$("#firstdiv").on('click', function () {
$(this).find('a').each(function(){
console.log($(this).attr('title'))
})
});
will get all a tags titles when the #first_div is clicked
$("#firstdiv a").on('click', function () {
console.log($(this).attr('title'))
});
will get the title of the a tag you clicked on
children() does what it says, looks at child nodes only - not descendant nodes also. For that, you need find(). However, you need neither in your case, just a change to your selector.
$('#firstdiv a')
As with CSS, a space in the selector denotes a child OR descendant.
According to the jQuery documentation
The .children() method differs from .find() in that .children() only
travels a single level down the DOM tree while .find() can traverse
down multiple levels to select descendant elements (grandchildren,
etc.) as well
So change your selector to:
$("#firstdiv").find("a").on("click", function () {});
This will search everything beneath #firstdiv in your DOM tree.
Or even:
$('#firstdiv a').click(function(){
... do stuff
});
That will select all 'a' elements within #firstdiv
Try this http://jsfiddle.net/ApfJz/22/
$("#firstdiv a").on('click', function () { alert($(this).attr('title')); });
Demo
$(document).ready(function() {
$('#firstdiv a').click(function(){
alert($(this).attr('title'))
});
});
$("#firstdiv").find("a").on('click', function () {
});

when open the page,why can't hide the content?

I have added the Prototype library to my site, then add the following code.when i open the page, i want to all the content in the ul are hidden.
Event.observe(window, 'load', function() {
$$('.block-category li.parent ul').hide() //why this line doesn't work
$$('.block-category li.parent > a span').each(function (element) {
element.observe('click', function (e) {
e.element().up().next('ul').toggle();
e.preventDefault();
});
});
});
html:
<div class="block block-category">
<li class="level-top parent">
<span>text one</span>
<ul> //the 1 ul
<li><a><span>....</span></a></li>
<li><a><span>....</span></a></li>
<li><a><span>....</span></a></li>
<li><a><span>....</span></a></li>
</ul>
</li>
<li class="level-top"><span>....</span></li>
<li class="level-top parent">
<span>text two</span>
<ul> //the 2 ul
<li><a><span>....</span></a></li>
</ul>
</li>
<li class="level-top parent">
<span>text three</span>
<ul>
<li><a><span>....</span></a></li>
<li><a><span>....</span></a></li>
</ul>
</li>
</div>
thank you.
The $$() method returns a list of elements that match that CSS selector - if you want to iterate over them and run the same method use the invoke() method
$$('.block-category li.parent ul').invoke('hide');
$$('.block-category li.parent ul').invoke('observe','click',function(){
alert('element was clicked');
});
If you need to do more than just run a single method use the each() method
$$('.block-category li.parent ul').each(function(item){
item.hide();
//item.update('new content');
//etc
});
Try this, seams that hide cannot applied to a set of elements directly:
$$('.block-category li.parent ul').each(function(elm) {
elm.hide();
});

Add Class to ALL Child of UL element

Well, I wanted to add class to all of li's of my ul, yet I don't know why it won't work.
My CSS code:
.vnav-menu li.selected {
background:#fff;
}
here's my html code for it.
<ul class="vnav-menu"> <!-- Initiates Showing/Hiding Dashboard Containers -->
<li onclick="vnav_function('current_offer');" id="current_offer_li" class="selected"> <a> CURRENT OFFERS </a></li>
<li onclick="vnav_function('draft_offer');" id="draft_offer_li"> <a> DRAFT OFFERS </a></li>
<li onclick="vnav_function('expired_offer');" id="expired_offer_li"> <a> EXPIRED OFFERS </a></li>
<li onclick="vnav_function('offer_code');" id="offer_code_li"> <a> OFFER CODE </a></li>
<li onclick="vnav_function('title');" id="title_li"> <a> TITLE </a></li>
<li onclick="vnav_function('schedule');" id="schedule_li"> <a> SCHEDULE </a></li>
<li onclick="vnav_function('offer_type');" id="offer_type_li"> <a> OFFER TYPE </a></li>
</ul>
And here is my code for the function vnav_function()
function vnav_function(data) { //Showing/Hiding Dashboard Containers
$('.vnav-menu li').each(function(i)
{
$(this).attr('id').addClass("selected");
});
}
Well, for some reason it won't work though. any ideas for this stuff?
.attr('id') returns a string. I think that you want to use the ID for comparison:
if ($(this).attr('id') == $(data.target).attr('id') {
$(this).addClass('selected');
}
However, it would be much easier to just do
function vnav_function(data) {
$(this).addClass('selected');
}
...and it would be even easier to do
<ul class="vnav-menu"> <!-- Initiates Showing/Hiding Dashboard Containers -->
<li id="current_offer_li" class="selected"> <a> CURRENT OFFERS </a></li>
<li id="draft_offer_li"> <a> DRAFT OFFERS </a></li>
<li id="expired_offer_li"> <a> EXPIRED OFFERS </a></li>
<li id="offer_code_li"> <a> OFFER CODE </a></li>
<li id="title_li"> <a> TITLE </a></li>
<li id="schedule_li"> <a> SCHEDULE </a></li>
<li id="offer_type_li"> <a> OFFER TYPE </a></li>
</ul>
$(".vnav-menu li").on('click', function () {
$(this).addClass('selected');
});
You may even want to do:
$(".vnav-menu li").on('click', function () {
$(".vnav-menu").removeClass('selected');
$(this).addClass('selected');
});
You are trying to invoke the addClass method on the string returned by $(this).attr('id'). Try using the addClass method on the jQuery collection returned by $(this):
$(this).addClass("selected");
No jQuery:
function getElementsByCSSSelector(s) {
return Array.prototype.slice.call(document.querySelectorAll(s));
}
getElementsByCSSSelector('.vnav-menu li').forEach(function(li) {
li.classList.add("selected");
});
function vnav_function(data) { //Showing/Hiding Dashboard Containers
$('.vnav-menu li').each(function()
{
$(this).addClass("selected");
});
}
Or just:
function vnav_function(data) {  //Showing/Hiding Dashboard Containers
$('.vnav-menu li').addClass('extra');
}
Well no need to use .each instead $('.vnav-menu li').addClass('extra'); this can add class to every li inside ul.vnav-menu

How to create a sitemap using jQuery

I have following markup
<div id="mnuMain">
<ul>
<li>Dashboard</li>
<li>Market Trends</li>
<li>Master
<ul>
<li>Products</li>
<li>Segments</li>
<li><a href="#" >Companies</a></li>
</ul>
</li>
<li>Settings
<ul>
<li>Dashboard Settings</li>
</ul>
</li>
</ul>
<br style="clear: left" />
</div>
<div id="divNavigation" style="height:20px;width:100%;
background:gray;color:white">
</div>
My question is
How to track parents upward when I click on particular <a> so that divNavigation
will contain suppose now I have clicked on "Segments" divNavigation should have Master > Segments with links.
rushed codes
$(function() {
$('#mnuMain ul li a').click(function() {
var $li = $(this).parents('li');
var container = $('#divNavigation').empty();
$li.each(function(i) {
if (i > 0) {
$('<span>></span>').prependTo(container);
}
$(this).children('a:first').clone().prependTo(container);
});
return false;
});
});​
demo
$("#mya").parent() for accessing the immediate parent. Use parents() for accessing all ancestors. This is if you have id. If you don't then you may need something like this:
$("a").each( var parent = $(this).parent(); <use parent to do stuff>);

Categories

Resources