I have this HTML code (and the number of components that I want to edit it's variable, it could be 3 or 20).
I have created a small example with similar scenario on my website
As you can see my script is able to edit the father div and add the classname. Same for firstchild.
I would like to edit all divs inside firstchild but not the immediately div, it has to be two inside.
Any ideas why my code is not working on the last part?
Thanks.
// WORKS OK
var firstc = document.getElementById('father');
firstc.classList.add("father-class");
firstc.children[0].children[0].children[0].setAttribute("id", "firstchild"); // WORKS OK
var second = document.getElementById('firstchild');
second.classList.add("child-class");
// NOT WORKING
var grandchildren = second.children[0].children[0].children[0];
for (let z = 0; z < grandchildren.length; z++) {
grandchildren[z].classList.add("slide");
}
<div id="father">
<div>
<div>
<div id="firstchild">
<div>
<div>
<div class="random63637236">
<li>1</li>
</div>
<div class="generic">
<li>2</li>
</div>
<div class="italy_gdgd">
<li>3</li>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
the problem in your code is the last children[0]. you are selecting only the first div, it's not an array. Fix that line and everything will work
var grandchildren = second.children[0].children[0].children;
As a side note: if for some reason the first or the second .children[0] are undefined you will get an error.
A better approach is to use querySelectorAll which returns an array;
if your array it is empty, nothing happens.
second.querySelectorAll('#firstchild > div > div > div')
.forEach(el => el.classList.add('slide'))
Related
This is the issue: I want to have nested divs with paragraphs inside with different texts.
I want to be able to get the paragraph that contains certain word, for example "mate" I did the below HTML structure trying to obtain an HTML collection and iterate it, and then using javascript, try to use the includes method to get the paragraph than contains that word, and finally, try to find a way to get the full path from the uppermost div to this p.
<div class="grandpa">
<div class="parent1">
<div class="son1">
<p>I like oranges</p>
</div>
<div class="son2">
<p>yeeeey</p>
<p>wohoo it's saturday</p>
</div>
<div class="son3"></div>
</div>
<div class="parent2"></div>
<div class="parent3">
<div class="son1">
<p>your team mate has been killed!</p>
<p>I should stop playing COD</p>
</div>
<div class="son2"></div>
</div>
</div>
I actually don't know how to achieve it, but at least I wanted to get an HTML collection to iterate, but I'm not being able to get it.... When I use this:
const nodes = document.querySelector('.grandpa');
console.log(typeof nodes);
I don't get an HTML collection, instead if I console.log typeof nodes variable it says it is an object..
How can I iterate this DOM tree, capture the element that contais the word "mate", and obtain (this is what I really want to achieve) the path to it?
Thanks!
You can loop through every element, remove all children elements, then check whether the textContent includes the string you are looking for:
const allElements = document.body.querySelectorAll('*');
const lookFor = "mate";
var elem;
for (let i = 0; i < allElements.length; i++) {
const cur = allElements[i].cloneNode(true); //doesn't mess up the original element when removing children
while (cur.lastElementChild) {
cur.removeChild(cur.lastElementChild);
}
if (cur.textContent.includes(lookFor)) {
elem = cur;
break;
}
}
console.log(elem);
<div class="grandpa">
<div class="parent1">
<div class="son1">
<p>I like oranges</p>
</div>
<div class="son2">
<p>yeeeey</p>
<p>wohoo it's saturday</p>
</div>
<div class="son3"></div>
</div>
<div class="parent2"></div>
<div class="parent3">
<div class="son1">
<p>your team mate has been killed!</p>
<p>I should stop playing COD</p>
</div>
<div class="son2"></div>
</div>
</div>
I'm trying to make a script which will change the content of every occurence like this:
<div id="random numbers">
<div class="column-1"></div>
<div class="column-1">this value I want to change</div>
<div class="column-1"></div>
</div>
there's many of those^
so far, this is the code I'm trying to make use of:
var elements = document.querySelectorAll('column-1');
for ( var i=elements.length; i--; ) {
elements[ i ].InnerHTML = "test";
}
but this isn't working, and I'm really just trying to piece together some code that will replace the content of the #2 column-1 of every <div id="random numbers">
I appreciate any help here, thanks in advance
There are two problems with your above code. First, your .querySelectorAll() should be targeting the class; you need to specify the full stop. Second, the i in .innerHTML needs to be lowercase.
After these two bugs have been fixed, you can only apply the change to every second element by running a condition based on a modulo of 2 using i % 2 as follows:
var elements = document.querySelectorAll('.column-1');
for (var i = 0; i < elements.length; i++) {
if (i % 2) {
elements[i].innerHTML = "OVERRIDDEN";
}
}
<div id="random numbers">
<div class="column-1">Should STAY</div>
<div class="column-1">Should CHANGE</div>
<div class="column-1">Should STAY</div>
</div>
If you're specifically trying to target the <a> tags, you can do that directly with querySelectorAll('.column-1 a') itself, using .outerHTML if you want to replace the <a> tag itself. Note that this doesn't require a conditional:
var elements = document.querySelectorAll('.column-1 a');
for (var i = 0; i < elements.length; i++) {
elements[i].outerHTML = "OVERRIDDEN";
}
<div id="random numbers">
<div class="column-1">Should STAY</div>
<div class="column-1">Should CHANGE</div>
<div class="column-1">Should STAY</div>
</div>
Hope this helps! :)
I have a HTML set up of many images, wrapped in divs, which are wrapped 4 items to a row. Example, 4 items per row, 2 rows:
<div class="staff-wrapper">
<div class="staff-row">
<div class="staff-item">
<img>
</div>
<div class="staff-item">
<img>
</div>
<div class="staff-item">
<img>
</div>
<div class="staff-item">
<img>
</div>
</div>
<div class="staff-row">
<div class="staff-item">
<img>
</div>
<div class="staff-item">
<img>
</div>
<div class="staff-item">
<img>
</div>
<div class="staff-item">
<img>
</div>
</div>
</div>
I want to be able to identify, when clicking on the image, which index this item has within its row.
So if the 3rd item of a row is clicked, the value will be 3. The possible answers should only ever be 1,2,3 or 4 because there can only ever be maximum 4 items per row.
I almost have this, however I'm finding the result is always based on the whole of the list of items, so I'm getting answers like 7 for the last item. Instead this should be 3`, because it's the third item in it's row.
Here is what I have:
var itemPosition = $(".staff-row img").index(this);
Any ideas?
JS Fiddle https://jsfiddle.net/vo6hz1zc/
You should be finding the index of the parent of the this which is img that's clicked.
Also add 1 as indexes start from 0
$('.staff-item img').click(function(){
var itemPosition = $(this).parent().index() + 1;
console.log(itemPosition);
});
JSFiddle
What you want is getting the right row first, and then get the index you could loop trough the rows:
$('.staff-item img').click(function(){
$this=$(this);
var itemPosition = $(".staff-row").each(function(){
itemPosition=$("img",$(this)).index($this);
if(itemPosition>-1){
console.log(itemPosition);
}
});
});
A better option is just select the child from this if thats possible is selecting the parent and search in the parent:
$('.staff-item img').click(function(){
var itemPosition = $(this).parent().index();
console.log(itemPosition)
});
Try this.
$('.staff-item img').click(function(){
var itemPosition = $(this).closest(".staff-row").find(".staff-item img").index(this);
alert(itemPosition);
});
Updated your jsfiddle https://jsfiddle.net/prakashlaxkar/vo6hz1zc/3/ as well. Thanks
Say I have 3 elements like below with different html contents:
<div id='result1'> <p>One</p> </div>
<div id='result2'> <p>Two</p> </div>
<div id='result3'> <p>Three</p> </div>
How can I copy just contents within the div element to the next one so that the final result looks like this?
<div id='result1'> <p>New content</p> </div>
<div id='result2'> <p>One</p> </div>
<div id='result3'> <p>Two</p> </div>
There will be new content for replacement and the last content can be discarded.
To clarify, I'll have something like:
<div id='new'> <p>New content</p> </div>
where I want to grab '<p>New content</p>' as new content to use.
What do you think?
To push the content down, reverse the collection and set the HTML to the HTML of the previous one.
var elems = $($('[id^=result]').get().reverse());
elems.html(function(i) {
return elems.eq(i+1).html();
}).last().html('New Content');
FIDDLE
You can use .html() on the element you want to change the content. For accessing particular element you can use ID Selector (“#id”) with Child Selector (“parent > child”).
Live Demo
$('#result1 > p').html('New content');
Edit to move contents to next elements you can iterate through all elements and start assigning the context of second last to last, third last to second last and so on
Live Demo
elements = $('[id^=result] > p');
len = elements.length;
elements.each(function(idx, el){
if(idx == elements.length-1) return;
$('#result'+ (len-idx) + ' p').html($('#result' + (len-idx-1) + ' p').html());
});
$('#result1 > p').html('New content');
try JS fiddle
I am suggesting to add a Parent Grid and use jquery first() and last(), These controls will function like a queue.
$('#Pdiv').children().last().remove();
$('#Pdiv').first().prepend("<div id='new'> <p>I am New One</p></div>");
alert($('#Pdiv').children().first().html());
I thought to use .index but it don't seem to work!
<div id="main">
<div id="one">
<div class="red"> ... </div>
</div>
<div id="two">
<div class="green"> ... </div>
</div>
<div id="three">
<div class="blue"> ... </div>
</div>
</div>
So I tried:
var isDivThere = $("main").index("#two") != -1;
but as mentioned, no go...
How can I simply look up a div inside div #main?
$("#main > div").index($("#two"))
var isDivThere = $("#main > div").index($("#two")) != -1;
Note: > is for filter only first level div's. So my solution will not work if you want to check the index of nested divs.
To check for existence, you can simply do this:
var isDivThere = !!$('#two').length;
If #two must exist inside #main:
var isDivThere = !!$('#main').find('#two').length;
If #two must be a child of #main:
var isDivThere = !!$('#main').children('#two').length;
To know the index of an element within its container just invoke index over the element id your are looking for:
var isDivThere = $("#two").index();
http://jsfiddle.net/NGhL7/
You need to add the # symbol for selecting by id. Working fiddle here:
$("#yourId");
http://jsfiddle.net/nnFh5/
You can use find() function of jquery,
$("#main").find("#two");
$Because the ID is unique within the all body this is enough to do what you do:
var isDivThere = !!$$("#two").length;
you will never find another element with an ID="two" so you have no need to identify that telling that is insode the main div