jQuery hierarchy issue with next() - javascript

Seems like $("img").next().hide(); is not working when both the image and div tag are a child of a paragraph.
<p>
<img src="image.jpg" />
<div>text</div> // this div is set to 'display: none' by default in css
</p>
Yet, if I substitute <div> with <span>
<p>
<img src="image.jpg" />
<span>text</span>
</p>
or if I omit the <p> tags
<img src="image.jpg" />
<div>text</div>
the jQuery selector does work properly. Any ideas why this is the case? Is it related to inline and block display? How can I make it work as described in the top code example?
This is the jQuery code I am using:
$(document).ready(function(){
$("img").hover(
function()
{
$(this).next().show();
},
function()
{
$(this).next().hide();
}
);
});
Thanks for your help!

You should not use block element (DIV) inside inline elmenents (P).
Instead of P use DIV with class set like P.

The p element does only allow inline-level elements as child elements. This may be the reason for why your first example does not work.

Related

remove parent node from javascript

I have a div like the following
<div id="basedata-legend-land" class="legends">
<p class="update_villages_2013">Villages</p>
<p><img src="url" alt="legend" class="update_villages_2013"></p>
<p class="district_boundaries">District Boundaries</p>
<p><img src="url" alt="legend" class="district_boundaries"></p>
</div>
As you can see, i have used the same class name for p element and the img inside the other p element. I want to remove these elements when clicking on a button based on the class name. For that i did something like this
$(`.legends .update_villages_2013`).remove();
This works but when the img is removed, it leaves a empty p element. I want to remove that as well. So basically if i run this code
$(`.legends .update_villages_2013`).remove();
this is how the div should appear
<div id="basedata-legend-land" class="legends">
<p class="district_boundaries">District Boundaries</p>
<p><img src="url" alt="legend" class="district_boundaries"></p>
</div>
I couldn't just use the parentNode property because if i do, it will remove the main div as well.
You can use :has() to select elements that have a matching descendant.
$(`.legends *:has(.update_villages_2013)`).remove();
$(`.legends .update_villages_2013`).remove();

How can I add class to parent if child contains class?

