jquery-how to detect child id? - javascript

<div id="first">
<div id="here">...</div>
</div>
<div id="second">
<div id="here">...</div>
</div>
jquery:
$("#second #here").click(function(){});
how to write jquery to detect when I click the second ?

This is the wrong question to be asking, because you are not supposed to have duplicate IDs in a document. An ID is like the social security number of an element. You can't give multiple elements the same one, because then when you tell Javascript to find an element by ID it will be terribly confused by the fact there's more than one and give you unexpected results. The reason ID lookups are as fast as they are is because the browser can have a hash table of ID->element - violating that understanding is a bad practice, to say the least.
When you have several elements that are all of the same "type", the proper practice is to class them:
<div id="first">
<div class="here">...</div>
</div>
<div id="second">
<div class="here">...</div>
</div>
So then you can do:
$('#first').find('div.here');
Or:
$('div.here', '#second');
Or:
$('#first div.here');
Which would all return what you expect them to return.

This is what you are looking for, but like Paolo said, you cannot have duplicate ID's. If you're styling things, use a class.

Related

Need a more elegant way of finding an element in the dom tree with jQuery

I have a few elements flying around in an element that need to be altered when the window finishes loading ($(window).load...)
When the script loads, I've been struggling to find a more elegant way of finding a string.
Noticeably below, you can also see the rampant re-use of parent and next operators...
I've tried closest but it only goes up the dom tree once (from what I understand) and parents has never really worked for me, but I could be using it wrong.
Ex.
$(window).load( function(){
if($(".postmetadata:contains('Vancity Buzz')").length){
$(this).parent().parent().next().next().next().next('.articleImageThumb img').hide();
}
});
HTML output this runs through looks like this:
<div class="boxy">
<div class="read">
<div class="postmetadata">Vancity Buzz</div>
<div class="articleTitle"></div>
</div>
<div class="rightCtrls"></div>
<div class="initialPostLoad"></div>
<div class="ajaxBoxLoadSource"></div>
<div class="articleImageThumb">
<a href="#">
<img src="image.png" class="attachment-large wp-post-image" alt=""/>
</a>
</div>
</div>
I think you want to do this:
$(".postmetadata:contains('Vancity Buzz')")
.closest('.read') //Closest will get you to the parent with class .read
.siblings('.articleImageThumb').hide(); //this will get you all the siblings with class articleImageThumb
this refers to window there not the element you are checking in the if condition.
Fiddle
I don't know if your intention is to have the empty anchor tag just by hiding the image. if so just add a find to it.
You can just do this
$('.articleImageThumb img').toggle($(".postmetadata:contains('Vancity Buzz')").length)
If there are multiple divs and you do need to traverse then there are multiple ways
$(".boxy:has(.postmetadata:contains('Vancity Buzz'))").find('.articleImageThumb img').hide()
or
$('.postmetadata:contains("Vancity Buzz")').closest('.boxy').find('.articleImageThumb img').hide()
or
$(".boxy:has(.postmetadata:contains('Vancity Buzz')) .articleImageThumb img").hide()
Have you looked into parents http://api.jquery.com/parents/ you can pass a selector like so:
$(this).parents('.boxy').find(".articleImageThumb")
Careful though, If there is a parent boxy to that boxy, parents() will return it and thus you find multiple .articleImageThumb.

I need the jquery to reach this nested div

