removing tag name but keep tag - javascript

Hello I have a <strong></strong> Tag nested in a paragraph <p></p>, I'm trying to remove the <strong> tag but keep the text or the value. Something similar to unwrapping in jquery but in javascript.
I tried this code on a dummy HTML page and it works fine
<html>
<body>
<p>aaa <Strong>bbbbb</Strong></p>
<p>acccaa <Strong>ddddd</Strong></p>
<p>eeee <Strong>ffff</Strong></p>
<script>
var p = document.getElementsByTagName("p");
for(var i=0;i<p.length;i++){
var strongs = p[i].getElementsByTagName("strong");
for(var j=0;j<strongs.length;j++){
p[i].replaceChild(document.createTextNode(strongs[j].innerText),strongs[j]);
}
}
</script>
</body>
</html>
But as soon as I try the same code on a real page example: https://www.bustle.com/privacy
I get this error:
Failed to execute 'replaceChild' on 'Node': The node to be replaced is not a child of this node.
Any idea on how to get this to work on the example or any other example?

getElementsByTagName() returns a live NodeList. So when you replace a tag, the indexes of all the following elements shift down and the code fails when you have more than one <strong> tag in the same paragraph. As a result, it will skip some tags.
The solution is to convert the NodeList to an array so it doesn't change while you're looping.
Another problem in your real page that isn't in the snippet is that the <strong> tags can be nested deeply within the <p>. You should use strongs[j].parentElement to get its direct parent, rather than assuming that the p[i] is the parent.
var p = document.getElementsByTagName("p");
for (var i = 0; i < p.length; i++) {
var strongs = Array.from(p[i].getElementsByTagName("strong"));
for (var j = 0; j < strongs.length; j++) {
strongs[j].parentElement.replaceChild(document.createTextNode(strongs[j].innerText), strongs[j]);
}
}
<html>
<body>
<p>aaa
<Strong>bbbbb</Strong> - <strong>12345</strong></p>
<p>acccaa <span><Strong>ddddd</Strong> x</span></p>
<p>eeee
<Strong>ffff</Strong>
</p>
</body>
</html>
You can also avoid the nested loops by using a query selector.
var strongs = document.querySelectorAll("p strong");
strongs.forEach(strong => strong.parentElement.replaceChild(document.createTextNode(strong.innerText), strong));
<html>
<body>
<p>aaa
<Strong>bbbbb</Strong> - <strong>12345</strong></p>
<p>acccaa <span><Strong>ddddd</Strong> x</span></p>
<p>eeee
<Strong>ffff</Strong>
</p>
</body>
</html>

No need to loop through paragraphs to remove <strong>. Simply removing all 'strongs' in place works fine.
function removeStrongs() {
let strongs = document.querySelectorAll('strong');
strongs.forEach(strong => {
strong.insertAdjacentText('afterend', strong.innerText);
strong.remove();
});
}
<h4>This is a <strong>Title</strong></h4>
<p>
Now is the time for all <strong>good</strong> men to come to the <strong>aid</strong> of the party.
</p>
<p>A <strong>quick brown</strong> fox jumps over the lazy dog.</p>
<button onclick="removeStrongs();">Remove Strongs</button>

Related

Removing first string character with substr in WordPress

