jQuery: `:eq(i) ` Selection - javascript

I'm trying to assign 10 div class hi with different height.
I know I can do it this way.
$(".hi:eq(0)").css("height",n[0]);
$(".hi:eq(1)").css("height",n[1]);
$(".hi:eq(2)").css("height",n[2]);
..........
$(".hi:eq(9)").css("height",n[9]);
However, when I try generating them by using a for loop it doesn't work.
for (i=0;i<10;i++){
$(".hi:eq(i)").css("height",n[i]);
}
Neither does this.
var i=0;
$(".hi:eq(i)").css("height",n[i]);
Something must be wrong with :eq(i).

This issue is that JavaScript doesn't have string interpolation.
But do it like this instead...
$(".hi").slice(0,10)
.css('height', function(i) {
return n[i];
});
This is far more efficient than repeating your DOM selection with a non-standard selector.
.slice(0,10) will give you the first 10 elements
.css() with a function passed as the second argument will assign the return value to the height css property of the current element in the iteration. The index of the current iteration is represented by the i parameter.

i can't be within the string. You probably want this:
for (i=0; i<10; i++){
$(".hi:eq(" + i + ")").css("left", n[i]);
}

Related

How to add a class to all similar elements with an index less than the clicked element with jquery?

I have 8 elements in sequence that each represent a yoga pose. When one of these elements is clicked I want to add/remove classes for all the pose cards that come before and after the clicked element. So far I have been able to get the index of the clicked element using the following:
$(".pose-card").click(function () {
clickedPoseIndex = $(".pose-card").index(this);
});
And then I tried to use a filter function to get the ones whose index is less than the clicked one with something like this:
let prevPoses = $(".pose-card").filter(function () {
return parseInt($(".pose-card").index(this) < clickedPoseIndex);
});
But that did not work! Please let me know if you can think of any better solutions. Much appreciated!
What you want to do inside filter is get the index as int (hence the parseInt function) and compare with the value you've stored in clickedPoseIndex which is already an int. You've simply missed a bracket or misplaced one. All you have to do is:
let prevPoses = $(".pose-card").filter(function () {
return parseInt($(".pose-card").index(this)) < clickedPoseIndex;
});
Edit
Don't need to use parseInt either as the value returned is already an int so:
return $(".pose-card").index(this) < clickedPoseIndex;

Traversing elements in javaScript