I can't figure out how to reach a nested div from the outer most element. Here is the html:
<li id="slide1">
<div id="video-container">
<div id=video-holder><div id="thumbnail"></div></div>
<div id=video-title></div>
<div id=video-desc></div>
</div>
</li>
I need jquery that will reach the id thumbnail from the starting id of the slide1
Use find to get the descendant.
$("#slide1").find("#thumbnail")
Basically since it is id you can just do: as id is supposed to be unique no matter where it appears.
$("#thumbnail");
For your scenario you want to use startswith selector to select the dynamic id starts with video_fake and in the 5th
slide.
$('#slide5fake').find('[id^=video_fake]').attr('id', 'newId')
$("#slide1").find("#thumbnail")
try this
<li id="slide1">
<div id="video-container">
<div id=video-holder><div class="thumbnail"></div></div>
<div id=video-title></div>
<div id=video-desc></div>
<div id="video-container">
<div id=video-holder><div class="thumbnail"></div></div>
<div id=video-title></div>
<div id=video-desc></div>
</div>
</li>
<script type="text/javascript">
$('#slide1').find('.thumbnail').each(function(){ });//you can get here two thumbnail
</script>
$("#thumbnail")
will find the thumbnail directly, but I suspect the id for your thumbnail will be repeated down the page, so you really need to be searchind for a class.
$("#slide1.thumbnail")
will do that if you change this line
<div id=video-holder><div id="thumbnail"></div></div>
to this
<div id=video-holder><div class="thumbnail"></div></div>
In case there are more "thumbnails" on your page, it would be better to give it a class. Ids should be unique.
In your given case, it would be sufficient to get it by ID
document.getElementById("#thumbnail")
If you gave it a class
document.querySelector("#slide1 .thumbnail")
would get you the element.
In jQuery the equivalent would be:
$("#slide1").find(".thumbnail");
There are many ways you can do this...
Single selector:
$('#slide1 #thumbnail');
If you already have the slide element:
var slide = document.getElementById("slide1");
// and then:
$('#thumbnail', slide);
Doing a .find() on the #slide1 element
$("slide1").find("#thumbnail");
But since you're using an ID it doesn't make sense to do anything else but finding that single ID, since you shouldn't have more than one element on a page with the same ID
$("#thumbnail");
There are probably more ways.. and what the best method is depends a lot on what you're doing and what the context is...
Good luck

jQuery: get a reference to a specific element without using id

I'm tinkering a bit with jquery to show a hidden div when a link is clicked. This should be fairly simple, but there's a flaw to it in this case. I have the following markup:
<div class="first-row">
<div class="week">
<p>Uge 2</p>
<p>(08-01-11)</p>
</div>
<div class="destination">
<p>Les Menuires</p>
<p>(Frankrig)</p>
</div>
<div class="days">4</div>
<div class="transport">Bil</div>
<div class="lift-card">3 dage</div>
<div class="accommodation">
<p><a class="show-info" href="#">Hotel Christelles (halvpension)</a></p>
<p>4-pers. værelse m. bad/toilet</p>
</div>
<div class="order">
<p>2149,-</p>
<p class="old-price">2249,-</p>
</div>
<div class="hotel-info">
<!-- The div I want to display on click -->
</div>
</div>
When I click the "show-info" link I want the "hotel-info" div to display.
My backend devs don't want me to use ids (don't ask me why..) and the above markup is used over and over again to display data. Therefore I need to be able to access the "hotel-info" div in the "first-row" div where the link is clicked.
I've tried to do something like:
$(document).ready(function() {
$('.show-info').click(function() {
var parentElement = $(this).parent().parent();
var lastElementOfParent = parentElement.find(".show-hotel");
lastElementOfParent.show();
});
});
But without a result :-/ Is this possible at all?
Any help is greatly appreciated!
Thanks a lot in advance!
Try this:
$('.show-info').click(function() {
$(this).closest('.accommodation').siblings('.hotel-info').show();
});
Even better imo, as it would be independent from where the link is in a row, if every "row div" has the same class (I assume only the first one has class first-row), you can do:
$(this).closest('.row-class').find('.hotel-info').show();
Reference: .closest, .siblings
Explanation why your code does not work:
$(this).parent().parent();
gives you the div with class .accommodation and this one has no descendant with class .hotel-info.
It is not a good idea to use this kind of traversal for more than one level anyway. If the structure is changed a bit, your code will break. Always try to use methods that won't break on structure changes.
You're right in not using an ID element to find the DIV you want :)
Use closest and nextAll
Live demo here : http://jsfiddle.net/jomanlk/xTWzn/
$('.show-info').click(function(){
$(this).closest('.accommodation').nextAll('.hotel-info').toggle();
});

prototype selector equivalent to jQuery

