I'm learning javascript and have created some HTML within my javascript file so as to test a simple function that takes in nodes as parameters. I keep getting a 'document not defined' error. What do I need to do within my JS file/code to define the document?
I already tried things listed here:
ReferenceError: document is not defined (in plain JavaScript)
var div1 = document.createElement("div");
var text1 = document.createTextNode('<div id="one">Some<span>node <em>contents</em> for</span>comparison</div>');
div1.appendChild(text1);
document.body.appendChild(div1);
var div2 = document.createElement("div");
var text2 = document.createTextNode('<div id="two">Some<span>node contents for</span>comparison</div>');
div2.appendChild(text2);
document.body.appendChild(div2);
var div3 = document.createElement("div");
var text3 = document.createTextNode('<div id="one">Some<span>node <strong>contents</strong> for</span>comparison</div>');
div3.appendChild(text3);
document.body.appendChild(div3);
var div4 = document.createElement("div");
var text4 = document.createTextNode('<div id="four">Some<span>node <em>contents</em> for</span>comparison</div>');
div4.appendChild(text4);
document.body.appendChild(div4);
function nodeEquivalence(node1, node2) {
var equal = false;
if (node1.innerHTML === node2.innerHTML) {
if (node1.tagName === node2.tagName) {
if (node1.type === node2.type) {
equal = true;
}
}
}
return equal;
}
console.log(nodeEquivalence(div1, div4));
Don't use innerHTML. Use createTextNode or textContent.
Create HTML element the right way:
var div = document.createElement("div");
var text = document.createTextNode("some text");
div.appendChild(text);
document.body.appendChild(div);
Your function is too complicated to compare to HTML nodes. This function
function nodeEquivalence(node1, node2) {
var equal = false;
if (node1.innerHTML === node2.innerHTML) {
if (node1.tagName === node2.tagName) {
if (node1.type === node2.type) {
equal = true;
}
}
}
return equal;
}
is much easier.
Related
I have a loop in which I am calling rec_append() recursively, apparently the first pass alone works, then the loop stops.
I have an array of 4 elements going into that $.each loop but I see only the first element going into the function recursively. Help!
I switched it for a element.forEach but that gives me only the second element and I am stuck, is there a better solution to process a tree of elements? My array is a part of a tree.
var data = JSON.parse(JSON.stringify(result))
var graph = $(".entry-point");
function rec_append(requestData, parentDiv) {
var temp_parent_details;
$.each(requestData, function (index, jsonElement) {
if (typeof jsonElement === 'string') {
//Element construction
//Name and other details in the form of a : delimited string
var splitString = jsonElement.split(':');
var details = document.createElement("details");
var summary = document.createElement("summary");
summary.innerText = splitString[0];
details.append(summary);
temp_parent_details = details;
parentDiv.append(details);
var kbd = document.createElement("kbd");
kbd.innerText = splitString[1];
summary.append(' ');
summary.append(kbd);
var div = document.createElement("div");
div.className = "col";
details.append(div);
var dl = document.createElement("dl");
div.append(dl);
var dt = document.createElement("dt");
dt.className = "col-sm-1";
dt.innerText = "Path";
div.append(dt);
var dd = document.createElement("dd");
dd.className = "col-sm-11";
dd.innerText = splitString[2];
div.append(dd);
var dt2 = document.createElement("dt");
dt2.className = "col-sm-1";
dt2.innerText = "Type";
div.append(dt2);
var dd2 = document.createElement("dd");
dd2.className = "col-sm-11";
dd2.innerText = splitString[1];
div.append(dd2);
} else {
$.each(jsonElement, function (jsonElementArrIndx, jsonChildElement) {
rec_append(jsonChildElement, temp_parent_details); //Only 1 pass works, rest skip
});
}
});
}
rec_append(data, graph);
Sample data:enter image description here
here is my code it return 0 when i call result variable i want to add elements in html without DOM, means i want to re-create this whole html in JS using this code.
var div = document.createElement("div");
div.setAttribute("id", "old");
var newDiv = document.createElement("div");
newDiv.setAttribute("id", "new");
var p = document.createElement("p");
p.setAttribute("id", "paragraph")
var domDiv = document.getElementById("old");
var domNewDiv = document.getElementById("new");
var domP = document.getElementById("paragraph");
var result = domDiv + domNewDiv + domP;
result;
Code in console
document.getElementById returns a Javascript Object. You cannot simply concatenate objects. But you can concatenate the html content of those objects for example:
var result = domDiv.innerHTML + domNewDiv.innerHTML + domP.innerHTML;
I have written a simple script and it's job is to change a innerHTML of a random element in one section of the page. Somehow when I call the function, and set it to fire every 1 second, when innerHTML of a specific element is changed, it doesn't stay that way , it just clears itself and moves on to another element. Can anyone help me with this. Here is the code, thanks in advance.
window.onload = function() {
var box1 = document.getElementById("one");
var box2 = document.getElementById("two");
var box3 = document.getElementById("three");
var box4 = document.getElementById("four");
var box5 = document.getElementById("five");
var box6 = document.getElementById("six");
var box7 = document.getElementById("seven");
var box8 = document.getElementById("eight");
var headingArray = ["RAVE", "RUN", "PAINT"];
var iconArray = ["ion-usb", "ion-android-walk", "ion-android-color-palette"];
var paragraphArray = ["Wanna good time? <br> Check out nearest party centres","Check out running tracks", "Ckeck out painting places"];
var boxArray = [box1,box2,box3,box4,box5,box6,box7,box8];
var heading = document.createElement("h2");
var icon = document.createElement("i");
var paragraph = document.createElement("p");
function getRandomNumberForContent() {
var randomHeading = Math.round(Math.random()*2) + 0;
return randomHeading;
}
function getRandomNumberForBox() {
var randomNumber = Math.round(Math.random()*7) + 0;
return randomNumber;
}
function changeBox() {
var random = getRandomNumberForContent();
heading.innerHTML = headingArray[random];
icon.className = "icon "+iconArray[random]+" big";
paragraph.innerHTML = paragraphArray[random];
var randomNum = getRandomNumberForBox();
boxArray[randomNum].innerHTML = "";
boxArray[randomNum].appendChild(heading);
boxArray[randomNum].appendChild(icon);
boxArray[randomNum].appendChild(paragraph);
}
setInterval(changeBox,1000);
}
You are somewhat moving the element to the new div each time the function is called, because you are assigning as a child the same element, not a copy of it.
You should create the new element inside the changeBox function.
That's the answer. If you create it outside the function, they will be a unique element that you are assigning either to one div or another.
I assume that it moves to another element because you append the same elements somewhere else. You could clone the elements when you append them:
boxArray[randomNum].appendChild(heading.cloneNode(true));
boxArray[randomNum].appendChild(icon.cloneNode(true));
boxArray[randomNum].appendChild(paragraph.cloneNode(true));
I'm new to JavaScript and am trying to create a recursive function that checks if two DOM nodes are equivalent. This function seems to be returning true for everything and isn't checking the DOM the way I want it to for some reason. Only nodes 1 & 4 are equivalent.
var htmlStrings = ['<div id="one">Some<span>node <em>contents</em> for</span>comparison</div>', '<div id="two">Some<span>node contents for</span>comparison</div>', '<div id="one">Some<span>node <strong>contents</strong> for</span>comparison</div>', '<div id="four">Some<span>node <em>contents</em> for</span>comparison</div>'];
var div1 = document.createElement('div');
div1.innerHTML = htmlStrings[0];
document.body.appendChild(div1);
var div2 = document.createElement('div');
div2.innerHTML = htmlStrings[1];
document.body.appendChild(div2);
var div3 = document.createElement('div');
div3.innerHTML = htmlStrings[2];
document.body.appendChild(div3);
var div4 = document.createElement('div');
div4.innerHTML = htmlStrings[3];
document.body.appendChild(div4);
function nodeEquivalence(node1, node2) {
var passed = false;
if (node1.nodeType === node2.nodeType) {
if ((node1.tagName === node2.tagName && node1.nodeValue === node2.nodeValue)) {
passed = true;
}
}
node1 = node1.firstChild;
node2 = node2.firstChild;
while (node1 && node2) {
nodeEquivalence(node1, node2);
node1 = node1.nextSibling;
node2 = node2.nextSibling;
}
return passed;
}
console.log(nodeEquivalence(div1, div2));
console.log(nodeEquivalence(div1, div4));
You're passing strings, not DOM elements. You need to convert the HTML to DOM elements. There are many solutions described at
Creating a new DOM element from an HTML string using built-in DOM methods or prototype
So you can do:
var html1 = '<div id="one">Some<span>node <em>contents</em> for</span>comparison</div>';
var html2 = '<div id="four">Some<span>node <em>contents</em> for</span>comparison</div>';
var html3 = '<div id="one">Some<span>node <b>contents</b> for</span>comparison</div>';
var div1 = document.createElement('div');
div1.innerHTML = html1;
var div2 = document.createElement('div');
div2.innerHTML = html2;
var div3 = document.createElement('div');
div3.innerHTML = html3;
alert(nodeEquivalence(div1.firstChild, div2.firstChild));
alert(nodeEquivalence(div1.firstChild, div3.firstChild));
function nodeEquivalence (node1, node2) {
var passed = true;
function test(node1, node2) {
if ((node1.nodeType === node2.nodeType) && (node1.tagName === node2.tagName || node1.nodeValue === node2.nodeValue) && (node1.childNodes.length === node2.childNodes.length)) {
passed = true;
} else {
passed = false;
}
}
node1 = node1.firstChild;
node2 = node2.firstChild;
while (passed && node1 && node2) {
test(node1, node2);
node1 = node1.nextSibling;
node2 = node2.nextSibling;
}
//test(document.body);
return passed;
};
Use document.createElement(*tagName*)
Here is some documentation.
For example, you'll want to create two elements, pass them both in and see if they're equivalent. And then you can base the same one in twice.
var newDiv = document.createElement("div");
var newSpan = document.createElement("span");
yes, instead of comparing 2 html elements, you are simply comparing 2 strings. And your node1, node2 will always be undefined.
by the way, this following has some nice examples as to how to compare 2 html elements.
How to compare two HTML elements
Most of the relevant part is innerHTML. Most of the information is in there. If the innerHTML of the two HTML nodes are the same, than nearly everything is the same. Than the tagName and for <input> tags the type attribute:
function nodeEquivalence(node1, node2) {
var equal = false;
if (node1.innerHTML === node2.innerHTML) {
if (node1.tagName === node2.tagName) {
if (node1.type === node2.type) {
equal = true;
}
}
}
return equal;
}
I think, this function will catch nearly all cases.
Note that there is a little difference, if you access the node via id or class name:
var el = document.getElementById(id);
el.innerHTML
var el2 = document.getElementsByClassName(className);
el[0].innerHTML;
Also, you can compare by outerHTML. When you give each HTML node the same class name, you will have the exact same thing.
Example
Create a HTML element:
var div = document.createElement("div");
var text = document.createTextNode("some text");
div.appendChild(text);
document.body.appendChild(div);
How can I get text value of a tag when tag is stored as string?
var value = "<div>teeext</div>";
tag can be anything, its attributes may contain ">" string as well, regexp can be dangerous - also text value itself can be another tag.
You can make a dummy element:
var value = "<div>teeext</div>";
var div = document.createElement('div');
div.innerHTML = value;
var text = div.innerText || div.textContent;
Using just javascript:
var div = document.createElement('div');
var value = "<div>teeext</div>";
div.innerHTML = value;
var element = div.firstChild
console.log(element.innerHTML); //this the stuff in the tag
Using jquery:
$(value).html();
I guess that you're trying to strip tags.. In that case you can do it like this:
originalString = "<div>teeext</div>";
var value = originalString.replace(/(<([^>]+)>)/ig,"");
Test it out. If there are any exceptions which you need to handle, then just comment here and I'll try to help you further.
Edit for multiple tags:
originalString = "<div>teeext</div>";
outputString = originalString;
while (outputString.indexOf(/(<([^>]+)>)/ig) !== -1){
outputString = outputString.replace(/(<([^>]+)>)/ig,"");
}
value = outputString;
Haven't tested it, but you get the point ;)
Does this help as a starter?
function getText(tagString) {
var firstOpenTag = tagString.indexOf(">"),
lastCloseTag = tagString.lastIndexOf("</"),
substrLength;
if (firstOpenTag == -1 || lastCloseTag == -1) {
return tagString;
}
substrLength = (tagString.length - firstOpenTag) - (tagString.length - lastCloseTag) - 1;
return tagString.substr(firstOpenTag + 1, substrLength);
}
var value = "<div>teeext</div>";
console.log(getText(value));
var moreTags = "<div><ul><li>Text</li></ul></div>",
returnValue = moreTags,
prevReturnValue = "";
while (returnValue !== prevReturnValue) {
prevReturnValue = returnValue;
returnValue = getText(returnValue);
}
console.log(returnValue);