Reputation:
I need to write a JS functionality that reads an entire HTML document and replace a text with some other text.
HTML -
<ul>
<li>
<a id="aId" href="https://www.w3schools.com" target="_blank"> Link1 </a>
</li>
<li>
<a id="bId" href="https://www.w3schools.com" target="_blank"> Link2 </a>
</li>
<li>
<a href="https://www.w3schools.com" target="_blank"> Link3 </a>
</li>
</ul>
Javascript code -
var strMessage1 = document.getElementById("aId") ;
var first = 'target="_blank"';
var second = 'target="_blank" rel="noopener noreferrer" onClick="alert(\'Hello World!\')"';
strMessage1.innerHTML = strMessage1.innerHTML.replace(first, second) ;
The javascript should be able to run through entire HTML and replace the first var with the second var (defined in the script), wherever found. This is an example of just the first id - 'aId'.
Question - How would the script cover and replace contents in
as well.
DEMO - http://jsfiddle.net/nikhil_gupta/rzy3ajhx/.
Note - No use of jQuery.
Upvotes: 0
Views: 10593
Reputation: 65806
.innerHTML
alters the content of an element (what's between the opening and closing tags). Your code attempts to alter the value of an element's attribute. These are not the same thing.
Also, it's important to understand the implications of using innerHTML
(and outerHTML
).
To change the value of an element's attribute, just access the HTML attribute you want to modify as a property of the JavaScript object or use the element.setAttribute(attributeName, value)
DOM method.
Question - How would the script cover and replace contents in
- bId id?
- Link3, which has no id?
as well.
When you want to alter more than one element, you need to get them into a collection or array and then you can loop over them. Getting them into a group can be done in many different ways that doesn't have to do with id
s at all (by tag name, by CSS class, by position in the document, by attribute values, etc.). In your example, if we wanted to modify all the links that were inside of bullets that have target=_blank
as their href
value, we could target them by position and attribute value with a CSS selector and the .querySelectorAll()
method. You'll notice in my example below, I've removed the id
attributes completely from the HTML and the code still works.
Lastly, you should not be using inline HTML event attributes (onclick
, etc.) to configure event handling callback functions. That is a 25+ year old technique that gets copied and pasted by every new web developer without an understanding of why it shouldn't be used. Instead, use modern, standards-based code and the .addEventListener()
DOM API.
// Get the elements you wish to work on into an Array
// Here, we're selecting <a> elements that have an href attribute with a value of _blank
// that are direct children of <li> elements:
var elementsToChange = Array.prototype.slice.call(document.querySelectorAll("li > a[target='_blank']"));
// We only need to worry about what's going to change
var newRel = 'noopener noreferrer'
// This will be the click event callback function
function doAlert(){
alert('Hello World!');
}
// Loop over the array
elementsToChange.forEach(function(element){
// Just access the HTML attribute you want to modify as a property of the JavaScript object
element.rel = newRel;
// Or, use the DOM API
element.setAttribute("rel", newRel);
// Either way the DOM API should always be used to set up event handlers
element.addEventListener("click", doAlert);
});
<ul>
<li><a href="https://www.w3schools.com" target="_blank">I will be modified by the code</a></li>
<li><a href="https://www.w3schools.com">I WON'T be modified by the code!</a></li>
<li><a href="https://www.w3schools.com" target="_blank">I will be modified by the code</a></li>
</ul>
Upvotes: 1
Reputation: 23859
You can use outerHTML
to replace the occurrence of the contents of first
with the contents of second
. You may select the second a
using the same document.getElementById
call.
For third one, you can use document.querySelectorAll
and get the last item of the returned collection.
var strMessage1 = document.getElementById("aId");
var strMessage2 = document.getElementById("bId");
var anchors = document.querySelectorAll("a");
var strMessage3 = anchors[anchors.length - 1];
var first = 'target="_blank"';
var second = 'target="_blank" rel="noopener noreferrer" onClick="alert(\'Hello World!\')"';
strMessage1.outerHTML = strMessage1.outerHTML.replace(first, second);
strMessage2.outerHTML = strMessage2.outerHTML.replace(first, second);
strMessage3.outerHTML = strMessage3.outerHTML.replace(first, second);
<ul>
<li>
<a id="aId" href="https://www.w3schools.com" target="_blank"> Link1 </a>
</li>
<li>
<a id="bId" href="https://www.w3schools.com" target="_blank"> Link2 </a>
</li>
<li>
<a href="https://www.w3schools.com" target="_blank"> Link3 </a>
</li>
</ul>
Better coding practices:
setAttribute()
to set individual attributes of an element instead of doing a replace. This will prevent unwanted bugs.document.getElementById
and document.querySelectorAll
, you may use one document.querySelectorAll
and loop on the collection to replace the contents.Upvotes: 0
Reputation: 91
Ans1: I don't know which kind of element is you need. So, I catch all of the
tags. There is a simple way to get elements: document.querySelectorAll("query")
Ans2: as Q1. Element that don't has id is fine.
Ans 3: .innerHTML is for <a>*here*</a>
, you need to edit attribute so you need to call .outerHTML
Refs:
var all_a_tag = document.querySelectorAll("a");
for (var i = 0; i < all_a_tag.length; i++) {
var elem = all_a_tag[i];
var first = 'target="_blank"';
var second = 'target="_blank" rel="noopener noreferrer" onClick="alert(\'Hello World!\')"';
elem.outerHTML = elem.outerHTML.replace(first, second);
}
<ul>
<li>
<a id="aId" href="https://www.w3schools.com" target="_blank"> Link1 </a>
</li>
<li>
<a id="bId" href="https://www.w3schools.com" target="_blank"> Link2 </a>
</li>
<li>
<a href="https://www.w3schools.com" target="_blank"> Link3 </a>
</li>
</ul>
Upvotes: 0
Reputation: 406
As far as I understand, you are trying to change the attributes in the html tag.
You can't use .innerHTML
or .replace
to do that, it just changes the content inside the html tag.
To solve for your question, you can use .getAttribute()
, .setAttribute()
, or .createAttribute()
method.
Something similar with your code, and it works:
var strMessage1 = document.getElementById("aId");
strMessage1.setAttribute("rel", "noopener noreferrer");
strMessage1.setAttribute("onClick", "alert(\'Hello World!\')")
Upvotes: 0
Reputation: 447
I think you mean outerHTML
http://jsfiddle.net/rzy3ajhx/1/
strMessage1.outerHTML = strMessage1.outerHTML.replace(first, second);
Upvotes: 0