How can I select the popupwindow of the popup-lightbox div?
in jQuery, it's be something like $('div#popup-lightbox #popupwindow'). Unfortunatly, in Prototype, it's not that easy... anyone can help me? thanks!
<div id="popup-lightbox" class="popup">
<div id="popupoverlay"></div>
<div id="popupdiv">
<div id="popupwindow"></div>
</div>
</div>
<div id="popup-modal" class="popup">
<div id="popupoverlay"></div>
<div id="modaldiv">
<div id="popupwindow">
<div id="modalint">Your changes have not been saved.</div>
</div>
</div>
</div>
Use the bling-bling http://api.prototypejs.org/language/dollardollar/
$$('#popup_lightbox #popup_window') (also, you are not using ids properly, like desau and fantactuka said)
First up, you're using ID attributes incorrectly. According to the W3C specification, ID attributes are supposed to be unique across the document.
That aside, the prototype selection syntax is slightly different from jQuery:
$("popup-lightbox").select("#popupwindow")[0];
Actually since id should be uniq at the page I'm not sure that it makes sense to use complex selector. Why not just $('popupwindow')?

Referring to a div inside a div with the same ID as another inside another

How can I refer to a nested div by id when it has the same id as a div nested in a similarly named div
eg
<div id="obj1">
<div id="Meta">
<meta></meta>
</div>
</div>
<div id="obj2">
<div id="Meta">
<meta></meta>
</div>
</div>
I want to get the innerHTML of meta
document.getElementById('obj1').getElementById('Meta').getElementsByTagName('meta')
doesn't work
IDs should only be used when there is one of that item on the page, be it a SPAN, DIV or whatever. CLASS is what you should use for when you may have a repeating element.
Code there doesn't work because you're referring to an element by unique ID, but have more than one on the page.
Id is supposed to be unique.
Hate to point out the obvious, but in your example, obj1_Meta and obj2_Meta are unique id's, so if it's the case in your working code:
document.getElementById('obj1_Meta').getElementsByTagName('meta')[0].innerHTML;
would work as described. As a double check, did you over think this?
If not, bummer...
As "bad" or "wrong" as your code is, an option that will work is to use a JavaScript framework like jQuery. Once you've included it, you can get elements by passing it a CSS selector (even a semantically incorrect one) like so:
$('#obj1 #obj1_Meta meta').html()
$() is jQuery's way of saying document.getElementById() ...on steroids.
.html() is its equivalent of .innerHTML
Other frameworks, like PrototypeJS and MooTools also provide similar functionality.
Prototype for example:
$$('#obj1 #obj1_Meta meta').innerHTML;//note the double $'s
Frameworks save lots of time and trouble with regard to browser compatibility, "missing" JavaScript methods (like getElementsByClassName) and coding AJAX quickly. These things make them a good idea to use to anyway.
IDs are meant to be unique, use classes intelligently.
<div id="obj1" class="obj">
<div id="obj1_Meta" class="obj_Meta">
<meta></meta>
</div>
</div>
<div id="obj2" class="obj">
<div id="obj2_Meta" class="obj_Meta">
<meta></meta>
</div>
</div>
.obj = targets both elements
#obj1.obj = targets only the first
#obj1.obj_Meta = targets obj1 inner DIV
#obj2.obj = targets only the second
#obj2.obj_Meta = targets obj2 inner DIV
You may also run into problems with this markup because the "meta" tag is only legal inside the head tag, not the body tag. As far as I can tell from looking at Firebug, Firefox will even go so far as to pull those meta tags out of the body and toss them into the head (and, in this case, put any text content inside the parent div), so you won't see them in the DOM at all.
For the HTML you've given, this should work:
document.getElementById('obj1').getElementsByTagName('div')[0].getElementsByTagName('meta');
Just ignore the bogus id on the inner div and get it by tag name. You should also be able to ignore the inner div completely, since getElementsByTagName searches the entire subtree:
document.getElementById('obj1').getElementsByTagName('meta');
As the id attribute is a unique document-wide identifier, you should probably namespace your ids.
<div id="obj1">
<div id="obj1_Meta">
<meta></meta>
</div>
</div>
<div id="obj2">
<div id="obj2_Meta">
<meta></meta>
</div>
</div>
document.getElementById('obj1_Meta').getElementsByTagName('meta')

Categories