So if I have a list of elements and I want to find out which one of them is the last one with this class. How can I do it without JQuery? Maybe I can get its index somehow?
in JQuery it would be something like that:
<div class="div">1</div>
<div class="div">2</div>
<div class="div">3</div>
<div class="div">4</div>
<div class="div">5</div>
<div>6</div>
jQuery(document).on('click', '.div', function() {
if ( $(this).is($(".div:last")) )
{
console.log($(this))
}
});
Link
You could either do that what you did, using the 'querySelector'
var lastElem = document.querySelector('div.class-name:last-child');
Or you could do something like this -
var elements = document.getElementsByClassName('class-name');
var lastElem = elements[elements.length - 1];
This is the standard query function, which accepts CSS selector syntax:
divs = document.querySelectorAll('.div');
last_div = divs.item(divs.length - 1);
See here.
Related
The code that i am writing is for an application where you select an icon and you get the css line displayed so you easily copy paste it and use it for another project. I'm having trouble with the $(this) selector. I have several divs with the "glyph-holder" class and it doesn't matter wich one I press, it always changes the "copy_text" div's value to the same class, the first one. I want it to change it to the div that i pressed.
The html that i have is:
<div id="copy_text">Select icon</div>
<div class="glyph-holder">
<div class="glyph">
<div class="icon-flip-horizontal"></div>
</div>
<div class="beschrijving-bij-glyph">
icon-flip-horizontal
</div>
</div>
The javascript that i currently have is this:
$(document).ready(function(){
var displayText = "Empty";
$(".glyph-holder").click(function(){
if($(this).has("icon-flip-horizontal")){
displayText = "icon-flip-horizontal";
}else if($(this).has("icon-flip-vertical")){
displayText = "icon-flip-vertical";
}
$("#copy_text").text(displayText);
});
});
Your selector in has() is missing the . prefix for the class. You also need to check the length property of the resulting jQuery object. Try this:
var displayText = "Empty";
$(".glyph-holder").click(function() {
if ($(this).has(".icon-flip-horizontal").length) {
displayText = "icon-flip-horizontal";
} else if ($(this).has(".icon-flip-vertical").length) {
displayText = "icon-flip-vertical";
}
$("#copy_text").text(displayText);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="copy_text">Select icon</div>
<div class="glyph-holder">
<div class="glyph">
<div class="icon-flip-horizontal"></div>
</div>
<div class="beschrijving-bij-glyph">
icon-flip-horizontal
</div>
</div>
You are targeting div by id so it will target only one div. You can get the copy_text div by the div using prev function.
$(document).ready(function(){
var displayText = "Empty";
$(".glyph-holder").click(function(){
if($(this).has(".icon-flip-horizontal")){
displayText = "icon-flip-horizontal";
}else if($(this).has(".icon-flip-vertical")){
displayText = "icon-flip-vertical";
}
$(this).prev().text(displayText);
});
});
You're not currently specifying that the has is looking for a class, also .has() returns a jQuery object and therefore .length should be used to test for the number of elements. Try this instead.
$(document).ready(function(){
var displayText = "Empty";
$(".glyph-holder").click(function(){
if($(this).has(".icon-flip-horizontal").length){
displayText = "icon-flip-horizontal";
}else if($(this).has(".icon-flip-vertical").length){
displayText = "icon-flip-vertical";
}
$("#copy_text").text(displayText);
});
});
Note, the . in .has(".icon-flip-horizontal") is important since it's referencing a class.
What I'm asking is how to implement the equivalent functionality of jQuery's children() with HTML5's querySelector/querySelectorAll, i.e. how do I designate the current element in the selector pattern.
For example:
<div id="foo">
<div class="bar" id="div1">
<div class="bar" id="div1.1">
</div>
</div>
<div class="bar" id="div2"></div>
</div>
With document.getElementById('foo').querySelectAll('div.bar') all three divs will be selected. What if I only wanna get div1 and div2, not div1's child div1.1? How do I write [[current node]] > div.bar like css selector?
Could anybody shed some light on this?
In your example you have did id="foo", so above example works.
But in a situation when parent element has no ID, but you still want to use querySelectorAll to get immediate children - it is also possible to use :scope to reference element like this:
var div1 = document.getElementById('div1'); //get child
var pdiv = div1.parentNode; //get parent wrapper
var list = pdiv.querySelectorAll(':scope > div.bar');
Here query will be "rooted" to pdiv element..
Actually there is a pseudo-class :scope to select the current element, however, it is not designated as being supported by any version of MS Internet Explorer.
document.getElementById('foo').querySelectAll(':scope>div.bar')
There's no selector for designating the element from which the .querySelectorAll was called (though I think something may have been proposed).
So you can't do anything like this:
var result = document.getElementById('foo').querySelectorAll('[[context]] > p.bar');
What you'd need would be to select from the document, and include the #foo ID in the selector.
var result = document.querySelectorAll("#foo > p.bar");
But if you must start with an element, one possibility would be to take its ID (assuming it has one) and concatenate it into the selector.
var result = document.querySelectorAll("#" + elem.id + " > p.bar");
If it's possible that the element doesn't have an ID, then you could temporarily give it one.
var origId = elem.id
if (!origId) {
do {
var id = "_" + Math.random().toString(16)
} while (document.getElementById(id));
elem.id = id;
}
var result = document.querySelectorAll("#" + elem.id + " > p.bar");
elem.id = origId;
You can just use like this:
document.querySelectorAll('#foo > p.bar')
I'm creating a directory of apps, each of which has it's own comments which are hidden until the user opens them. I'd like to show the number of comments that each app currently contains but I can only get it display the total number of comments on the page (See JSFiddle: http://jsfiddle.net/9M4nw/2/ for a basic example). Ideally it should display 2 in the top box and 4 in the bottom box. I thought I might need to use an array or something along those lines?
Here is my code:
HTML
<div class="parent">
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
<div class="child"></div>
</div>
jQuery
$(".parent").each(function(index){
var numChilds = $(".child").length;
$(".parent").append(numChilds);
});
You have to select the current HTML element (with class parent). Then, you will use it in selecting the length of elements with class .child and the html for .counter.
Using $(this) you can select the current HTML element from each() function.
Corrected code:
$(".parent").each(function(){
var numChilds = $(".child", $(this)).length;
$(".counter", $(this)).html(numChilds);
});
JSFIDDLE
The problem is you need to limit the scope of the element look up to the desired parent element
$(".parent").each(function(index){
var numChilds = $(".child", this).length;
$(".counter", this).html(numChilds);
});
Another version
$(".parent").each(function(index){
var $this = $(this);
var numChilds = $this.find(".child").length;
$this.find(".counter").html(numChilds);
});
Demo: Fiddle
This would require some extra work to show the number of childs in a more elegan way, but it should be enough to understand the idea
$(".parent").each(function(index){
var $this = $(this);
var numChilds = $this.find(".child").length;
$this.append("<span>" + numChilds + "</span>");
});
This code will help you to get number of children separately for each parent div :-
$(document).ready(function () {
$(".parent").each(function (i) {
$(this).children().length;
});
});
Try this hope this may help you.Vote
How does one select DOM elements in javascript?
Like for example:
<div class="des">
<h1>Test</h1>
<div class="desleft">
<p>Lorem Ipsum.</p>
</div>
<div class="Right">
<button>Test</button>
</div>
</div>
Now how do i select h1? This is just a part of a bigger Page, so cannot use getElementsByTagName(), since others might get selected. Also since there might be other h1's in the document later, i cannot attach the index(body's) to above.
Is there a simple way to select, say <h1> tag which is under the classname of desleft?
I cannot use jQuery or any other libraries.
You can use this to get to your H1:
var des = document.getElementsByClassName('des')
var fc = des[0].getElementsByTagName('h1')
alert(fc[0].innerHTML)
w3.org has selectors now (http://www.w3.org/TR/selectors-api/#examples). Here are 2 different ways that worked for me on Chrome. You may want to use querySelectorAll function that returns a list.
<script type="text/javascript">
//looks for <h1> tag under <div> with className "des"
showOff1 = function() {
var x = document.querySelector(".des h1");
alert(x.innerHTML);
}
//looks for <div> tag with className "desleft" and then use previousSibling to traceback <h1> tag
showOff2 = function() {
var y = document.querySelector("div.desleft");
var z = y.previousSibling.previousSibling;
alert(z.innerHTML);
}
</script>
<body onload="showOff2();">
Use querySelectorAll
You can use querySelectorAll:
// Will return a NodeList even if there is only one element found
var heading = document.querySelectorAll('.des > h1');
heading[1].style.color = 'red'; // NodeList is similar to an array
This will return a NodeList.
or
Use querySelector to return the first element found:
var first_heading = document.querySelector('.des > h1');
first_heading.style.color = 'blue';
Commonly used with an id selector #single-header-id.
Here's a demo
getElementsByTag()
Would be a function that you can start with, and then you can filter for the DOMElements that have the class.
var h1_array = document.getElementsByTag('h1');
var h1_class_array = [];
for (var i=0, len=h1_array.length; i < len; i++) {
if (h1_array[i].className.indexOf('classname') !== -1) {
h1_class_array.push(h1_array[i]);
}
}
The .indexOf function returns -1 if the needle is not found in the haystack.
Now re-reading your question, why not just give your h1's id's ?
DOM traversal is one of javascript's glaring issues (enter jQuery).
a simple getElementById() would save you a headache, and ids on all your h1's would be much cleaner in the end than trying to formulate an algorithm to select them by other means.
If you mean to select a h1 that is before the first element of class desleft, you could always do this:
document.getElementsByClassName("desleft")[0].previousSibling.previousSibling
Example: http://jsfiddle.net/Xeon06/ZMJJk/
previousSibling needs to be called twice because of the empty text node between the two. That's why using libraries to do this stuff is really the best way to go.
var h1 = document.querySelector('.desleft').previousElementSibling;
Find element with className='desleft' using selector '.desleft'
Just move back to previous element (not to previous node!)
So I want to get the first <a> tag in this <div>. This is really driving me nuts. Thanks for any help.
HTML
<div id="PGD" class="album" onmouseover="load(this)">
<a class="dl" href="#">DOWNLOAD</a>
</div>
Javascript
function load(dl)
{
var ID = $(dl).attr('id');
var elemnt = $('ID:first').attr('id');
}
Non-jQuery: (was not tagged with jQuery before, so I included this)
If you want to get the first child element only:
var element = document.getElementById('PGD').children[0];
If you want to get the first anchor element:
var element = document.getElementById('PGD').getElementsByTagName('a')[0];
With jQuery:
var element = $('#PGD').find('a:first');
// or, to avoid jQuery's pseudo selecors:
// var element = $('#PGD').find('a').first();
and actually your function can just be
function load(dl)
{
var element = $(dl).find('a:first');
}
Update:
As you are using jQuery, I suggest to not attach the click handler in your HTML markup. Do it the jQuery way:
$(function() {
$("#PGD").mouseover(function() {
$(this).find('a:first').attr('display','inline');
alert($(this).find('a:first').attr('display'));
});
});
and your HTML:
<div id="PGD" class="album">
<a class="dl" href="#">DOWNLOAD</a>
</div>
​See for yourself: http://jsfiddle.net/GWgjB/
$("#PGD").children("a:first")
This will give you the first child "a" tag, but not the descendents. E.g.
<div id="log">
<p>Foo</p>
Hello
Hello
</div>
Will give you : Hello
$(ID).find(':first')
See find jQuery command.
$('#PGD').find('a:first')
Actualy I've not understanding problem, so I'm trying correct your function, to make it clear for you:
function load(dl)
{
// var ID = $(dl).attr('id');
// var elemnt = $('ID:first').attr('id'); // Here is error-mast be like $(ID+':first')
var ID = $(dl).attr('id');
var elemnt = $(ID).find('*:first').attr('id');
}
I supose dl that is $('#PGD'). But child element A have not attribute id, what are you trying to find?
Also See: http://api.jquery.com/category/selectors/