How to built a text array of the document content with javascript - javascript

Hi how can I extract the text of an document as an array within javascript.
It´s easy to get the innerHTML, but I do not get the text before and after the div for example.
This should be the output:
[0]=before div
[1]=innerHTML
[2]=aferHTML
[3]=before div2
[4]=innerHTML2
[5]=aferHTML2
Of the following document:
<html><head>
<body>
before div <div>innerHTML </div>aferHTML
before div2 <div>innerHTML2 </div>aferHTML2
</body></html>
I found this link, but it does not get the text before and after the elements as well:
How to get all text from all tags in one array?

You scenario is not clear. Could you please elaborate more the specific reason.
However if you want to get text from all elements in a document, kindly review this thread -> link.

By using the childNodes property you can achieve this. But for afterHtml and before div2, you need to do some extra work because they are part of the same text node.
Please take a look at the snippet below. You can remove the last element of the array manually.
const arr = [];
document.body.childNodes.forEach(node => {
arr.push(node.textContent.trim());
})
console.log(arr)
<body>
before div <div>innerHTML </div>aferHTML
before div2 <div>innerHTML2 </div>aferHTML2
</body>

Okay here's mine.
As you can see, I wrapped your HTML inside a div with a class name content.
<!DOCTYPE html>
<html>
<head>
<title></title>
</head>
<body>
<div class="content">
before div <div>innerHTML </div>aferHTML
before div2 <div>innerHTML2 </div>aferHTML2
</div>
</body>
</html>
<script type="text/javascript">
var body = document.querySelector('.content').children;
var list = [];
for (var i = 0; i < body.length ; i++) {
var before = body[i].previousSibling.nodeValue.trim();
var inner = body[i].innerHTML;
var after = body[i].nextSibling.nodeValue.trim();
if (before && i == 0) list.push(before); //prevent duplication and empty value
list.push(inner);
if(after) list.push(after); //prevent empty value
}
console.log(list); //output
</script>
in innerHTML, you could split the string using inner.split(" ") if you like.

Related

How to move All elements in the body with adding exception for some elements to not be moved?

