document.getElementById can't select more than one element - javascript

I'm working on loading. I have div #loading which is visible. And more divs #message which are hidden. I have js function.
function loading() {
setTimeout(function() {
document.getElementById("loading").style.display = "none";
document.getElementById("message").style.display = "block";
}, 500, "fadeOut");
}
But that row document.getElementById("message").style.display = "block"; selects only first div #message.
function loading() {
setTimeout(function() {
document.getElementById("loading").style.display = "none";
document.getElementById("message").style.display = "block";
}, 500, "fadeOut");
}
loading();
#loading {
display: block;
}
#message {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="messages" onload="loading();">
<div id="loading">
...
</div>
<div id="message">
QWERTY
</div>
<div id="message">
123456
</div>
</div>

As the others have mentioned ids are unique and can only be used once on a page, so use a class instead. Here I've used querySelectorAll to grab a static list of classes.
The other issue is that you seem to be trying to use jQuery to fade the elements out, but you're not using jQuery for anything else. I'm going to suggest you CSS transitions. They're easy to use, and you don't have the need of loading a huge library. Here I add new classes fadein and fadeout which (based on your code) increases/reduces the opacity of the specified elements to zero over three seconds.
function loading() {
setTimeout(function() {
// use a class for the loader too otherwise the transition
// won't work properly
const loader = document.querySelector('.loading');
loader.classList.add('fadeout');
// grab the elements with the message class
const messages = document.querySelectorAll('.message');
// loop over them and add a fadeout class to each
[...messages].forEach(message => message.classList.add('fadein'));
}, 500);
}
loading();
.loading {
opacity: 1;
}
.message {
opacity: 0;
}
.fadein {
transition: opacity 3s ease-in-out;
opacity: 1;
}
.fadeout {
transition: opacity 3s ease-in-out;
opacity: 0;
}
<div class="messages">
<div class="loading">
Loading
</div>
<div class="message">
QWERTY
</div>
<div class="message">
123456
</div>
</div>

You need to use unique ID's for your DOM elements. Try modify your code like this:
<script type="text/javascript">
function loading() {
setTimeout(function() {
document.getElementById("loading").style.display = "none";
var el = document.getElementsByClassName('message');
console.log(el);
$.each(el, function(i, item){
item.style.display = 'block';
});
}, 500, "fadeOut");
}
loading();
</script>
<style>
#loading {
display: block;
}
.message{
display: none;
}
</style>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="messages" onload="loading();">
<div id="loading">
...
</div>
<div class="message">
QWERTY
</div>
<div class="message">
123456
</div>
</div>

ID attribute must be unique. You can't use same ID multiple times on the page. If you like to use same key then use it as a class or data-id which can be same or differ.

You cannot have same id twice in a document in order to select multiple elements group them by same Class rather than by id and then use the following to select them all.
document.querySelectorAll(".ClassName")
Or
document.getElementsByClassName(".ClassName");
Note that both methods returns a collection of all elements in the document with the specified class name, as a NodeList object.

function loading() {
setTimeout(function() {
document.getElementById("loading").style.display = "none";
document.getElementById("message").style.display = "block";
}, 500, "fadeOut");
}
loading();
#loading {
display: block;
}
#message {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="messages" onload="loading();">
<div id="loading">
...
</div>
<div id="message">
QWERTY
</div>
<div id="message">
123456
</div>
</div>

Related

How could this JavaScript function be simplified. I have 100 buttons controlling the show/hide display of 100 content areas

