How to get the classes of an element's children in JS? - javascript

i'm just creating a grid system for responsive web design and my code (simplified) looks like this:
<div id="row1">
<div class="type_3">
</div>
<div class="type_1">
</div>
<div class="type_2">
</div>
<div class="type_2">
</div>
</div>
Now I want to get the names of the classes and the order of the elements, that are direct children of .row1 as an array or string (or similar) in js.
The order is very important in this case.
Any ideas?
Thanks in advance,
JBG

Iterate over the children of #row1 node:
var children = document.getElementById("row1").children;
for (var i = 0; i < children.length; ++i) {
alert(children[i].className);
}
alert is just for a quick demo, do anything you want inside the loop. Here is a jsfiddle.

Related

How can I get the path to a specific DOM element iterating a HTML collection?

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>

Selecting #2 element inside every div X

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! :)

Hide only on certain elements

I'm using a script that checks for any tag that also has a SRC="self". My function should function like this:
Check if img src="self"
If true, hide the parent div
If false, do nothing
Currently the function actually hides every img regardless of src. If I replace the jQuery hide() action then the function works perfectly. It just seems like it isn't quite performing the hide function like I anticipated.
function changeSourceAll() {
var images = document.getElementsByTagName('img');
for (var i = 0; i < images.length; i++) {
if (images[i].src.indexOf('self') !== -1) {
$(".redditThumbnail").hide();
}
else (){}
}
}
changeSourceAll();
Sample HTML is below. I have multiple .listrow div elements identical to this and the function removes all the .redditThumbnail divs.
<div class="listrow news">
<div class="newscontainer">
<div class="redditThumbnail"></div>
<div class="articleheader news">
<div class="actionmenu">
<p class="mediumtext floatleft alignleft">
author
</p>
<div id="redditUsername"></div>
<div class="floatright">
<div class="redditPermalink material-icons"></div>
</div>
</div>
<p class="redditTitle mediatitle news"></p>
</div>
</div>
</div>
Thanks!
You could use an attribute-equals selector to find all of the <img> elements that point to "self" and then hide their parents :
// Hide the closest thumbnail for elements that match this constraint
$('img[src="self"]').closest('.redditThumbnail');
Example
$(function() {
$('button').click(function(){
$('img[src="self"]').closest('.redditThumbnail').hide();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='redditThumbnail'>
A (has self)
<img src='self' />
</div>
<div class='redditThumbnail'>
B (doesn't have self)
<img src='self-test' />
</div>
<div class='redditThumbnail'>
C (has self)
<img src='self' />
</div>
<hr />
<button>Hide Self-Referencing Images</button>
The issue with hiding every img is because you select and hide all .redditThumbnail elements for every matching item. To fix this you could use this:
$(images[i]).closest('.redditThumbnail').hide();
However a better approach entirely would be to use filter() and find only the .redditThumbnail elements which match the requirements. Try this:
$('.redditThumbnail').filter(function() {
return $(this).find('img[src="self"]').length != 0;
}).hide();
You are hiding all: $(".redditThumbnail").hide();. I guess you should do something like $(images[i]).hide();

jQuery Replicate an existing Div Multiple Times

I am building a search query which gives me results.
I have a template ready for the item inside a hidden div. What I want to do is replicate the template n number of times using jQuery.
So For example:
I search for flights and I get 5 search results, I need to replicate the below div template 5 Times
<div id="oneWayFlightElement" class="displayNone">
<div id="flightIndex1" class="flightDetailElement boxShadowTheme">
<div id="flightDetailsLeftPanel1" class="flightDetailsLeftPanel marginBottom10">
<div class="fullWidth marginTop10">
<span id="flightPriceLabel1" class="headerFontStyle fullWidth boldFont">Rs 9500.00</span><hr/>
<div id="homeToDestination1" class="flightBlockStyle">
<span id="flightNumberFromHome1" class="fontSize16">AI-202</span><br/>
<span id="flightRouteFromHome1" class="fontSize26">PNQ > DEL</span><br/>
<span id="flightDepartTimeFromHome1" class="fontSize26">Depart: 10.00 AM</span><br/>
<span id="flightArrivalTimeFromHome1" class="fontSize26">Arrive: 12.00 PM</span><br/>
</div>
<div id="destinationToHome1" class="flightBlockStyle">
<span id="flightNumberToHome1" class="fontSize16">AI-202</span><br/>
<span id="flightRouteToHome1" class="fontSize26">PNQ > DEL</span><br/>
<span id="flightDepartTimeToHome1" class="fontSize26">Depart: 10.00 AM</span><br/>
<span id="flightArrivalTimeToHome1" class="fontSize26">Arrive: 12.00 PM</span><br/>
</div>
</div>
</div>
<div id="flightDetailsRightPanel1" class="flightDetailsRightPanel textAlignRight marginBottom10">
<img src="images/flightIcon.png" class="marginRight10 marginTop10 width40"/><br/>
<button class="marginRight10 marginBottom10 width40 bookNowButtonStyle">Book Now</button>
</div>
</div>
</div>
Inside this div for 5 times
<div id="searchFlightResultDiv" class="fullWidth" style="border:solid">
</div>
Is there a better way to do that rather than string appending in jQuery?
Thanks,
Ankit Tanna
You'll need to wrap your template div (#flightIndex1) in a container with a unique id attribute. Then, you take the contents of that container (a template for a single record), and append it to your results div (#searchFlightResultDiv) using some type of loop based on the number of results received.
Basically,
HTML:
<!-- Here's your template -->
<div class="displayNone" id="oneWayFlightElement">
<!-- This id (singleResult) is important -->
<div id="singleResult">Result</div>
</div>
<!-- Container for the results -->
<div id="results"></div>
Javascript:
//Get the number of results.
//This can be sent from your API or however you're getting the data.
//For example, in PHP you would set this to $query->num_rows();
var count = 5;
//Start a for loop to clone the template element (div#singleResult) into div#results 'count' times.
//This will repeat until the number of records (count) has been reached.
for (i = 1; i <= count; i++) {
//Append the HTML from div#thingToRepeat into the #results.
$('#results').append($('#singleResult').clone());
}
Here's a JSFiddle to show you how it works. You can play with it and tweak it if necessary.
I can't in good conscious complete this post without telling you the downsides of this. Doing it this way is majorly frowned upon in the web development community and is super inefficient. It may be good for practice and learning, but please do take a look at and consider a javascript templating framework like moustache or handlebars. It does this same thing but way more efficiently.
Hope this was helpful!
function populateResult(resCount) {
resCount = typeof resCount === 'number' ? resCount : 0;
var res = [];
var templateEle = $('#oneWayFlightElement');
for(var i = 0; i < resCount; ++i)
res.push(templateEle.clone().removeAttr('id class')[0]);
$('#searchFlightResultDiv').html(res);
}
populateResult(5);
We use an array res to hold the DOM elements as we loop and finally sets it to the target div using html method. We don't need a JQuery object here as the html method accepts any array like object. In this way we can minimize browser reflows. Here is the JSFiddle

jQuery - How to find an index of an ID within another container DIV?

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

Categories