given the following:
<div ID="parent">
<div ID="child1">Children Stuff</div>
<div ID="child2">More Childish things</div>
</div>
<div ID="orphan">Whhhaa I want a mommy</div>
var p = document.getElementById("parent");
var c = document.getElementById("orphan");
p.appendChild(c);
var ch = p.childNodes;
var ln = p.children;
for(var i=0;i < ln.length; i++) {
console.log(ch[i]);
}
console.log(ln.length);
The console output provides:
<div ID="child1">Children Stuff</div>
<div ID="child2">More Childish things</div>
3
Here's where I am lost:
I need to obtain information out of each child node (including the new child). Naturally I won't be simply outputting it to a console, I need to perform some logic on other DOM elements that share similar IDs as the children.
Why doesn't the element.childNodes; call pick up on the new child?
Any help is appreciated.
The above is sample air-code so I apologize if the syntax is not 100%, but I'm hoping the point gets accross nonetheless.
You're looping over ln.length but reading ch:
for(var i=0;i < ln.length; i++) {
console.log(ch[i]);
}
That gets confusing very quickly, as ln has a length of 3 and contains the child elements. ch has a length of 6 and contains all elements (including 3 text elements with just line feeds).
This is really easy to see if you just add 2 more console logs:
console.log('ch',ch);
console.log('ln',ln);
As here: https://jsfiddle.net/mqhevnsu/
Because you mix childNodes and children. Try using only children:
var p = document.getElementById("parent");
var c = document.getElementById("orphan");
p.appendChild(c);
var ln = p.children;
for(var i=0;i < ln.length; i++) {
console.log(ln[i]);
}
console.log(ln.length);
<div ID="parent">
<div ID="child1">Children Stuff</div>
<div ID="child2">More Childish things</div>
</div>
<div ID="orphan">Whhhaa I want a mommy</div>
It just works if you fix the typos and become consistent in using p.children or p.childNodes:
var p = document.getElementById("parent");
var c = document.getElementById("orphan");
p.appendChild(c);
var ch = p.children;
for(var i=0;i < ch.length; i++) {
console.log(ch[i]);
}
console.log(ch.length);
jsfiddle
Related
I have several div tags trainingData0, trainingData1, trainingData2, etc that I am trying to use innerHTML to update text.
I am trying to refer to them with a for loop but it doesn't work. (even though trainingDataDiv does hold the correct value ie trainingData0 which DOES work if I type trainingData0.innerHTML )
Any advice? Thanks in advance.
<div id="trainingData0"></div>
---------------
for (var i=0; i<15; i++)
{
var trainingDataDiv = "trainingData" + i;
trainingDataDiv.innerHTML = data;
}
Answer by Robby Cornelissen in comments of my question :)
for (var i=0; i<15; i++)
{
var trainingDataDiv = document.getElementById("trainingData" + i);
trainingDataDiv.innerHTML = data;
}
So you don't have to change your max number when you change the number of elements:
//Get all elelemtns with ids that start with trainingData
var trainingDataDivs = document.querySelectorAll("[id^='trainingData']");
var data = "I'm training Data";
//iterate the elements we found earlier and update the data
for(var i = 0; i < trainingDataDivs.length; i++)
{
trainingDataDivs[i].innerHTML = data;
}
<div id="trainingData0"></div>
<div id="trainingData1"></div>
<div id="trainingData2"></div>
<div id="trainingData3"></div>
<div id="trainingData4"></div>
<div id="trainingData8"></div><!-- Note the gap in numbers -->
<div id="bob">I'm not training</div>
For more info see Attribute selectors and querySelectorAll
Assume an article generated my markdown which has 1-N paragraphs in it. My brain is a bit fried tonight, all I could come up with was
var chunks = s.split('</p>');
if ( chunks.length > 3)
{
s = chunks[1]+'</p>'+chunks[2]+'</p>'+chunks[3]+'</p>';
}
Is there a more sane way to collect the first three paragraphs into a string? The markdown processor guarantees the paragraphs should be legal HTML. But I'm sure there must be a more clever regex solution. Also this won't guarantee three paragraphs if there is something else like a but that's OK.
Something like this?
var s= '<p>Paragraph 1</p><p>Paragraph <em>2</em></p><p>Paragraph 3</p><p>Paragraph 4</p><p>Paragraph 5</p>';
s= (s.split('</p>')
.splice(0,3)
.join('</p>') +
'</p>'
).replace(/\<\/p> *\<\/p>/g,'</p>');
console.log(s);
Id use something used to handling the DOM.... say jQuery
var arrP = $("body p").slice(0,3);
var strP = "";
for(var i = 0; i < arrP.length; i++)
{
strP += arrP[i].outerHTML;
}
console.log(strP);
//Or Taking the article in as a string
var strArticle = "<p>Parra <em>1</em></p><p>Parra <strong>2</strong></p><p>Parra 3</p><p>Parra 4</p>";
var divArticle = document.createElement('div');
divArticle.innerHTML = strArticle;
arrP = $(divArticle).find("p").slice(0,3);
strP = "";
for(var i = 0; i < arrP.length; i++)
{
strP += arrP[i].outerHTML;
}
console.log(strP);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>Parra <em>1</em></p>
<p>Parra <strong>2</strong></p>
<p>Parra 3</p>
<p>Parra 4</p>
<div id="target"></div>
I wouldn't just use jQuery for this, but if you're already using it or looking for an excuse to use it, this is an option. Otherwise go for Ricks answer. Regex is only appropriate for parsing HTML given very tight control over the input. Some would say it should never be used.
Or vanilla Javascript
var arrP = document.body.getElementsByTagName("p");
var strP = ""
for(var i = 0; i < 3; i++)
{
strP += arrP[i].outerHTML;
}
console.log(strP);
//Or Taking Article body as a string
var strArticle = "<p>Parra <em>1</em></p><p>Parra <strong>2</strong></p><p>Parra 3</p><p>Parra 4</p>";
var divArticle = document.createElement('div');
arrP = document.body.getElementsByTagName("p");
strP = ""
for(var i = 0; i < 3; i++)
{
strP += arrP[i].outerHTML;
}
console.log(strP);
<p>Parra <em>1</em></p>
<p>Parra <strong>2</strong></p>
<p>Parra 3</p>
<p>Parra 4</p>
<div id="target"></div>
There is a one line regular expression, of course, but it is pretty hard to read.
var s= '<p>Paragraph 1</p><p>Paragraph <em>2</em></p><p>Paragraph 3</p><p>Paragraph 4</p><p>Paragraph 5</p>';
regex = /(?:\<p\>.*?\<\/p\>){3}/;
s = regex.exec(s);
console.log(s);
The regular expression matches some non-capturing group exactly three times. Digging into the non-capturing group, we see several characters have to be escaped and that we need to use a lazy quantifier. I'd take your way over the clever regex any day.
You could get the paragraphs and just concat them together until you reach three.
var pars = '';
//Get the p tags, go through some of them. Use your favorite library to do this.
Array.prototype.some.call(document.querySelectorAll('p'), function(current, index) {
console.log("This should only go to 2", index);
pars = pars + ['<p>', current.innerHTML, '</p>'].join('');
return index >= 2; //Counting by zero
});
console.log(pars);
<p>This is one.</p>
<p>This is two.</p>
<p>This is five, er, three.</p>
<p>FOUR</p>
<p>FOUR PLUS ONE</p>
<p>FOUR PLUS TWO</p>
I want to convert this code into an array.
<div id="Parent">
<div class="childOne" ><span id="1dfgdffsf">ChildOne </span></div>
<div class="childOne" ><span id = "2sdfsf">ChildTwo</span> </div>
<div class="childOne" ><span id="3sdfsf">ChildThree </span></div>
<div class="childOne" ><span id="4dssfsf">ChildFour </span></div>
</div>
span id is dynamic. therefore i can't use it.please tell me how to convert it into an array.
You will have to loop over each element and push it into an array
//declare an array
var my_array = new Array();
//get all instances of the SPAN tag and iterate through each one
$('div#parent div.childOne span').each(function(){
//build an associative array that assigns the span's id as the array id
//assign the inner value of the span to the array piece
//the single quotes and plus symbols are important in my_array[''++'']
my_array[''+$(this).attr('id')+''] = $(this).text();
//this code assigns the values to a non-associative array
//use either this code or the code above depending on your needs
my_array.push($(this).text());
});
If you do not use a library, the following should work fine:
var result = [], matches = document.querySelectorAll("#Parent span");
for (var i = 0, l = matches.length; i < l; i++)
result.push(matches[i].getAttribute("id"));
Else if the document.querySelectorAll function is not supported:
var result = [], parent = document.getElementByID("Parent");
for (var i = 0, l = parent.childNodes.length; i < l; i++)
result.push(parent.childNodes[i].childNodes[0].getAttribute("id"));
If you wanted to get key/value pairs instead you can do the following:
var result = [], matches = document.querySelectorAll("#Parent span");
for (var i = 0, l = matches.length; i < l; i++)
result[matches[i].getAttribute("id")] = matches[i].text;
With jQuery it is as simple as a single line of code:
var result = $("#Parent span").map(function() { return $(this).attr("id"); }).get();
First of all, try to avoid naming id's and classes from capital letters.
Then try this:
var arr = [];
$('#parent').children().each(function(){
arr.push($(this).find('span').text());
}
maybe this is the best way currently
const array = Array.from(document.querySelectorAll('.childOne'));
Below Code May be help you :
<!DOCTYPE html>
<html>
<head>
<style>
div { color:red; }
</style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>
<div>First</div>
<div>Second</div>
<div>Third</div>
<div>Fourth</div>
<script>
var elems = document.getElementsByTagName("div"); // returns a nodeList
var arr = jQuery.makeArray(elems);
arr.reverse(); // use an Array method on list of dom elements
$(arr).appendTo(document.body);
</script>
</body>
</html>
This would be simple one, as :
jQuery(function($) {
var anArray = [];
$("#Parent").find("span").each(function(){
anArray.push($(this).html());
});
alert(anArray);
});
I need to use pure Javascript for the first time in a long while, and having gotten used to the comfy mattress of jQuery, all the important stuff is escaping me.
I need to select a bunch of divs on regular expression. So I have stuff like this;
<div id="id_123456_7890123"> .. </div>
<div id="id_123456_1120092"> .. </div>
<div id="id_555222_1200192"> .. </div>
<div id="id_123456_9882311"> .. </div>
And I'd need to create a loop that goes through all the divs with an id that begins with id_123456_. How would I go about doing that?
I used jQuery with the :regex filter plugin before, but looking at it, it doesn't seem like there's much I could salvage in a pure javascript rewrite.
In plain javascript, you could do this generic search which should work in every browser:
var divs = document.getElementsByTagName("div"), item;
for (var i = 0, len = divs.length; i < len; i++) {
item = divs[i];
if (item.id && item.id.indexOf("id_123456_") == 0) {
// item.id starts with id_123456_
}
}
Working example: http://jsfiddle.net/jfriend00/pYSCq/
HTML DOM querySelectorAll() method will work here.
document.querySelectorAll('[id^="id_"]');
Borrowed from StackOverFlow here
This works by recursively traversing the whole DOM.
It's possibly not the most efficient, but should work on every browser.
function find_by_id(el, re, s) {
s = s || [];
if (el.tagName === 'DIV' && re.exec(el.id) !== null) {
s.push(el);
}
var c = el.firstChild;
while (c) {
find_by_id(c, re, s);
c = c.nextSibling;
}
return s;
}
var d = find_by_id(document.body, /^id_123456_/);
See http://jsfiddle.net/alnitak/fgSph/
Here you are: http://jsfiddle.net/howderek/L4z9Z/
HTML:
<div id="nums">
<div id="id_123456_7890123">Hey</div>
<div id="id_123456_1120092">Hello</div>
<div id="id_555222_1200192">Sup</div>
<div id="id_123456_9882311">Boom</div>
</div>
<br/>
<br/>
<div id="result"></div>
Javascript:
divs = document.getElementsByTagName("div");
divsWith123456 = new Array();
for (var i = 0;i < divs.length;i++) {
if (divs[i].id.match("id_123456") != null) {
divsWith123456.push(divs[i]);
document.getElementById("result").innerHTML += "Found: divs[" + i + "] id contains id_123456, its content is \"" + divs[i].innerHTML + "\"<br/><br/>";
}
}
I want to do multi AddEventListener to specific function, but the result is not what I want.
I get always the last child on the list.
Why?
This is the code:
First section:
<script>
var inside_elm= new Array();
inside_elm[1]="inside_e1";
inside_elm[2]="inside_e2";
inside_elm[3]="inside_e3";
var kk = {
showBox :function(elm){
alert(elm);
document.getElementById(elm).style.display='block';
}
}
function load() {
var e_elm= new Array();
e_elm[1]="e1";
e_elm[2]="e2";
e_elm[3]="e3";
for(var i=1;i<3;i++){
var k=e_elm[i];
alert(inside_elm[i]);
document.getElementById(e_elm[i]).addEventListener('click',function(){kk.showBox(inside_elm[i])},false);
}
}
</script>
The body:
<body onload="load();">
<div id="e1">
e1
<div id="inside_e1" style="display:none;">inside_e1</div>
</div>
<div id="e2">
e2
<div id="inside_e2" style="display:none;">inside_e2</div>
</div>
<div id="e3">
e3
<div id="inside_e3" style="display:none;">inside_e3</div>
</div>
It's basically down to the fact that it doesn't evaluate 'i' until the function executes, by which stage it's set to 3.
What you want to do is use something like the following:
for(var i=1;i<4;i++){
var k=e_elm[i];
alert(inside_elm[i]);
var elm = document.getElementById(e_elm[i]);
elm.inside_elm = inside_elm[i];
elm.addEventListener('click', function(){kk.showBox(this.inside_elm)},false);
}
I think it is down to the following, or at least it won't help matters.
for(i = 1;i < 3;i++){
....
}
Will only access the first two atoms of your array and will exit the loop before iterating the third time. Try
for(i = 1;i < 4;i++){
....
}
Similarly it is good practice to start array indices at 0 in which case
for(i = 0;i<3;i++){
....
}
would iterate through each (assuming the start index is 0)