Looping Through Classes And Changing Color - javascript

I need a little help, this may seem easy, but I have an invert colors button on my webpage, and I would need to loop through elements with the class name of text.
Here's the code:
//Javascript File
var text = document.getElementsByClassName('text');
var button = document.getElementById('invertcolors');
function onClick() {
for (var i = 0; i < text.length; i++) {
//Do something like this:
//text[i].style.color =
}
}
button.addEventListener('click', onClick, false);
<!--Stuff here...-->
<div id="content">
<font id="text1" class="text">I walked in the forest</font>
<br>
<font id="text2" class="text">Through the grey concrete path</font>
<br>
<font id="text3" class="text">Holding on the dog</font>
</div>
<!--Stuff here...-->
I need to loop through the elements in the i variable, and set their color to white. I don't know how, can someone help? Thanks!

Please check the javascript code below:
var text = document.getElementsByClassName('text');
var button = document.getElementById('invertcolors');
function onClick() {
var selectedId
console.log(text[0].getAttribute( 'id' ));
for (var i = 0; i < text.length; i++) {
console.log(text[i].getAttribute('id'));
selectedId = text[i].getAttribute('id');
document.getElementById(selectedId).style.color = "white";
}
}
button.addEventListener('click', onClick, false);
And also check the code # https://jsfiddle.net/cskcvarma/akLx5tt8/7/
Please let me know if this helps.

var text = document.getElementsByClassName('text');
var button = document.getElementById('invertcolors');
function onClick(text) {
for (var i = 0; i < text.length; i++) {
text[i].style.color = '#fff';
}
}
button.addEventListener('click', onClick.bind(null, text), false);

You pretty much have the exact code you would need, see below for a working version of what you wanted.
var text = document.getElementsByClassName('text');
var button = document.getElementById('invertcolors');
function onClick() {
for (var i = 0; i < text.length; i++) {
text[i].style.color = '#f00';
}
}
button.addEventListener('click', onClick, false);
#invertcolors {
height:20px;
width:100px;
border:1px solid black;
border-radius:7px;
}
<div id="content">
<font id="text1" class="text">I walked in the forest</font>
<br>
<font id="text2" class="text">Through the grey concrete path</font>
<br>
<font id="text3" class="text">Holding on the dog</font>
</div>
<div id='invertcolors'>Button</div>

You can use querySelectorAll method to do that. The <font> element is not supported in HTML5 so you should replace it with for example <span> element.
var button = document.getElementById('click');
button.addEventListener('click',function(){
var elements = document.querySelectorAll('.text');
elements.forEach(function(a){
a.style.backgroundColor = 'yellow';
});
});
<div id="content">
<span id="text1" class="text">I walked in the forest</span>
<br>
<span id="text2" class="text">Through the grey concrete path</span>
<br>
<span id="text3" class="text">Holding on the dog</span>
</div>
<br/>
<button id="click">change style</button>

Related

change the text of every element in a class javascript

How do I change the text of all elements in a class
If the element is in a division do I need to do anything else?
P.S. I hardly know js so plz help.
enter image description here
You can use querySelectorAll and with a foreach set the new text:
const examples = document.querySelectorAll('.example');
examples.forEach(example => {
example.innerHTML = 'new text';
});
<div class="example">
text 1
</div>
<div class="example">
text 2
</div>
I hope these examples can help you
function myFunction()
{
x=document.getElementsByClassName("infoblock"); // Find the elements
for(var i = 0; i < x.length; i++){
x[i].innerText="text changed!"; // Change the content
}
}
function myFunction2()
{
x=document.getElementsByClassName("notationgrade"); // Find the first span elements
y=document.getElementsByClassName("percentgrade"); // Find the second span elements
for(var i = 0; i < x.length; i++){
x[i].innerText="text 1 changed!"; // Change the content
}
for(var i = 0; i < y.length; i++){
y[i].innerText="text 2 changed!"; // Change the content
}
}
<body>
<div class="class-stats fsClassStatsAverage">
<p><span class="infoblock notationgrade">old text 1 </span></p>
<p> <span class="infoblock percentgrade">old text 2</span></p>
</div>
<button type="button" onclick="myFunction()">Change All Spans</button>
<button type="button" onclick="myFunction2()">Change Each Span</button>
</body>

Javascript search with includes for each DIV