I think the title is clear, but I've some examples for you guys, here is my idea:
I've this Html5:
<html>
<head></head>
<body class="oldParent">
<div class="p1"></div>
<div class="p2"></div>
<div class="p3"></div>
<div class="p4"></div>
<div class="p5"></div>
<div class="NewParent"></div>
</body>
</html>
as you can see my NewParent is child of My OldParent
(i want to move all body elements except NewParent), and i need to move all elements except this one:
<div class="**NewParent**"></div>
I'm New to Javascript and I thought that you guys know how to add exception
for this, I've found this too:
var newParent = document.getElementById('NewParent');
var oldParent = document.getElementById('OldParent');
while (oldParent.childNodes.length > 0) {
newParent.appendChild(oldParent.childNodes[0]);
}
but i don't know how to add exception!?
I need help:(
You're pretty close with your original code. Just switch to getElementsByClassName - but be aware it returns a collection so you'll have to index into it. You might want to switch to id's if that's an option.
Then you can basically just add an if condition to test for the className of the element to exclude:
var newParent = document.getElementsByClassName('NewParent')[0];
var oldParent = document.getElementsByClassName('oldParent')[0];
while (oldParent.childNodes.length > 0) {
if (oldParent.childNodes[0].className !== 'NewParent') {
newParent.appendChild(oldParent.childNodes[0]);
}
else { break; }
}
Here's a jsfiddle you can play with. Be careful with your class names, the ones for old and new parents have different casing.
I would add while this is closest to your original code, it may not actually be the best way to solve this. This assumes your new parent is the last in the collection as it has to break out of your while loop due to the way you're looping. Cloning as the other answer shows is probably a safer solution.
You can try below method.
Get your current element which you want to retain.
Create a Clone of that element.
Empty the entire parent element.
Append the element which you have cloned earlier.
var newParent = document.getElementsByClassName('NewParent')[0];
var cln = newParent.cloneNode(true);
document.getElementsByClassName('oldParent')[0].innerHTML = '';
document.getElementsByClassName('oldParent')[0].appendChild(cln);
<html>
<head></head>
<body class="oldParent">
<div class="p1">1</div>
<div class="p2">2</div>
<div class="p3">3</div>
<div class="p4"5></div>
<div class="p5">5</div>
<div class="NewParent">77</div>
</body>
</html>

Why is the childNodes count is greater than expected?

I have a question about DOM. Consider the following javascript code, the output will be 5.
<body>
<p>Hello</p>
<script>
function countBody() {
var childs = document.getElementsByTagName("body")[0].childNodes;
alert(childs.length);
}
window.onload = countBody;
</script>
</body>
Since I have two element nodes and two text nodes, what is the 5th node?
You have three text nodes.
Between the body start tag and the paragraph.
Between the paragraph and the script.
Between the script and the body end tag
… you could loop over childNodes and console.log() each value to see.
Just check it for yourself:
<body>
<p>Hello</p>
<script>
function countBody() {
var childs = document.getElementsByTagName("body")[0].childNodes;
console.log([].map.call(childs, function (node) { return node.textContent; }));
}
window.onload = countBody;
</script>
</body>
You have missed one text node in your counting. Please be aware that output from snippet will be different from code you have provided.

Get Value from another div, subtract, and populate another div with jQuery

I'm trying to get the value of one specific div class, subtract that by 500 and then populate the result into another div.
I'm not quite sure what process I would need in order to populate the result of the subtraction into the other div.
Something like this:
<div class="main-value">5000</div>
<!-- main-value - 500-->
<div class="new-value"></div>
//Script
var main = $(".main-value");
main.html(parseInt(main.html()) - 500 ).appendTo($(".new-value"));
So far, the subtraction work, but I can't get it to append the updated value to the empty div and keep the original one intact.
For that, you need to clone the element otherwise it may update and append the original element. Although parsing the string is optional since the operation is subtraction.
var main = $(".main-value");
main.clone().text(main.text() - 500).appendTo($(".new-value"));
//----^^^^----- clone the element
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-value">5000</div>
<!-- main-value - 500-->
<div class="new-value"></div>
In case you just want to show the result in new-value class then do it like.
var main = $(".main-value");
// update the text content in `new-value` div
$(".new-value").text(main.html() - 500);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="main-value">5000</div>
<!-- main-value - 500-->
<div class="new-value"></div>
Try this:
var mainval = $(".main-value").text();
$(".new-value").text(parseInt(mainval) - 500);
Reference: http://api.jquery.com/text/
Break it into two:
var main = $(".main-value");
mainValue = parseInt(main.html());
$(".new-value").html(mainValue);
<!doctype html>
<html>
<body>
<div class="main-value">5000</div>
<div class="new-value"> </div>
<script>
var x= document.getElementsByClassName("main-value")[0].innerHTML;
var y= document.getElementsByClassName("new-value")[0];
y.innerHTML= x-500;
</script>
</body>
</html>

JS get value of generated textnode

I have this Javascript in a for loop:
renderAElements[i] = document.createElement ("a");
renderAElements[i].setAttribute("href", "#");
renderAElements[i].setAttribute("class", "expander");
renderAElements[i].appendChild(expand);
alert (renderAElements[i].nodeValue);
where expand is created as:
var expand = document.createTextNode("+");
The alert, which is meant to return the link text of each created element returns null. Why is this?
Because you are trying to get the nodeValue of the Element node and not the Text node.
alert (renderAElements[i].firstChild.nodeValue);
It's because the a element contains another element and not a value. If you want to get the text out of the node you'll need to do either
renderAElements.childNodes[0].nodeValue
or
renderAElements.innerText
Check this out
<head>
<script type="text/javascript">
function GetTextNode () {
var textContainer = document.getElementById ("textContainer");
var textNode = textContainer.firstChild;
alert (textNode.data);
}
</script>
</head>
<body>
<div id="textContainer">This is a simple text in the container.</div>
<button onclick="GetTextNode ()">Get the contents of the container</button>
</body>
try this alert (renderAElements[i].firstChild.nodeValue);

how to get tinyMCE editable for a cloned textarea by cloneNode(true) function

When I try to clone a textarea by using cloneNote(true), the cloned textarea is not editable. Does anyone know how to resolve the problem? The sample codes show as following:
<html>
<head>
<script type="text/javascript" src="/javascripts/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript">
tinyMCE.init({
theme : "advanced",
mode : "textareas",
});
</script>
<script type="text/javascript">
testclonenode = {
addAbove : function (element) {
var rowEl = element.parentNode.parentNode.parentNode;
var rowElClone = rowEl.cloneNode(true);
rowEl.parentNode.insertBefore(rowElClone, rowEl);
return false;
}
};
</script>
</head>
<body>
<table>
<tr><td>
<textarea name="content" style="width:100%">this is a test </textarea>
<p> <button onclick='return testclonenode.addAbove.call(testclonenode, this);'> Add above </button>
</td></tr>
</table>
</body></html>
It does not work that way. Also, it is impossible to move a tinymce editor using dom manipulation.
The tinymce wiki states the following:
mceAddControl
Converts the specified textarea or div
into an editor instance having the
specified ID.
Example:
tinyMCE.execCommand('mceAddControl',false,'mydiv');
So when you clone a textarea there is another problem: You will have the same id twice which will result in errors accessing the right tinymce instance.
I got this to work by using an ID which is incremented each time my clone function is triggered, so
var insertslideID = 0;
function slideclone() {
$('<div class="slides"><textarea name="newslide['+insertslideID+'][slide_desc]" id="mydiv'+insertslideID+'"></textarea></div>').insertAfter('div.slides:last');
tinyMCE.execCommand('mceAddControl',false,'mydiv'+insertslideID);
insertslideID++;
}
$('input[name=addaslidebtn]').click(slideclone);
Seems to work.
A wee bit tidier, I just use a number for my id - copy1 is the name of my button - I add the new element to the end of my container.
var count = 0;
$("#copy1").click(function(){
var newId = count;
$( "#first" ).clone().appendTo( "#container" ).prop({ id: newId, });
tinyMCE.execCommand('mceAddControl',false,newId);
count++;
});
I ran into a similar problem, except my element IDs (not just textareas) could be anything, and the same ID was always appearing twice. What I did is supposed to be horribly inefficient but there was no noticeable performance loss with dozens of elements on the page.
Basically I removed the TinyMCE ID first (uses jQuery):
$(new_element).find('.mce-content-body').each(function () {
$(this).removeAttr('id');
});
Then I reinitialized TinyMCE for all relevant elements.

Categories