Javascript targeting the parent div from a string of text - javascript

<div class="myDiv">
<span class="mySpan">SAMPLE TEXT A</span>
<span class="mySpan">SAMPLE TEXT B</span>
</div>
I'm struggling to get the right javascript to hide "myDiv" if the text in "mySpan" is "SAMPLE TEXT A".

Somehow like this (you will not see anything, because <div class="myDiv"> is hidden already):
var spans = document.getElementsByClassName('mySpan')
for(var i = 0; i < spans.length; i++) {
if(spans[i].innerHTML === 'SAMPLE TEXT A') spans[i].parentElement.style.display = 'none';
}
<div class="myDiv">
<span class="mySpan">SAMPLE TEXT A</span>
<span class="mySpan">SAMPLE TEXT B</span>
</div>
UPDATE
"What is the significance of the 'for' statement?"
document.getElementsByClassName('mySpan') will select ALL elements with class mySpan, think about it as an array. Then i iterate through all selected span's and finding the case, where innerHTML is equal to our specific string.
"In the if statement, how would I specify just the parent div and not every element with class "myDiv"? There are other elements on the page with that class."
If so, you need to use parentElement (I have updated my answer with needed row).

Related

Javascript - Hide all elements that do not have the specified ID

Hey there StackOverflow Community!
I'm fairly new to Stack and coding in general so this code will probably have an obvious error that I can't figure out.
Basically, in the following code I want everything shown on screen that isn't the element with the id settings to be hidden.
if ((!"#settings").style.display === "block") {
$(!"#settings").hide();
}
HTML:
<body>
<span id="mainBtnArea">
<button id="settings-btn">Settings</button>
<button id="stats-btn">Stats</button>
</span>
<div id="mainArea">
<h1 id="clickHeader"></h1>
<button id="main-btn">Click Me</button>
</div>
<div id="settings">
<h1>this is the page I want to show</h1>
</div>
<div id="stats">
<p id="stats-clicks" class="stats">Keys:</p>
<p id="stats-keys" class="stats">Keys:</p>
</div>
</body>
Query selectors don't work quite like that - you can't negate a selector with a ! symbol.
You can, however, use the visible selector and the not selector. The following will hide every element that is a child of body ($("body.find"), is a div or span (div, span), is visible (:visible), and doesn't have the id 'settings' (:not('#settings'))
$("body").find("div:not('#settings'), span").hide()
var elements = document.getElementsByTagName('div');
for (var i = 0; i < elements.length; i++) {
if (elements[i].id != 'settings') {
elements[i].style.display = 'none';
}
}
You need to have a forloop!
Update: You have to add an element tag DIV in order for it to work. Please see above.
It works for me:
https://jsfiddle.net/bowtiekreative/j697okqd/1/

Getting text content of a div element excluding its children

I have the following HTML code and I need to console.log only Shipping.
I tried a few methods but can't seem to get it to work.
I tried selecting first its children and printing out the textContent of its parent - no go. I could delete its children and print out what's left but I can't do that.
Any suggestions?
<div class="accordion shadowed-box shipping collapsed summary">
<fieldset>
<legend>
Shipping
<div id="shippingTooltip" class="form-field-tooltip cvnship-tip" role="tooltip">
<span class="tooltip">
<div class="tooltip-content" data-layout="small tooltip-cvn">
<div id="cart-checkout-shipping-tooltip" class="html-slot-container">
<p>We ship UPS, FedEx and/or USPS Priority Mail.<br>
<a class="dialogify" data-dlg-options="{"height":200}" href="https://www.payless.com/customer-service/ordering-and-shipping/cs-ordering-shipping-schedule.html" title="shipping information">Learn more about our shipping methods and prices.</a>
</p>
</div>
</div>
</span>
</div>
Edit
</legend>
</fieldset>
</div>
I tried this:
var accordionChildren = document.querySelector('.accordion.shadowed-box.shipping>fieldset>legend *');//selects the first child
var accordionTitle = accordionChildren.parentElement;
var text = accordionTitle.textContent;
console.log(text);
I want to get Shipping but instead I get still all the text contents of the legend element.
you can access Text nodes by iterating over the child nodes (or access the intended node directly) of the accordionTitle variable.
let textNode = accordionTitle.childNodes[0],
text = textNode.textContent;
console.log(text);
See https://developer.mozilla.org/en-US/docs/Web/API/Node/childNodes and https://developer.mozilla.org/en-US/docs/Web/API/Text
You just need to find the TextNode child from all of the elements children, you do this by iterating over all of the childNodes and when the node type matches TextNode, return its textContext.
For a jQuery based solution on how to pick the TextNode child of an element see this question - but my example shows how to do it in vanilla ES (with a for loop over childNodes):
Object.defineProperty(HTMLElement.prototype, 'onlyTextContent', {
enumerable: false,
configurable: false,
get: function() {
for(let i = 0; i < this.childNodes.length; i++) {
if(this.childNodes[i].nodeType === Node.TEXT_NODE) {
return this.childNodes[i].textContent.trim();
}
}
return null;
}
});
document.addEventListener('DOMContentLoaded', function() {
console.log(
document.getElementById('legend1').onlyTextContent
);
});
<div class="accordion shadowed-box shipping collapsed summary">
<fieldset>
<legend id="legend1">
Shipping
<div id="shippingTooltip" class="form-field-tooltip cvnship-tip" role="tooltip">
<span class="tooltip">
<div class="tooltip-content" data-layout="small tooltip-cvn">
<div id="cart-checkout-shipping-tooltip" class="html-slot-container">
<p>We ship UPS, FedEx and/or USPS Priority Mail.<br>
<a class="dialogify" data-dlg-options="{"height":200}" href="https://www.payless.com/customer-service/ordering-and-shipping/cs-ordering-shipping-schedule.html" title="shipping information">Learn more about our shipping methods and prices.</a>
</p>
</div>
</div>
</span>
</div>
Edit
</legend>
</fieldset>
</div>
You can get the contents of the <legend> tag as a string and then use a regular expression to remove the HTML tags and their content inside. Like this:
let legends = document.querySelector('.accordion.shadowed-box.shipping>fieldset>legend');
let title = legends.innerHTML.replace(/<.*/s, '');
// title = "Shipping"
The regular expression matches the first < character and everything that follows. So we replace that match with an empty string ''.

jQuery : Split the DOM Node using jQuery

My problem is to split the Dom element using jquery.
<span class="start">
<span class="second">
new text <span class='split'>is written</span> in this place.
</span>
</span>
And I want to Split the above DOM Like this.
<span class="start"><span class="second">new text</span></span>
<span class="start"><span class="second">is written</span></span>
<span class="start"><span class="second">in this place.</span></span>
Please, anybody give me some advice.
One way to do it would be:
last_text=$('.split')[0].nextSibling; //get textNode after split span
prev_text=$('.split')[0].previousSibling; //get text Node before split span
current=$('.split').text(); //get split span text
$('.second').html(' '); //clear current html
cloned1=$('.start').clone(); // clone el
cloned1.insertAfter($('.start'));
cloned2=$('.start').first().clone(); //clone one more
cloned2.insertAfter($('.start').last());
//set text for elements
$('.start .second').eq(0).html(prev_text);
$('.start .second').eq(1).html(current);
$('.start .second').eq(2).html(last_text);
Demo:
last_text=$('.split')[0].nextSibling; //get textNode after split span
prev_text=$('.split')[0].previousSibling; //get text Node before split span
current=$('.split').text(); //get split span text
$('.second').html(' '); //clear current html
cloned1=$('.start').clone(); // clone el
cloned1.insertAfter($('.start'));
cloned2=$('.start').first().clone(); //clone one more
cloned2.insertAfter($('.start').last());
//set text for elements
$('.start .second').eq(0).html(prev_text);
$('.start .second').eq(1).html(current);
$('.start .second').eq(2).html(last_text);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span class="start">
<span class="second">
new text <span class='split'>is written</span> in this place.
</span>
</span>
P.S. If there are no classes (i guess that could be the case), you will have to use different selectors, to target spans (inside container?), with eq(), maybe, but, basically, this simple logic should work...

Add div as only child of a node

I am trying to add div as only child to a node. and if that node already has any children make them children of the div.
original DOM looks like:
<a href = "">
<span id="gsp" > </span>
<span id="gbsp"> some text </span>
</a>
I want the output to be:
<a href = "">
<div id="oaa_web_accessibility_highlight">
<span id="gsp" > </span>
<span id="gbsp"> some text </span>
</div>
</a>
instead, below snippet gives me:
<a href = "">
<div id="oaa_web_accessibility_highlight"> </div>
<span id="gsp" > </span>
<span id="gbsp"> some text </span>
</a>
I am trying to use the below snippet, but it is not working.
var new_div_element = this.document.createElement('div');
new_div_element.id = 'oaa_web_accessibility_highlight';
node.insertBefore(new_div_element, node.childNodes[0]);
for (var i =0; i < node.childNodes.length; i++) {
if (i == 0) continue;
node.childNodes[0].appendChild(node.childNodes[i]);
}
please can anyone help me on this?
Do it like this:
var new_div_element = document.createElement('div');
new_div_element.id = 'oaa_web_accessibility_highlight';
while (node.firstChild) {
new_div_element.appendChild(node.firstChild);
}
node.appendChild(new_div_element);
This empties the children of node into new_div_element, and then appends new_div_element to the now empty node.
It doesn't use innerHTML, so you're not destroying any state of the elements being transferred.
FYI, the reason yours didn't work properly was that your loop is incrementing i, but you're removing elements from the .childNodes list when you do the .appendChild.
Since .childNodes is a live list, its content is updated when you move one of its items to a different location. As a result, after the first child is removed, the second child takes its place at that index. Since your i is incremented, it skips passed the one(s) that were relocated in the list.
If you're willing to use jQuery, it has a wrapAll method that does this for you.
$(node).children().wrapAll('<div id="oaa_web_accessibility_highlight"></div>');

jQuery update html element text without affect the HTML children elements

I have a litle problem and I don't know how to fix it.
I have an HTML hierarchy like the one here
<ul id="mylist">
<li id="el_01">
<div class="title">
Title Goes Here
<span class="openClose"></span>
</div>
</li>
</ul>
What I like to do is to modify the "Title Goes Here".
What I have try is :
$('#el_01 title').text('New Title Goes Here');
But that also remove the :
<span class="openClose"></span>
Is there a way to update only the "Title Goes Here" without affect the span element ?
You can edit the text node directly by accessing the DOM element, and getting its firstChild.
$('#el_01 .title')[0].firstChild.data = 'New Title Goes Here';
If there are several .title elements, you can do it in an .each() loop.
$('#el_01 .title').each(function(i,el) {
el.firstChild.data = 'New Title Goes Here';
});
Two possible solution:
Either: Wrap the text in a span of its own:
<div class="title">
<span class="text">Title Goes Here</span>
<span class="openClose"></span>
</div>
... and update that:
$('#el_01 .text').text('New Title Goes Here');
Or: Keep a copy of the openClose span and re-insert it after updating the text:
var openClose = $('#el_01 .title .openClose');
$('#el_01 .title').text('New Title Goes Here').append(openClose);

Categories