I am trying to remove the "|" from the file size span tag. The syntax of my javascript code so far does look fine, but it's not working quite yet.
From my understanding I am using the proper syntax for substr: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr
In Chrome, I am getting this console error:
Uncaught TypeError: Cannot read property 'substr' of undefined
In Firefox, I am getting this console error:
Uncaught TypeError: innerTextString is undefined.
Also the "|" isn't being removed as intended. Any ideas where I am going wrong here?
Thank you in advance.
<script>
const prettyLinkRightFileSize = document.querySelectorAll('.prettyFileList .float_right:nth-child(1)');
const innerTextString = prettyLinkRightFileSize.innerText;
innerTextString.substr(0);
</script>
.prettyFileList .float_right {
float: right;
}
<div class="prettyFileList">
<div>
<a href="#" class="prettylink">
<span class="float_right">| Size 150 KB</span>
<span class="float_right">28th Jan 2021</span>
</a>
</div>
</div>
You do not crop anything, when you use innerTextString.substr(0), as it has the same amount of characters like the original String.
var e = "ThisisaText";
var t = e.substring(0);
Log.v("e", e);
Log.v("t", t);
Output:
"ThisisaText"
"ThisisaText"
additionally you select the Items via classname. So I recommend, you crop all Items with the same class to provide consistency.
Try this code:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="prettyFileList">| Testsize</div>
</body>
<script>
var c = document.getElementsByClassName('prettyFileList');
for (var i = 0; i < c.length; ++i) {
var item = c[i];
item.innerHTML = item.innerHTML.substr(1);
}
</script>
</html>
querySelectorAll() returns a static (not live) NodeList. You need to use prettyLinkRightFileSize[0].innerText.
const prettyLinkRightFileSize = document.querySelectorAll('.prettyFileList .float_right:nth-child(1)');
const innerTextString = prettyLinkRightFileSize.innerText;
To
const prettyLinkRightFileSize = document.querySelector('.prettyFileList .float_right:nth-child(1)');`
let innerTextString = prettyLinkRightFileSize.innerText;
innerTextString = innerTextString.slice(1);
console.log(innerTextString)
This will do the job:
<script>
Array.from(document.querySelectorAll('.prettyFileList .float_right:first-child'))
.map(element => element.innerText = element.innerText.substring(1));
</script>
It also works with multiple elements on your page!
If you do querySelectorAll you will get a nodeList with all elements matching the select statement. You have to iterate over these results to manipulate each of them (also if you only match one element: An array with one element still requires other treatment than the element it self).

Can't append table to div

I created a table using d3.js library,
but when I try to append the table to a div, it gives an error?
code:
<head>
<script src="../../d3.min.js"></script>
</head>
<body>
<div id="main">
Hi
</div>
<script>
const table = d3.create("table");
const tbody = table.append("tbody");
var i,j,row;
for(i=0;i<5;i++){
row =tbody.append("tr");
for(j=0;j<3;j++){
row.append("td").text(`${i},${j}`);
}
}
console.log(typeof(table));
console.log(table);
node =table.node();
console.log(typeof(node));
console.log(node);
d3.select("#main").append(node);
</script>
</body>
</html>
but I get an error:
although my code similar to what is in this tutorial
A tutorial on d3js
Observable tutorials are meant to create Observable notebooks. There are several small differences between Observable and a regular D3 running in a browser.
That being said, the only problem in your approach is that append requires either a string with the tag name or the element. If you have a string, just use it as append("foo"). However, if you have the element to be appended (in your case, table.node()), you have to return it from a function.
So, instead of:
d3.select("#main").append(node);
It has to be:
d3.select("#main").append(() => node);
Here is your code with that change only:
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="main">
Hi
</div>
<script>
const table = d3.create("table");
const tbody = table.append("tbody");
var i, j, row;
for (i = 0; i < 5; i++) {
row = tbody.append("tr");
for (j = 0; j < 3; j++) {
row.append("td").text(`${i},${j}`);
}
}
node = table.node();
d3.select("#main").append(() => node);
</script>
Finally, if you are writing regular scripts for a browser, just ditch this d3.create() followed by append(() => selection.node()). Use a simple tag string instead.

Javascript help on dynamically creating html elements and populating the element onto the DOM

So in the script tag here I have an array myArr that is printed into p tag in the html:
<html>
<body>
<h1>Header 1</h1>
<div>
<p id="test"></p>
</div>
</body>
</html>
<script>
var myArr = ["abc", 123, "test"];
document.getElementById('test').innerHTML = myArr;
</script>
All that works and is good. So, I have a couple of questions about this, as I'm pretty new to javascript.
I know how to iterate through the array and print out each element within the script tag. But how would I be able to display it into the html? Is there a way to dynamically create the p tags with the element from the array as the contents?
And would I be able to easily add stying into the dynamically created p tag?
Can this kind of thing be done using something like jquery? or another popular simple javascript library?Unfortunately, I will be unable to run a full fledged javascript framework. I am only able to run a basic library.
I attempted a try here:
var my_arr = ["test", "abc", 123];
var arr_length = my_arr.length;
for (i = 0; i < arr_length; i++) {
document.createElement("p");
document.getElementById('test').innerHTML = arr_length;
my_arr[i]
}
<h2>My First Web Page</h2>
<p>My first paragraph.</p>
<div id="test">
</div>
You just need to forEach over the array. Inside the callback, create a p, append it to the desired container, and set its textContent to the array element. No frameworks/libraries required:
const test = document.getElementById('test');
const my_arr = ["test", "abc", 123];
my_arr.forEach((item) => {
test.appendChild(document.createElement('p'))
.textContent = item;
});
<h2>My First Web Page</h2>
<p>My first paragraph.</p>
<div id="test">
</div>
Array methods are generally preferrable to for loops, but if you really wanted to use a for loop like in your original code, you would have to set the textContent of the created p to my_arr[i], in addition to appending the p to test:
var my_arr = ["test", "abc", 123];
var arr_length = my_arr.length;
const test = document.getElementById('test');
for (i = 0; i < arr_length; i++) {
const p = document.createElement("p");
p.textContent = my_arr[i];
test.appendChild(p);
}
<h2>My First Web Page</h2>
<p>My first paragraph.</p>
<div id="test">
</div>

Referencing elements by 'class' and not 'id'

I am trying to reference elements (to get pieces of text) in a news website and display them in a simple way.
I watched a YouTube tutorial about referencing elements and it referenced paragraphs using 'getElementById.'
The website I want to use doesn't use 'Id=' very much, it mostly uses 'class=' so I cannot use this same method.
I tried swapping the above 'getElementById' for 'getElementsByClassName' however I am getting the answer 'undefined.'
Code:
<html lang="en">
<body>
<p class="para1" > this is the 1st paragraph </p>
<p> <br/> </p>
<p> <br/> </p>
<p> <br/> </p>
<p class="para2" > this is the 2nd paragraph </p>
</body>
</html>
<script type="text/javascript">
var input=document.createElement("input");
input.type="button";
input.value="Check";
input.onclick = showAlert1;
input.setAttribute("style", "font-size:18px;position:absolute;top:100px;right:40px;");
document.body.appendChild(input);//Placement of check button on website;
function showAlert1()
{
alert(document.getElementsByClassName('para2').innerHTML);
}
</script>
getElementsByClassName returns a collection of elements(like an array). So you need to access those using indexes like this:
document.getElementsByClassName("someClass")[0];
//Or if you want to access all
var len = document.getElementsByClassName("someClass").length;
for(var i=0;i<len;i++){
//access like document.getElementsByClassName("someClass")[i]
}
In your case
document.getElementsByClassName('para2')[0].innerHTML
you have to add the script after html tag.
<div class="increased">hi</div> <!-- first specify the tag-->
<script type="text/javascript"> <!-- then call in script-->
var i = 23;
var elems=document.getElementsByClassName("increased");
for(var k = 0; k < elems.length; k++) {
elems[k].style.size = '100px';
}
</script>

Get all html tags with Javascript

Does anybody knows how can I get all the HTML tags that exist in a page?
I need to get only the tags without their IDs or other attributes, and create a kind of tree-structure of them.
Prefer to do that with Javascript or JQuery.
For example, This HTML code:
<html>
<head>
<title>
Example Page
</title>
</head>
< body>
<h1 style="somestyle">
Blabla
</h1>
<div id="id">
<table id="formid">
<tr>
<td>
</td>
</tr>
</table>
</div>
</body>
</html>
should return return:
html
head
title
body
h1
div
table
tr
td
You can pass a * to getElementsByTagName() so that it will return all elements in a page:
var all = document.getElementsByTagName("*");
for (var i=0, max=all.length; i < max; i++) {
// Do something with the element here
}
Its a very simple piece of Javascript
document.querySelectorAll('*')
Try it out in the console log and it will show you all the tags in the document.
Another example is to getElementsByTagName
These do print out into an array, so you can then loop through the elements and doing different things on different elements.
Example:
var items = document.getElementsByTagName("*");
for (var i = 0; i < items.length; i++) {
//do stuff
}
I did it with getElementsByTagName and .tagName for every value in the return array.

Categories

Resources