I am trying to add a class to a parent DIV if it has a child IMG element with class of "testing".
<article>
<div id="on-1" class="box">
<img src="110.jpg">
</div>
<div class="present">
<img class="testing" src="image.jpg">
</div>
</article>
I have set up if statement to check if class "testing" exists. I am having trouble adding class to the parent "article" element though.
if ($("article").find(".testing").length > 0) {
$(.this.parentNode.parentNode).addClass("hasclass");
}
Use parent() to select parent element.
$("article img.testing").parent().addClass('hasclass');
$("article img.testing").parent().addClass('hasclass');
.hasclass {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.0/jquery.min.js"></script>
<article>
<div id="on-1" class="box">
<img src="110.jpg">
</div>
<div class="present">
<img class="testing" src="image.jpg">
</div>
</article>
$('div:has(img.testing)').addClass('hasclass');
Based on your comment on #Tushar's answer, to help elaborate on traversing up many parent nodes, I usually take the following approach:
To add a class to the direct parent div:
$('article img.testing').parent().toggleClass('new-class', true);
And to add the class to the encompassing article parent:
$('article img.testing').parents('article:first').toggleClass('new-class', true);
I also like using toggleClass() as it seems 'cleaner' to avoid any chance of adding the same class twice to an element, although I'm sure jQuery would check for this.
Hope this helps!

Adding Additional Div breaks Existing Jquery Code

I have a very simple div with an image inside:
<div class="stack4">
<img src="images/002m.jpg" width=200>
</div>
And a very simple Jquery function for when you hover over the image:
$(function () {
$('.stack4>img').hover(function(){
prompt('hello');
});
});
This all works fine. However, I'm trying to add additional content to the page, and so put the following HTML directly after the end of the first div:
<div id="menucontainer" class="menuContainer">
<div id="menu" class="menuContent">
<img src="images/003m.jpg" />
<img src="images/004m.jpg" />
</div>
</div>
After I add this, the jquery prompt no longer works. Why would adding anothing div break my existing javascript command like that?
There has to be a script error in the page that is causing a failure. Or there is a very slight chance that your new html in some way introduces an invisible element that covers your stack4 image. If you can provide a link somebody could debug it for you.
It breaks because the selector no longer matches any elements (because the class selector .stack4 does no longer match any element).
<div id="menucontainer" class="menuContainer">
<div id="menu" class="menuContent">
<img src="images/003m.jpg" />
<img src="images/004m.jpg" />
</div>
</div>
$(function () {
$('.stack4>img').hover(function(){
prompt('hello');
});
});
If you look at your javascript, it will:
match any child image of an element with class name stack4
Add a hover listener to each image
Display a prompt on hover.
IF you look at your updated DOM structure, class stack4 no longer exists. To make it work again, you have to replace this selector with your new equivalent, which would be the div with id=menu and class=menuContent.
Now, depending on your needs, you can target either #menu>img or .menuContent>img. If you go with the first one, the javascript fragment will only work for a single menu, with the id of menu. However, if you choose the second approach, any content with the class menuContent will have this functionality. So I'd go with:
$(function () {
$('.menuContent>img').hover(function(){
prompt('hello');
});
});

jquery double function each

I have the following block of HTML code more than once
<div id="page_1" class="page">
<div class="imageDetail_bg">
<img src="../_img/detail_car.jpg" alt="" id="car_detail" class="car_detail"/>
</div><!-- imageDetail-->
<div id="listThumbs">
<div id="thumbsContainer_1" class="thumbsContainer">
<div id="areaThumb" class="areaThumb">
<div id="posThumb_1" class="posThumb">
<img src="../_img/detail_car.jpg" class="detail_img" alt="">
</div>
</div><!--areaThumb-->
<div id="areaThumb" class="areaThumb">
<div id="posThumb_2" class="posThumb">
<img src="../_img/detail_car.jpg" class="detail_img" alt="" />
</div>
</div><!--areaThumb-->
...
...
...
</div><!--listThumbs-->
</div><!--page-->
and the following jQuery code:
$('.page').each(function(i) {
$('.areaThumb').each(function(j) {
$('.detail_img').eq(j).click(function(){
$('.car_detail').eq(i).attr('src', $(this).attr('src'));
});
});
});
What I want to do is: For each page there's a block of thumbs, and when I click in any thumb, the image in #car_detail is replaced by the image of the thumb I clicked. At this moment I can do this, BUT the #car_detail image is replaced in all pages. I'm not getting individually actions for each page. Every click make the action occurs in all pages.
Can anyone tell me what I'm doing wrong?
Thanks
You need not iterate through each element of the jquery selector result to bind a click event.
And you are missing a closing div for thumbsContainer div, add that before each .
Also if you have an element with id car_detail then you should use #car_detail instead of .car_detail
Working example # http://jsfiddle.net/2ZQ6b/
Try this:
$(".page .areaThumb .detail_img").click(function(){
$(this).closest("div.page").find('.car_detail').attr("src", this.src);
});
If the .detail_img elements are being used for the car_detail image then you can simplify the above code to:
$(".detail_img").click(function(){
$(this).closest("div.page").find('.car_detail').attr("src", this.src);
});
You need to give context to your children nodes:
$('.page').each(function(i) {
$('.areaThumb', this).each(function(j) {
$('.detail_img', this).eq(j).click(function(){
$('.car_detail', this).eq(i).attr('src', $(this).attr('src'));
});
});
});
Every this is pointing to the current element given by the jquery function that called it.
[edit] Cybernate found a better way to do what you wanted to. My answer mostly explains why your code did not work as you wanted
I think you have the wrong approach about this,
You should just use cloning and you will be fine...
HTML
<div class="holder">Replace Me</div>
<div>
<div class="car"><img src="img1" /></div>
<div class="car"><img src="img2" /></div>
</div>
JS
$('.car').click(function(){//when you click the .car div or <img/>
var get_car = $(this).clone();//copy .car and clone it and it's children
$('.holder').html('').append(get_car);//put the clone to the holder div...
});
I think this is what you should be doing, simple and elegant... do not understand why you complicate as much :)

Find child with a specific class

I am trying to write code to search all children for a div that has a specific class. The DIV does not have an ID. Here is the HTML I will be using.
<div class="outerBUBGDiv">
<div class="innerBUBGDiv">
<div class="bgHeaderH2">Technology Group</div>
<div class="bgBodyDiv">
<div align="center">
<img height="33" border="0" width="180" src="/heading.jpg"/>
/////other stuff here/////
</div>
</div>
</div>
How can I get the text inside the div with the class bgHeaderH2?
$(this).find(".bgHeaderH2").html();
or
$(this).find(".bgHeaderH2").text();
Based on your comment, moddify this:
$( '.bgHeaderH2' ).html (); // will return whatever is inside the DIV
to:
$( '.bgHeaderH2', $( this ) ).html (); // will return whatever is inside the DIV
More about selectors: https://api.jquery.com/category/selectors/
I'm not sure if I understand your question properly, but it shouldn't matter if this div is a child of some other div. You can simply get text from all divs with class bgHeaderH2 by using following code:
$(".bgHeaderH2").text();

Categories