I am trying to develop a filter function with includes. As for now, I have 3 main DIV, and each main DIV has its own DIV. The current script I have now only worked on main DIV.
Instead of highlighting main DIV, I only want to highlight matched char DIV.
For example, when key in 'inner', Inner First and Inner Sec will be highlighted. When key in 'Inner First', only DIV for Inner First will be highlighted.
Would appreciate if anyone of you can help me. Thanks in advance.
function myFunction() {
var input = document.getElementById("Search");
var filter = input.value.toLowerCase();
var nodes = document.getElementsByClassName('target');
for (i = 0; i < nodes.length; i++) {
nodes[i].style.backgroundColor = "";
if (input.value !== '') {
if (nodes[i].innerText.toLowerCase().includes(filter)) {
nodes[i].style.backgroundColor = "blue";
for (j = 0; j < nodes[i].length; j++) {
nodes[j].style.backgroundColor = "";
if (input.value !== '') {
if (nodes[j].innerText.toLowerCase().includes(filter)) {
nodes[j].style.backgroundColor = "grey";
for (k = 0; k < nodes[j].length; k++) {
nodes[k].style.backgroundColor = "";
if (input.value !== '') {
if (nodes[k].innerText.toLowerCase().includes(filter)) {
nodes[k].style.backgroundColor = "yellow";
} else {
nodes[k].style.backgroundColor = "red";
}
}
}
} else {
nodes[j].style.backgroundColor = "red";
}
}
}
} else {
nodes[i].style.backgroundColor = "red";
}
}
}
}
<table align="center" width="20%">
<tr>
<td style="padding-right: 10px">
<input type="text" id="Search" title="Type in a name">
<button onclick="myFunction()">
Click to search
</button>
</td>
</tr>
</table>
<br>
<div class="target">
This is my DIV element.
<div class="target">
Inner First
<div class="target">
Inner Sec
</div>
</div>
</div>
<div class="target">
This is another Div element.
</div>
<div class="target">
Can you find me?
</div>
The problem with your code is that node.innerText also gives the text of the child elements. To fix this, you should use node.childNodes[0].nodeValue which will only give the node's text.
Moreover, you are doing nested loops but referencing incorrectly:
for (j = 0; j < nodes[i].length; j++).
nodes[i].length here is undefined. Maybe you mean nodes[i].children.length?
Also, your code is hard to follow with all the nested loops which does the same thing and just differ in color. I suggest you make a recursive function.
Please see below function if I what I'm thinking is correct. I guess you wanted to put different colors depending of the level of the node in the heirarchy. (Open your developer tool to see console.log outputs)
var input;
var filter;
var nodes;
var colors;
function myFunction() {
//initialize variables
input = document.getElementById("Search");
filter = input.value.toLowerCase();
nodes = document.getElementsByClassName('target');
// store colors here for accessing via index
colors = ['blue', 'grey', 'yellow', 'green'];
if (filter !== '') {
updateNodesBg(nodes); //neat
}
}
function updateNodesBg(lNodes, colorIdx) {
colorIdx = colorIdx || 0; // this will be the index of the color
for (var i = 0; i < lNodes.length; i++) {
var currentNode = lNodes[i];
var currentText = currentNode.childNodes[0].nodeValue;
var innerText = currentNode.innerText;
console.log('currentText and innerText EQUAL?', currentText === innerText);
if (currentText.toLowerCase().includes(filter)) {
currentNode.style.backgroundColor = colors[colorIdx]; //pass in the index to get the color
} else {
currentNode.style.backgroundColor = 'red'; //else, we should color red
}
if (currentNode.children && currentNode.children.length > 0) {
updateNodesBg(currentNode.children, colorIdx + 1); //if the node has children, call `updateNodesBg` recursively
}
}
}
<table align="center" width="20%">
<tr>
<td style="padding-right: 10px">
<input type="text" id="Search" title="Type in a name">
<button onclick="myFunction()">
Click to search
</button>
</td>
</tr>
</table>
<br>
<div class="target">
This is my DIV element.
<div class="target">
Inner First 1
<div class="target">
Inner Sec 1
<div>Inner Third 1</div>
</div>
<div class="target">
Inner Sec 2
<div>Inner Third 1</div>
<div>Inner Third 2
<div>Inner Fourth 1</div>
</div>
</div>
</div>
<div class="target">
Inner First 2
<div class="target">
Inner Sec 2
<div>Inner Third 2</div>
</div>
</div>
</div>
<div class="target">
This is another Div element.
</div>
<div class="target">
Can you find me?
</div>
Note that .nodeValue has different returns depending on the type of the node:
Node Value of nodeValue
CDATASection Content of the CDATA section
Comment Content of the comment
Document null
DocumentFragment null
DocumentType null
Element null
NamedNodeMap null
EntityReference null
Notation null
ProcessingInstruction Entire content excluding the target
Text Content of the text node
You need to check if the text is in the current div, then in any child divs.
InnerText and textContent both concatenate text of the parent and all children, so you'll need to figure out where the text is actually coming from.
I do this recursively, because I don't think you'll have that many layers of divs. If there is a lot of nesting, then you'd need to take an iterative approach
function myFunction()
{
let targets = document.querySelectorAll('.target');
targets.forEach(target => target.style.background = 'white');
let filterText = document.getElementById('Search').value;
if(filterText != '')
{
let result = [...targets].filter(target => target.textContent.includes(filterText));
result.forEach(r => { checkSelf(r, filterText); checkKids(r, filterText); });
}
}
function checkSelf(element, filterText)
{
let selfText = element.textContent;
for(let child of element.children)
{
selfText = selfText.replace(child.textContent, '');
}
if(selfText.includes(filterText))
{
element.style.background = 'limegreen';
}
else
{
element.style.background = 'white';
}
}
function checkKids(element, filterText)
{
for(let child of element.children)
{
if(!child.textContent.includes(filterText))
{
child.style.background = 'white';
}
else
{
checkKids(child, filterText);
}
}
}
<table align="center" width="20%">
<tr>
<td style="padding-right: 10px">
<input type="text" id="Search" title="Type in a name">
<button onclick="myFunction()">
Click to search
</button>
</td>
</tr>
</table>
<br>
<div class="target">
This is my DIV element.
<div class="target">
Inner First
<div class="target">
Inner Sec
</div>
</div>
</div>
<div class="target">
This is another Div element.
</div>
<div class="target">
Can you find me?
</div>