The abbreviated JS file below provides the same functionality for 100 buttons.
All buttons are identified by ID names such as #btn1, #btn2 etc.
The buttons trigger the hide/show of content contained within div tags labelled within corresponding class names such as .btn1, .btn2, etc.
For example, selecting #btn1 is tied to the content within content content content .
The process is to select a button, then whichever button is selected, hide the content within all the 100 DIVs and then show the selected button’s associated content.
In writing the JS file I have written out the whole function 100 times - listing each one of 100 buttons to be selected, all 100 div areas to be hidden, and then the one div area to be shown.
How could this be simplified into a smarter and more concise function?
// JavaScript Document
$(document).ready(function() {
$('#btn0').click(function() {
location.reload();
});
});
$(document).ready(function() {
$('#btn1').click(function() {
$('.btn0').hide();
$('.btn1').hide();
$('.btn2').hide();
$('.btn3').hide();
$('.btn4').hide();
$('.btn5').hide();
$('.btn6').hide();
$('.btn7').hide();
$('.btn8').hide();
$('.btn9').hide();
$('.btn10').hide();
$('.btn11').hide();
$('.btn11').hide();
$('.btn12').hide();
$('.btn13').hide();
$('.btn14').hide();
$('.btn15').hide();
$('.btn16').hide();
$('.btn17').hide();
$('.btn18').hide();
$('.btn19').hide();
$('.btn20').hide();
$('.btn21').hide();
$('.btn22').hide();
$('.btn23').hide();
$('.btn24').hide();
$('.btn25').hide();
$('.btn26').hide();
$('.btn27').hide();
$('.btn28').hide();
$('.btn29').hide();
$('.btn30').hide();
$('.btn31').hide();
$('.btn32').hide();
$('.btn33').hide();
$('.btn34').hide();
$('.btn35').hide();
$('.btn36').hide();
$('.btn37').hide();
$('.btn38').hide();
$('.btn39').hide();
$('.btn40').hide();
$('.btn41').hide();
$('.btn42').hide();
$('.btn43').hide();
$('.btn44').hide();
$('.btn45').hide();
$('.btn46').hide();
$('.btn47').hide();
$('.btn48').hide();
$('.btn49').hide();
$('.btn50').hide();
$('.btn51').hide();
$('.btn52').hide();
$('.btn53').hide();
$('.btn54').hide();
$('.btn55').hide();
$('.btn51').hide();
$('.btn52').hide();
$('.btn53').hide();
$('.btn54').hide();
$('.btn55').hide();
$('.btn56').hide();
$('.btn57').hide();
$('.btn58').hide();
$('.btn59').hide();
$('.btn60').hide();
$('.btn61').hide();
$('.btn62').hide();
$('.btn63').hide();
$('.btn64').hide();
$('.btn65').hide();
$('.btn66').hide();
$('.btn67').hide();
$('.btn68').hide();
$('.btn69').hide();
$('.btn70').hide();
$('.btn71').hide();
$('.btn72').hide();
$('.btn73').hide();
$('.btn74').hide();
$('.btn75').hide();
$('.btn76').hide();
$('.btn77').hide();
$('.btn78').hide();
$('.btn79').hide();
$('.btn80').hide();
$('.btn81').hide();
$('.btn82').hide();
$('.btn83').hide();
$('.btn84').hide();
$('.btn85').hide();
$('.btn86').hide();
$('.btn87').hide();
$('.btn88').hide();
$('.btn89').hide();
$('.btn90').hide();
$('.btn91').hide();
$('.btn92').hide();
$('.btn93').hide();
$('.btn94').hide();
$('.btn95').hide();
$('.btn96').hide();
$('.btn97').hide();
$('.btn98').hide();
$('.btn99').hide();
$('.btn100').hide();
$('.btn98').hide();
$('.btn99').hide();
$('.btn100').hide();
$('.btn1').show();
});
});
$(document).ready(function() {
$('#btn2').click(function() {
$('.btn0').hide();
$('.btn1').hide();
$('.btn2').hide();
$('.btn3').hide();
$('.btn4').hide();
$('.btn5').hide();
$('.btn6').hide();
$('.btn7').hide();
$('.btn8').hide();
$('.btn9').hide();
$('.btn10').hide();
$('.btn11').hide();
…………………….. BTN12 to 97 ……………………..
$('.btn98').hide();
$('.btn99').hide();
$('.btn100').hide();
$('.btn1').show();
});
});
Etc., up to 100 buttons
// JavaScript Document
Assuming you can't change the html structure, I would probably do:
$('[id^="btn"]').on('click', function() {
const id = $(this).attr('id');
$('[class^="btn"]').hide();
$(`.${id}`).show();
});
Which will listen to the click event on any element where the id starts with btn, then hide all elements where the class starts with btn, then show the element with the same class as the id that was just clicked (e.g. #btn2 click will show .btn2)
something like this.
for(let i = 0;i<=99;i++){
let btnclass= ".btn" + i;
$(btnclass).hide()
}
You can use a for loop to iterate from 0 to 100:
$(document).ready(function() {
$("#btn1").click(function() {
for (let i = 0; i <= 100; i++) {
$(`.btn${i}`).hide();
}
});
})
Full version:
// JavaScript Document
$(document).ready(function() {
$("#btn0").click(function() {
location.reload();
});
});
$(document).ready(function() {
$("#btn1").click(function() {
for (let i = 0; i <= 100; i++) {
$(`.btn${i}`).hide();
}
});
})
$(document).ready(function() {
$("#btn2").click(function() {
for (let i = 0; i <= 100; i++) {
$(`.btn${i}`).hide();
}
});
});
Common class and data attributes along with event delegation makes the code easier to maintain.
document.querySelector("#wrapper").addEventListener("click", function (event) {
var toggles = event.target.dataset.toggles;
// Hide previous selected elements
var selectedElems = document.querySelectorAll(".out.selected");
if (selectedElems.length){
selectedElems.forEach(function (elem) {
elem.classList.remove("selected");
});
}
// show the new active elements
const activeElems = document.querySelectorAll(toggles);
if (activeElems.length){
activeElems.forEach(function (elem) {
elem.classList.add("selected");
});
}
});
.out {
display: none;
}
.out.selected {
display: block;
}
<div id="wrapper">
<button id="btn1" data-toggles=".out1">1</button>
<button id="btn2" data-toggles=".out2">2</button>
<button id="btn3" data-toggles=".out3">3</button>
<button id="btn4" data-toggles=".out4">4</button>
</div>
<div class="out out1">1</div>
<div class="out out2">2</div>
<div class="out out3">3</div>
<div class="out out4">4</div>
If you want to use jQuery
$("#wrapper").on("click", "[data-toggles]", function (event) {
var toggles = $(this).data('toggles');
$(".out.selected").removeClass("selected");
$(toggles).addClass("selected");
});
.out {
display: none;
}
.out.selected {
display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrapper">
<button id="btn1" data-toggles=".out1">1</button>
<button id="btn2" data-toggles=".out2">2</button>
<button id="btn3" data-toggles=".out3">3</button>
<button id="btn4" data-toggles=".out4">4</button>
</div>
<div class="out out1">1</div>
<div class="out out2">2</div>
<div class="out out3">3</div>
<div class="out out4">4</div>

How to add a transition when styling display? [duplicate]

This question already has answers here:
Transitions on the CSS display property
(37 answers)
Closed 1 year ago.
I have a program, where I use JavaScript to make one div appear and another disappear when I click something:
<div id="first" class="active"> some content here </div>
<div id="second" class="inactive"> some content here </div>
<button onclick="change()"> button </button>
function change(){
document.getElementById("first").className="inactive";
document.getElementById("second").className="active"
}
.active{ display: block; }
.inactive{display: none; }
I'd like to make it so that one div fades in while the other fades out.
I've tried transition: ease 1s;, transition: display 1s and using a custom transition, however none of them have worked.
Try clicking the different buttons on this Carrd - the words fade in and out. I'm going for that effect here.
I'd prefer a solution using only HTML, CSS and/or JavaScript -- trying to keep this project simple.
Use opacity:
function change() {
document.getElementById("first").className = "inactive";
document.getElementById("second").className = "active"
}
.active{
opacity:1;
}
.inactive{
opacity:0;
}
div{
transition:opacity 1s;
}
<div id="first" class="active"> some content here </div>
<div id="second" class="inactive"> some content here </div>
<button onclick="change()"> button </button>
To prevent the hidden element from taking up space, use:
function change() {
const f1 = document.getElementById("first");
f1.style.opacity = "0";
setTimeout(() => {
f1.style.display = "none"
const f2 = document.getElementById("second");
f2.style.display = "block";
setTimeout(() => {
f2.style.opacity = "1";
}, 50);
}, 1000);
}
.active {
display: block;
opacity: 1;
}
.inactive {
display: none;
opacity: 0;
}
div {
transition: opacity 1s;
}
<div id="first" class="active"> some content here </div>
<div id="second" class="inactive"> some content here </div>
<button onclick="change()"> button </button>

Displaying show/hide content with a button and an .active css class

I am trying to create a testimonial section on a wordpress site where there is an "expand" button to show the full testimonial quote. I want the text in the button to change to "collapse" after it is clicked. I also need to add a class to the div wraper so I can implement custom css styling when the button is active. I need this pasted three times. The problem is it fails after the first testimonial.
I have this working with the code below, with it duplicated three times (for three different testimonials) and it works on a basic html document. But when I implement it in a wordpress site by pasting the code, only the first testimonial totally works. The other two do show/hide my inner div element, but they won't insert the .active class or change the text of the button to "collapse"
Both of the second testimonials give a
"Uncaught TypeError: Cannot set property 'innerHTML' of null" in the console.
So for example, here are two out of three of my testimonials I want to show. I have to change the ID's on them to avoid the javascript conflict.
function showhide() {
var content = document.getElementById('hidden-content');
var wrap = document.getElementById('testimonial-wrap');
var btn = document.getElementById('button1');
if (content.style.display === 'none') {
content.style.display = 'block';
wrap.style.background = 'grey';
btn.innerHTML = 'COLLAPSE';
wrap.classList.add('active');
} else {
content.style.display = 'none';
wrap.style.background = 'white';
btn.innerHTML = 'EXPAND';
wrap.classList.remove('active');
}
}
function showhide2() {
var content2 = document.getElementById('hidden-content2');
var wrap2 = document.getElementById('testimonial-wrap2');
var btn2 = document.getElementById('button2');
if (content2.style.display === 'none') {
content2.style.display = 'block';
wrap2.style.background = 'grey';
btn2.innerHTML = 'COLLAPSE';
wrap2.classList.add('active');
} else {
content2.style.display = 'none';
wrap2.style.background = 'white';
btn2.innerHTML = 'EXPAND';
wrap2.classList.remove('active');
}
}
<div id="testimonial-wrap" style="background-color: white;">
<div id="testimonial">
above testimonial content
<div id="hidden-content" style="display: none;">
<p>"hidden content”</p>
</div>
<button id="button1" onclick="showhide()">EXPAND</button>
</div>
</div>
<div id="testimonial-wrap2" style="background-color: white;">
<div id="testimonial">
above testimonial content
<div id="hidden-content2" style="display: none;">
<p>"hidden content.”</p>
</div>
<button id="button2" onclick="showhide2()">EXPAND</button>
</div>
</div>
I think this is what you're looking for. You can do it much easier with jQuery & a small amout of code.
I didn't use display: none as I want to add the transition to the action. (transition won't work with display: none)
$(document).ready(function() {
$(".toggle-button").on("click", function() {
$(this).closest(".testimonial-wrap").toggleClass("active");
});
});
.testimonial-wrap {
background-color: #C1C1C1;
padding: 5px;
margin-bottom: 10px;
}
.testimonial-wrap.active {
background-color: #0095FF
}
.hidden-content {
height: 0px;
visibility: hidden;
transition: all 0.5s ease-out;
}
.active .hidden-content {
height: 100px;
visibility: visible;
transition: all 0.5s ease-in;
background-color: rgba(0, 0, 0, 0.5);
}
button {
display: inline-block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="testimonial-wrap">
<div id="testimonial">
<p>above testimonial content</p>
<div class="hidden-content">
<p>"hidden content”</p>
</div>
<button id="button1" class="toggle-button">EXPAND</button>
</div>
</div>
<div class="testimonial-wrap">
<div id="testimonial">
<p>above testimonial content</p>
<div class="hidden-content">
<p>"hidden content.”</p>
</div>
<button id="button2" class="toggle-button">EXPAND</button>
</div>
</div>

TOGGLE 2 DIVS with a Button (Using Javascript, HTML and CSS)

Basically I have 2 divs both with different contents inside and I'd like to toggle between them with a button.
I have here my 2 divs with class "step1Content" and "step2Content" respectively.
<div class = 'step1Content'> Content1 </div>
<div class = 'step2Content'> AnotherContent </div>
I gave step1Content the style display: block.
.step1Content { display: block; }
I gave step2Content the style display: none.
.step2Content { display: none; }
I have a button that would toggle between these 2 to show or hide.
<button onclick = 'step2()'>2. Taskeros and Prices</button>
And my javascript function:
function step2(){
document.getElementByClassName('step1Content').style.display = 'none';
document.getElementByClassName('step2Content').style.display = 'block';
}
You'd think the results would be a okay right? Nope, when I click the button it does literally nothing. I have no idea why, any help with this?
Keep in mind that
getElementsByClassName
will return a collection of all elements in the document with the specified class name, as a NodeList object.
You can either use getElementById or querySelector
Here's a working solution. Hope it helps!
function step2(){
if(document.querySelector('.step1Content').style.display === "none"){
document.querySelector('.step2Content').style.display = 'none';
document.querySelector('.step1Content').style.display = 'block';
}else{
document.querySelector('.step1Content').style.display = 'none';
document.querySelector('.step2Content').style.display = 'block';
}
}
.step1Content { display: block; }
.step2Content { display: none; }
<button onclick = 'step2()'>2. Taskeros and Prices</button>
<div class= 'step1Content'> Content1 </div>
<div class = 'step2Content'> AnotherContent </div>
The function is getElementsByClassName not getElementByClassName and it returns array-like collection of elements. so you need to use index 0 here for the first element.
function step2(){
var element=document.getElementsByClassName('step1Content');
element[0].style.display = (element[0].style.display ==='none') ? 'block' : 'none';
var element1= document.getElementsByClassName('step2Content');
element1[0].style.display = (element1[0].style.display ==='block') ? 'none' : 'block';
}
.step1Content { display: block; }
.step2Content { display: none; }
<div class = 'step1Content'> Content1 </div>
<div class = 'step2Content'> AnotherContent </div>
<button onclick = 'step2()'>2. Taskeros and Prices</button>
If you want to toggle visibility of div then you can use j-query toggle function.
Please read http://api.jquery.com/toggle/
$("button").click(function(){
$("#shay").toggle();
});
For Toggling two div -
CSS - .show { display: block; } .hide { display: none; }
$("button").click(function(){
$('#div1').toggle();
$('#div2').toggle();
});
</script>
<body>
<div class="hide" id="div1">Hi Div1</div>
<div class="show" id="div2">Hi Div2</div>
<button>Click me</button>
You can use Array.prototype.reverse() to toggle display of div elements
.step1Content {
display: block;
}
.step2Content {
display: none;
}
<button onclick='step2()'>2. Taskeros and Prices</button>
<div class='step1Content'>Content1</div>
<div class='step2Content'>AnotherContent</div>
<script>
var divs = Array.from(document.querySelectorAll("div[class^=step]"));
function step2() {
divs[0].style.display = "none";
divs[1].style.display = "block";
divs.reverse();
}
</script>

Change visibility of Node when User scrolls to it with CSS

If I have something like this:
<br><br><br>...Lots of BRs...<br><br><br>
<div id="thetarget"></div><div id="show"></div>
<br><br><br>...Lots of BRs...<br><br><br>
I want to show the #show when user scroll to the #thetarget OR/and to manipulate with css styles of the #thetarget when user scroll to it, but without "click interaction" of the user as it normally would with the target
Is this even possible with only css code?
If it's not, how can I make this with javascript(not jquery) so it won't be impact on performance at all(=tiny affect)?
Thank you
You could also do this with pure JS
window.onscroll = function() {
var show = document.getElementById('show');
if (this.pageYOffset > 100) {
show.style.display = 'block';
} else {
show.style.display = 'none';
}
}
#thetarget {
height: 1000px;
}
#show {
display: none;
position: fixed;
z-index: 1;
bottom: 0;
}
<div id="thetarget">
<h1>Keep scrolling</h1>
</div>
<div id="show">
<h1>Revealed</h1>
</div>

Categories