I need to change the href of link in a box. I can only use native javaScript. Somehow I have problems traversing through the elements in order to match the correct <a> tag.
Since all the a tags inside this container are identical except for their href value, I need to use this value to get a match.
So far I have tried with this:
var box = document.getElementsByClassName('ic-Login-confirmation__content');
var terms = box.querySelectorAll('a');
if (typeof(box) != 'undefined' && box != null) {
for (var i = 0; i < terms.length; i++) {
if (terms[i].href.toLowerCase() == 'http://www.myweb.net/2/') {
terms[i].setAttribute('href', 'http://newlink.com');
}
}
}
However, I keep getting "Uncaught TypeError: box.querySelectorAll is not a function". What do I need to do in order to make this work?
Jsfiddle here.
The beauty of querySelectorAll is you dont need to traverse like that - just use
var terms = document.querySelectorAll('.ic-Login-confirmation__content a');
And then iterate those. Updated fiddle: https://jsfiddle.net/4y6k8g4g/2/
In fact, this whole thing can be much simpler
var terms = document.querySelectorAll('.ic-Login-confirmation__content a[href="http://www.myweb.net/2/"]');
if(terms.length){
terms[0].setAttribute('href', 'http://newlink.com');
}
Live example: https://jsfiddle.net/4y6k8g4g/4/
Try This:
var box = document.getElementsByClassName('ic-Login-confirmation__content')[0];
Since you are using getElementsByClassName ,it will return an array of elements.
The getElementsByClassName method returns returns a collection of all elements in the document with the specified class name, as a NodeList object.
You need to specify it as follows for this instance:
document.getElementsByClassName('ic-Login-confirmation__content')[0]
This will ensure that you are accessing the correct node in your HTML. If you console.log the box variable in your example you will see an array returned.
you can select by href attr with querySelector,
try this:
document.querySelector('a[href="http://www.myweb.net/2/"]')
instead of defining the exact href attribute you can simplify it even more :
document.querySelector('a[href?="myweb.net/2/"]'
matches only elments with href attribute that end with "myweb.net/2/"

jQuery for loops not running function

I'm trying to make a loop in jQuery that finds all 'img' elements and places a caption below them, according to the value of the element's 'caption' attribute. Whenever I run the loop below, I am left with no captions under any of the images.
for (var i = 0; i < $('.myimage').length; i++) {
$('.myimage')[i].after('<h6>' + $('.myimage').attr('caption') + '</h6>');
};
However, when I run this code
$('.myimage').after('<h6>TEST</h6>');
the word 'TEST' appears below all of the images. Therefore I know my html is correct, I have no typos, and the selector is working, I just cannot get the for loop to work... What have I done wrong?
$('.myimage')[i] returns a DOM element (not a jQuery object) so there is no after method. If you want to loop, simply use .each
$(".myimage").each(function() {
//this refers to each image
$(this).after('<h6>' + $(this).attr('caption') + '</h6>');
});
You can loop through the .myimage elements like this, using .after()'s callback function
$('.myimage').after(function(){
return '<h6>' + $(this).attr('caption') + '</h6>';
});
One minor note, don't make up your own attributes. use the custom data attribute instead, like data-caption="something".
jsFiddle example

Is a recursive function an effective way to add table rows dynamically?

In my research and attempts to use JavaScript to add rows to a HTML Table dynamically, it was important that each id tag be incremented according to the row number. I found various suggested ways of doing this. Finally, I thought I'd give a try at writing a recursive function to do the trick. The following works. But I do not know if it could be optimized. Kindly let me know what I can do to improve it.
function incrementElementID(element, incrementVal) {
if(element.hasAttribute("id")) {
idVal = element.getAttribute("id");
element.setAttribute("id",idVal+incrementVal);
}
var numChildren = element.childElementCount;
for (var i=0; i<numChildren; i++)
incrementElementID(element.children[i],incrementVal);
return;
}
Best done with a closure variable if you're not intentionally trying to use recursion.
Set a variable outside the function scope and increment it within the function.
You're better off with some simple jQuery:
var incrementVal = ...
$("[id]").each(function(index, value) {
elem = $(value);
elem.attr("id", +elem.attr("id") + incrementVal);
});
$("[id]") selects any element that has an id attribute: http://api.jquery.com/has-attribute-selector/
.each iterates through all the items in the collection: https://api.jquery.com/jQuery.each/
The + at the front of +elem.attr("id") converts the attribute value from a string to an int.

Selecting multiple, but not all HTML classes

So lets say I want to hide a div or span with CSS of a particular class.
Is there anyway to do so for the first X number of instances, or better yet, do it for all except for the last one? I imagine this would require javascript.
pseudocode I am thinking would look like this
if divname.class = "XYZ" {
select all instances -1
execute code that inserts random programmatic id into each class
execute code that hides all ids except the last one
}
Am I on the right track? Or is there any easier/better way?
If you can use jQuery and its nice pseudo-selectors, you could do something like
$('.question-summary:not(:last)')
You can test on the SO homepage.
You could do something like this,
var class_div = document.getElementsByClassName("class_name");
var i =0;
for(i=0;i<class_div.length-1;i++){
//do whatever you want with class_div[n-1] elements.
}
I am not sure how you do this with jquery but this is one possible solution for javascript.
If you were using jQuery...
$('.class_name').hide().last().show();
Here ya go - http://jsfiddle.net/uUK6G/
Set all your divs to the same class. Then use jQuery to filter out the last one.
$('.myDiv').filter(':not(:last)').hide();​
You can use the :last-child selector in CSS to do this.
http://www.w3schools.com/cssref/sel_last-child.asp
Is there anyway to do so for the first X number of instances, or
better yet, do it for all except for the last one? I imagine this
would require javascript.
You can try:
var elms = document.getElementsByClassName('XYZ'), total = elms.length;
for (var i = 0; i < total; i++){
elms[i].style.display = 'none';
}
In above loop, i will contain index of each element, you can put condition or rather range to specify which ones to delete. For example, if you wanted to hide all except for last one, you would modify it like:
for (var i = 0; i < total - 1; i++){
elms[i].style.display = 'none';
}

Categories