classList.add works but toggle doesn't

My HTML
<div class="chapter">text text text </div>
<div class="chapter">text text text </div>
<button id="button">button</button>
My js
var button = document.querySelector('#button');
var chapter = document.querySelectorAll('.chapter');
for(var i = 0; i < chapter.length; i++){
button.addEventListener('click', function(){
for(var i = 0; i < chapter.length; i++) {
chapter[i].classList.add('active');
}
});
}
This adds the class of "active" on clicking the button.
But toggle doesn't work. Instead of
chapter[i].classList.add('active');
When I do,
chapter[i].classList.toggle('active');
the class of "active" does not toggle. console shows no error.
So I tried to check the class of "active" first & remove the class if the class exists. I know I was trying to reinvent the toggle function; as stated above, toggle wasn't working so I tried it anyway.
if (chapter[i].contains('active')){
chapter[i].classList.remove('active');
And I got a slew of error messages. This is as far as I got. I somehow felt that this wasn't going to work but just tried it anyway.
I am stumped.
Can anyone point out why classList.toggle isn't working in my code & how this can be fixed?
Thanks.
You have one too many loop. Remove the outer one:
var button = document.querySelector('#button');
var chapter = document.querySelectorAll('.chapter');
button.addEventListener('click', function(){
for(var i = 0; i < chapter.length; i++) {
chapter[i].classList.toggle('active');
}
});
.active{
color: red;
}
<div class="chapter">text text text </div>
<div class="chapter">text text text </div>
<div class="chapter">text text text </div>
<div class="chapter">text text text </div>
<button id="button">button</button>
var button = document.querySelector('#button');
var chapters = document.querySelectorAll('.chapter');
button.addEventListener('click', function(){
for(var index = 0; index < chapters.length; index++) {
if(chapters[index].classList.contains('active')){
chapters[index].classList.remove('active');
}else{
chapters[index].classList.add('active');
}
}
});
.active {
color: red;
}
<div class="chapter">text text text </div>
<div class="chapter">text text text </div>
<button id="button">Toggle Color</button>

How to make selector choose div class and with tag name of p?

Hello I am kind of stuck right now. I am trying to make my script choose all paragraph inside a div class of change but I don't really understand how to do it. The html looks something like this in the body
<body>
<div id="top" class="change">
<p> Microsoft </p>
<p> Apple </p>
<p> Sony </p>
</div>
<div id="middle">
<p> Disney </p>
<p> Nintendo </p>
<p> Sony </p>
</div>
<div id="bottom" class="change">
<p> Ice</p>
<p> Tea</p>
<p> Water</p>
</div>
</body>
I am trying to make it so when the mouse cursor touches anything that has a class of change in a paragraph, it will change the color to a color of my choice but I don't know how to do it with selectors with pure javascript. This is the current code I have but it is not working. I can only use javascript
var fontChange = document.getElementsByClass("change").getElementsByTagName("p");
for (let i = 0; i < changeFont.length; i++) {
changeFont[i].onmouseover=function() {
this.style.color = "red";
}
}
for (let i = 0; i < changeFont.length; i++) {
changeFont[i].onmouseout=function() {
this.style.color = "black";
}
}
There's no function getElementsByClass, it's getElementsByClassName.
document.getElementsByClassName() returns a collection (see What do querySelectorAll, getElementsByClassName and other getElementsBy* methods return?), you have to index it to use getElementsByTagName on the elements that it returns.
var fontChange = [];
var change = document.getElementsByClassName("change");
for (var i = 0; i < change.length; i++) {
var paras = [].slice.call(change[i].getElementsByTagName("p"));
fontChange.concat(paras);
}
Or you could just use querySelectorAll
var fontChange = document.querySelectorAll(".change p");
You also have a typo. You set the variable fontChange, but then use changeFont in the loop.
You can achieve what you want without javascript, just add this code to your css
.change p:hover {
color: red;
}

Show one div and hide the previous showing div

I have some links that will show a div when clicking it. When clicking another link, it should show the link's associated div and hide the previously shown div.
HTML
Text 1
Text 2
Text 3
<div id="text1" class="unhidden">
This will show up when the Text 1 link is pressed.
</div>
<div id="text2" class="hidden">
This will show up when the Text 2 link is pressed.
</div>
<div id="text3" class="hidden">
This will show up when the Text 3 link is pressed.
</div>
Javascript
function unhide(divID) {
var item = document.getElementById(divID);
if (item) {
item.className='unhidden';
}
}
CSS
.hidden { display: none; }
.unhidden { display: block; }
How can I accomplish this?
Try with:
function unhide(divID) {
var unhidden = document.getElementsByClassName('unhidden');
for (var k in unhidden) {
unhidden[k].className='hidden';
}
var item = document.getElementById(divID);
if (item) {
item.className='unhidden';
}
}
You can do something like this :
function unhide(divID) {
var divs = document.getElementsByTagName('div');
foreach(var div in divs){
div.className = 'hidden';
if(div.id == divID)
div.className = 'unhidden';
}
}
Be careful with document.getElementsByTagName('div');, it will return you all divs on your document. You could adapt it using a wrapper.
For example :
HTML
<div id="wrapper">
<div id="text1" class="unhidden">
This will show up when the Text 1 link is pressed.
</div>
<div id="text2" class="hidden">
This will show up when the Text 2 link is pressed.
</div>
<div id="text3" class="hidden">
This will show up when the Text 3 link is pressed.
</div>
</div>
JS :
var divs = document.getElementById('wrapper').getElementsByTagName('div');
Try this http://jsfiddle.net/L79H7/1/:
function unhide(divID) {
var divIds = [ "text1", "text2", "text3" ];
for ( var i = 0, len = divIds.length; i < len; i++) {
var item = document.getElementById(divIds[i]);
if (item) {
item.className = divID == divIds[i] ? 'unhidden' : 'hidden';
}
}
}
You could also store in an array the names of the divs you want to hide and iterate over it when unhiding one:
var divs= new Array("text1", "text2", "text3");
function unhide(divID) {
var item = document.getElementById(divID);
if (item) {
item.className='unhidden';
}
for (var i in divs){
if (divs[i] != divID){
item = document.getElementById(divs[i]);
if (item) {
item.className='hidden';
}
}
}
}
JSFiddle
You don't need exactly links for this, but if you insist change it to:
<a href="#" onclick='unhide("text3");'>Text 3</a>
Otherwise you can change it to:
<p onclick="unhide('text1')">Text 1</p>
<p onclick="unhide('text2')">Text 2</p>
<p onclick="unhide('text3')">Text 3</p>
<div id="text1" class="unhidden">
This will show up when the Text 1 link is pressed.
</div>
<div id="text2" class="hidden">
This will show up when the Text 2 link is pressed.
</div>
<div id="text3" class="hidden">
This will show up when the Text 3 link is pressed.
</div>
And your function should look like this to add or remove classes:
function unhide(id){
yourElement = document.getElementById(id);
if(yourElement.className == "unhidden"){
yourElement.className = "hidden";
}else{
yourElement.className = "unhidden";
}
}
demo
<div id="text1" class="hidden"> 1 </div>
<div id="text2" class="hidden"> 2 </div>
<div id="text3" class="hidden"> 3 </div>
.hidden{ display:none; }
#text1{ display: block; }
function show(id) {
var item = document.getElementById(id);
var all = document.getElementsByClassName('hidden');
for(var i=0; i<all.length; i++)all[i].style.display = 'none';
if(item)item.style.display = 'block';
}
you can use jquery try the code below and import the jquery library first
$('#text1').show();
$('#text2').hide();
it is the easiest way

Categories

Resources