Finding the DOM element with specific text in javascript - javascript

I know how to find specific text, but I'm really struggling to find elements with specific text
for example: <span class="foo">Special</span>
Is there example like this script below to find elemements with text?
var txt = window.document.body.innerHTML;
if (txt.match(/Special/)) {
// do something if true
alert("Found");
} else {
// do something if false
alert("Sorry");
};

You could e.g. catch every element inside your document and check if any of them contains given text.
var elems = document.querySelectorAll("*"),
res = Array.from(elems).find(v => v.textContent == 'Special');
console.log(res ? 'found!' : 'not found');
<span class="foo">Special</span>
<span class="foo">Else</span>

With pure Javascript just grab element's parent like this:
var x = this.parentElement.nodeName; //x=="span"
or
var x = this.parentElement; //x == <span> object
With jQuery just grab element's parent like this:
$(this).parents("span");
So if you add above line inside your if you can get span element as object or as text.

Related

How can I convert specific text to link within a div node?

NOTE: The first requirement for this is that it not use jQuery.
I also do not want to use .innerHTML if I can avoid it (even if that requires a bit more code)
I have divs within a page (multiple locations) that will be something like this:
<div class="p-user-content">John Smith current working on ticket LQ-1954</div>
... again, multiple locations ...
<div class="p-user-content">Sally Jones assigned GM-3398 yesterday</div>
There will be simple text, and tags like <a> mixed in with the text as shown.
The following script successfully identifies all the "text nodes":
var el = document.getElementsByClassName('p-user-content');
for (var i in el) {
if (typeof el[i].childNodes === 'undefined') continue
for (var k in el[i].childNodes) {
if (typeof el[i].childNodes[k] === 'function') continue
if (el[i].childNodes[k].nodeType !== Node.TEXT_NODE) continue
/**
This successfully gets the nodeValue
*/
console.log(el[i].childNodes[k].nodeValue)
}
}
What I want to do is split the text node word-by-word, and then convert values like LQ-1954 and GM-3398 to anchor elements, and then replace the modified text and anchor links back into the existing div. I'm able to split the text up and do the matching part, but how would I
build the nodes back with the new links and
replace it back into the same div?
You can use .replace
document.body.outerHTML = document.body.outerHTML.replace(/(LQ-1954)/g , '<a> $1 </a>')
If you must avoid manipulating html by changing the value of innerHTML,
create a new element and replace the old element with it:
function addLinks(){
var el = document.getElementsByClassName('p-user-content');
for (var i in el) {
if (typeof el[i].childNodes === 'undefined') continue
let value = el[i].innerHTML.replace(/[A-Z]{2}-[\d]{4}/g, (match)=>'' + match + '');
let newDiv = document.createElement('div')
newDiv.insertAdjacentHTML("beforeend", value);
el[i].replaceChildren(newDiv)
}
}
<div class="p-user-content">John Smith current working on ticket LQ-1954</div>
... again, multiple locations ...
<div class="p-user-content">Sally Jones assigned GM-3398 yesterday</div>
<button onclick="addLinks()">Add Links</button>
Simple way using innerHTML:
function addLinks(){
var el = document.getElementsByClassName('p-user-content');
for (var i in el) {
if (typeof el[i].childNodes === 'undefined') continue
el[i].innerHTML = el[i].innerHTML.replace(/[A-Z]{2}-[\d]{4}/g, (match)=>'' + match + '');
}
}
<div class="p-user-content">John Smith current working on ticket LQ-1954</div>
... again, multiple locations ...
<div class="p-user-content">Sally Jones assigned GM-3398 yesterday</div>
<button onclick="addLinks()">Add Links</button>

Removing elements from the DOM that were added through JS

I have tried to lookup for an answer to this but I have not been able to find an answer.
In my project, I add HTML by using JS.
let winnerHTML = 'this HTML will appear in the dom when a condition is met'
const gameCont = document.getElementById('game-container');
const decideWinner = () => {
if ( spadesPosition === 90 ||
heartsPosition === 90 ||
clubsPosition === 90 ||
diamondsPosition === 90 ) {
gameCont.insertAdjacentHTML("afterend", winnerHTML);
}
};
Now I want to remove that HTML, I've tried to set winnerHTML = ''; but clearly it's not the right logic. Since the added HTML is not part of the document, I can't select it and remove it.
Could you guys help me out here? My apologies in advance if there's already something about this but I didn't find it.
Cheers!
Add it to paragraph or span with id for later reference :
let winnerHTML = "<p id='para'>this html will appear in the dom when a condition is met<p>";
Then to remove it:
let elem=document.getElementById("para");
elem.remove();
You can also use document.createElement and store the element in a variable. Then you can use the remove function to remove it. Example
let elem = document.createElement("p");
elem.innerHTML = "Your text";
document.getElementById('game-container').appendChild(elem);
elem.remove();

Wrap a tag around multiple instances of a string using Javascript

I’m trying to wrap multiple instances of a string found in html around a tag (span or abbr) using pure JS. I have found a way to do it by using the code:
function wrapString() {
document.body.innerHTML = document.body.innerHTML.replace(/string/g, ‘<tag>string</tag>');
};
but using this code messes with a link’s href or an input’s value so I want to exclude certain tags (A, INPUT, TEXTAREA etc.).
I have tried this:
function wrapString() {
var allElements = document.getElementsByTagName('*');
for (var i=0;i<allElements.length;i++){
if (allElements[i].tagName != "SCRIPT" && allElements[i].tagName != "A" && allElements[i].tagName != "INPUT" && allElements[i].tagName != "TEXTAREA") {
allElements[i].innerHTML = allElements[i].innerHTML.replace(/string/g, ‘<span>string</span>');
}
}
}
but it didn’t work as it gets ALL the elements containing my string (HTML, BODY, parent DIV etc.), plus it kept crushing my browser. I even tried with JQuery's ":containing" Selector but I face the same problem as I do not know what the string's container is beforehand to add it to the selector.
I want to use pure JavaScript to do that as I was planning on using it as a bookmark for quick access to any site but I welcome all answers regarding JQuery and other frameworks as well.
P.S. If something like that has already been answered I couldn't find it...
This is a quite complicated problem actually (you can read this detailed blog post about it).
You need to:
recurse on the dom tree
find all text nodes
do your replace on its data
make the modified data into dom nodes
insert the dom nodes to the tree, before the original text node
remove the original text node
Here is a demo fiddle.
And if you still need tagName based exclusions, look at this fiddle
The code:
function wrapInElement(element, replaceFrom, replaceTo) {
var index, textData, wrapData, tempDiv;
// recursion for the child nodes
if (element.childNodes.length > 0) {
for (index = 0; index < element.childNodes.length; index++) {
wrapInElement(element.childNodes[index], replaceFrom, replaceTo);
}
}
// non empty text node?
if (element.nodeType == Node.TEXT_NODE && /\S/.test(element.data)) {
// replace
textData = element.data;
wrapData = textData.replace(replaceFrom, replaceTo);
if (wrapData !== textData) {
// create a div
tempDiv = document.createElement('div');
tempDiv.innerHTML = wrapData;
// insert
while (tempDiv.firstChild) {
element.parentNode.insertBefore(tempDiv.firstChild, element);
}
// remove text node
element.parentNode.removeChild(element);
}
}
}
function wrapthis() {
var body = document.getElementsByTagName('body')[0];
wrapInElement(body, "this", "<span class='wrap'>this</span>");
}

Issue Extracting the div tag from inside another div

HI i am working in Javascript.
My code is:
var oldData = document.getElementById(id).innerHTML;
alert(oldData);
alert is shown as : text<img src="add-icon.png"><div id = "1"></div>
Here old data contains a text an image tag and a div tag. The issue is I want to just access the div tag id but i dnt know how to get it. Please help.
Thanx in advance
The thing with using vanilla JavaScript is, you've got to write all the filters yourself :)
var oldData = document.getElementById(id), firstDiv, id;
firstDiv = filterElements(node);
id = firstDiv.id;
function filterElements( node ){
var children = parent.childElements, firstDiv, node;
for (var i = 0; i < children.length; i += 1 ){
node = children[i];
if (node.tagName && node.nodeType && node.nodeType === 1 &&
node.tagName.toLowerCase() === "div"){
firstDiv = node;
break;
}
}
return firstDiv;
}
I suggest the use of jQuery. Then you can access the id of the div within its element stored as elem as
$(elem).children("div").attr("id")
If you know the parent by ID, then you can do this:
$("#"+id).children("div").attr("id")
or even this:
$("#"+id+">div").attr("id")
Of course, if you want the ID just to access an element, then you don't need to. To append a new image to the div:
$("#"+id+">div").append("<img ...>")
or
$("#"+id+">div").append($("<img>"). ...)
Also, I recommend using classes instead of childhood to identify elements:
$("#"+id+" .image-holder").append(...)
or
$("#"+id+").find(".image-holder").append(...)

convert htmlelement to string for comparison javascript

I am using a function that obtains a target element id at onclick. Example, if I click on the text element that has the id of 'help'.
var click = (e && e.target) || (event && event.srcElement);
The var click would contain the ref to the id of "help".
I want to compare the var click to the string 'help' using the if statement below.
if (click == 'about') {do something}
The comparison does not work because the var click is not a string. When I use the alert(click) to debug, it shows click as "object HTMLElement".
How would you compare whether the id 'help' is obtained from var click?
I could write out something like
if (click == document.getElementById('help')) {do something}
but that would make a long statement.
also
if the var click is document.getElementById('help'), how would I create a new var "div" as document.getElementById('helpdiv') by adding the word "div" in the id of the var click?
basically, I want to use the same function to generate dynamic responses to each element that was clicked on, and not having to create a separate function for each element.
if (click.id == 'help'){
var link = click;
var divid = click.id+'div';
var div = document.getElementById(divid);
alert (div.id); //helpdiv string
}
TIA for all your help.
The simplest approach is probably
if (click.id == 'help') { //do something }
The line:
var click = (e && e.target) || (event && event.srcElement);
is not getting the id rather the element itself, use getAttribute to get the id instead.
var id = click.getAttribute('id');
alert(id);
Or simply:
var id = click.id;
alert(id);
So your condition now becomes:
if (id == 'about') {do something}
and
if (id == document.getElementById('help')) {do something}
if (click["id"] != null && click["id"] == "help") { do stuff }
Addressing the last part of your question, you cannot create a new DOM object by modifying your current one like you propose in your question, and I do not understand if you want to locate an already existing object and store it in a variable, or create a new one from scratch, so :
If you want to find a new one, and you know its named like "show" + the id of your current click variable, you can easily do:
if (click["id"] != null) {
var found = document.getElementById("show" + click["id"]);
}
Or if you intend to create a new one :
if (click["id"] != null) {
var created = document.createElement("div"); // replace with whatever you need
created["id"] = "show" + click["id"];
}
I think this is what you're after ...
if (click.id == 'help') { // Test to see if click is the 'help' element
var newEl = document.createElement('div'); // Create a new element
newEl.id = click.id + 'div'; // Set it's id
newEl.innerHTML = 'my help text goes here'; // Set it's content
click.parentElement.appendChild(newEl); // Add it to the document immediately following the 'click' element
}
Be aware that the name of an element is not the same as the element itself. Just making a new element name by appending 'div' to some existing name does not, in and of itself, create a new element. You have to explicitely create a new element object and add it into the document, as shown above.

Categories