getElementsByClassName doesn't work - javascript

I try to hide some HTML elements onload and then show and manipulate them. The code works fine when I use element's individual IDs with getElementById() method. But when I try to do it more efficiently using the classes, it doesn't work. Here is the code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
</head>
<body onload="HideModals()">
<p id="p1" class="MyModal99">1. I will disappear or not.</p>
<p id="p2" class="MyModal99">2. I will disappear or not.</p>
<button id="toggle">Toggle</button>
<button id="hide">Hide</button>
<script>
$(document).ready(function(){
$("#toggle").click(function(){
$("#p1").toggle();
});
$("#hide").click(function(){
$("#p2").hide();
});
});
</script>
<script>
function HideModals() {
//document.getElementById("p1").style.display = 'none';
//document.getElementById("p2").style.display = 'none';
document.getElementsByClassName("MyModal99").style.display = 'none';
}
</script>
</body>
</html>

You cannot apply properties in bulk like that. This is why using jQuery is preferred for things like this:
$('.MyModal99').css('display', 'none');
If you want to do this without jQuery:
var nodes = document.getElementsByClassName("MyModal99");
for(var i = 0; i < nodes.length; i++) {
nodes[i].style.display = 'none';
}

It's because getElementsByClassName() returns an array-like object of elements. You need to access a specific element in order to change the style object.
You could iterate over the elements:
var elements = document.getElementsByClassName("MyModal99");
Array.prototype.forEach.call(elements, function (el) {
el.style.display = 'none';
});
or:
var elements = document.getElementsByClassName("MyModal99");
for (var i = 0; i < elements.length; i++) {
elements[i].style.display = 'none';
}

document.getElementsByClassName returns an array, which doesn't have a "style" property. You need to iterate over the array:
function HideModals() {
//document.getElementById("p1").style.display = 'none';
//document.getElementById("p2").style.display = 'none';
var modals = document.getElementsByClassName("MyModal99");
for (var i=0; i < modals.length; i++) {
modals[i].style.display = 'none';
}
}

The issue here is that document.getElementsByClassName("MyModal99") returns a list of items, so you'd have to loop through them and apply your properties one at a time. Something like this:
var elements = document.getElementsByClassName("MyModal99");
for ( var e in elements ) {
e.style.display = "none";
}
If you need to support older browsers, do it the old fashioned way without a for..in loop:
var elements = document.getElementsByClassName("MyModal99");
for ( var i = 0 ; i < elements.length ; ++i ) {
elements[i].style.display = "none";
}

Thats because document.getElementsByClassName returns an array of nodes. You need to iterate each of the returned nodes to set their styles individually.
var eleArray = document.getElementsByClassName('MyModal99');
for(var i = 0; i < eleArray.length; i++) {
eleArray[i].style.display = 'none';
}

You can use a for loop to cycle through all of the elements in the collection returned by getElementsByClassName like this:
var results = document.getElementsByClassName("MyModal99");
for (var i = 0; i < results.length; i++) {
results[i].style.display = 'none';
}
working demo: http://jsfiddle.net/gratiafide/3qg308bq/2/

I had difficulties with this code because I didn't know how to name jQuery functions. Now i know. Here is the corrected code:
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js">
</script>
</head>
<body onload="HideModals()">
<p id="p1" class="MyModal99">1. I will disappear or not.</p>
<p id="p2" class="MyModal99">2. I will disappear or not.</p>
<button id="toggle">Toggle</button>
<button id="hide">Hide</button>
<script>
$(document).ready(function(){
$("#toggle").click(function(){
$("#p1").toggle(100);
});
$("#hide").click(function(){
$("#p2").hide(100);
});
});
function HideModals() {
$('.MyModal99').css('display', 'none');
}
</script>

Related

dynamically add EventListener doesn't work as expected

When I try to dynamically fill a wrapper element with HTML elements, and then add an EventListener for that element, it only uses the last value.
window.onload=function(){
sW="";
for(var i = 0; i < 5; i++) {
var e = document.createElement('div');
e.innerHTML = "test div number "+i;
e.addEventListener('click', function() {alert("t:"+i);});
document.getElementById('wrap').appendChild(e);
}
}
<html>
<body>
<div id="wrap"></div>
</body>
</html>
That's because var keeps the the reference to the variable. Use let instead.

Can't change style : display using getelementbyclassname

document.getElementByClassName('xyz').style.display = 'none';
I am unable to hide class content.
document.getElementsByClassName return an array like object. you can use following script for this
document.getElementsByClassName('xyz')[0].style.display = 'none';
or if you want to hide all .xyz element
var x = document.getElementsByClassName("xyz");
var i;
for (i = 0; i < x.length; i++) {
x[i].style.display = 'none';
}
function show(){
var element = document.getElementsByClassName('elem');
console.log(element);
element[0].style.display = 'block';
}
.elem {
display: none;
}
<div> visible
<div class="elem">hidden
</div>
<button type="button" onclick="show()">click</button>
</div>
getElementsByClassName returns an array, you can't directly set the style of element like it.
You need to do something like:
let elem = document.getElementsByClassName('xyz')[0];
elem.style.display = 'none';
document.getElementsByClassName elements is a live HTMLCollection of found elements.
<div class="xyz">
test content
</div>
<button type="button" onclick="document.getElementsByClassName('xyz')[0].style.display = 'none';">Hide Content </button>
<button type="button" onclick="document.getElementsByClassName('xyz')[0].style.display = '';">Show Content </button>
$("#afficher_commentaire").change(function(){
// alert("OK");
if($(this).prop("checked") == true){
var commentaire_date_fin_fourniture = document.getElementsByClassName("commentaire_date_fin_fourniture");
for (var i = 0; i < commentaire_date_fin_fourniture.length; i++) {
commentaire_date_fin_fourniture[i].style.display='block';
}
}
else if($(this).prop("checked") == false){
var commentaire_date_fin_fourniture = document.getElementsByClassName("commentaire_date_fin_fourniture");
for (var i = 0; i < commentaire_date_fin_fourniture.length; i++) {
commentaire_date_fin_fourniture[i].style.display='none';
}
}
});
Working version
hide = function(){
document.getElementsByClassName('xyz')[0].style.display="none";
}
<input class="xyz" type="text"/>
<button onclick="hide();">Click to hide!</button>
If you really want to do things this way, then of course first you need to spell getElementsByClassName correctly; you saw this error in the console, right? Then, you need to know that getElementsByClassName returns an array-like things; you saw that in the documentation, right? So you have to loop over it, or take the first element with [0], or whatever.
But in general, it's bad practice to retrieve elements from the DOM like this and set their styles directly. Instead, take advantage of CSS, which will do 90% of the work for you. Here, I'd use a single higher-level class which controls the behavior, and just set that:
<main id="main">
<div class="xyz"></div>
<main>
Then write your CSS as
main.hide-xyz .xyz { display: none; }
To hide the xyz element, then you need a single JS statement:
document.getElementById("main").classList.add("hide-xyz");
To remove it:
document.getElementById("main").classList.remove("hide-xyz");
Or toggle it:
document.getElementById("main").classList.toggle("hide-xyz");
Once you wrap your head around this style, you'll find yourself writing much less JavaScript that needs to all kinds of DOM lookups and loops and setting of styles.
document.getElementsByClassName always returns an array like object. Specify the array[0] number.
Typescript
let hiddenLocales = document.getElementsByClassName('localeMatch') as HTMLCollectionOf<HTMLElement>;
let hideParentNode = hiddenLocales[0]?.parentElement;
hideParentNode?.remove(); // Remove the element
hideParentNode?.style.display = "none"; // Hide the element

Hide Multiple Elements in html using javascript

I'd like to show/hide multiple ID of elements.
I have a problem with the javascript in my HTML file.
Here's the javascript:
<Script type="text/javascript" language="JavaScript"><!--
function HideContent(d){
document.getElementById(d).style.display = "none";
}
function ShowContent(d){
document.getElementById(d).style.display = "block";
}
//--></script>
And my HTML:
<div class = "left" id="colsxmenu">
<ul>
<li> ENGLISH
<li>FRENCH
Actually, if I select ENGLISH it works good hiding the colsxmenu, but what I need is if I select FRENCH it should hide more than only 1 elements.
I tried to add ('colsxmenu';'colsxmenu2'), but that didn't works.
You can pass an array of elements to your function
<div id="first">first</div>
<div id="second">second</div>
ENGLISH
<script>
function HideContent(obj) {
for (var i = 0; i < obj.length; i++) {
document.getElementById([obj[i]]).style.display = 'none';
}
}
</script>
Define your HideContent function to accept variable number of argument. It should be some thing like below to hide multiple elements.
<script>
function HideContent() {
if (arguments.length > 0){
for(var i=0; i < arguments.length; i++{
document.getElementById(arguments[i]).style.display = "none";
}
}
}
</script>
After that you can call it like
HideContent('colsxmenu');
HideContent('colsxmenu', 'uniqename');

How to select every element in an element list

I'm a beginner programmer and I am trying to select every element in a class array to style them. I have tried using the generic selector * but this has not worked and I have not found a suitable solution. eg.
var link = document.getElementsByClassName;
link[*].style.color = "#eee";
From https://developer.mozilla.org/en/docs/Web/API/Document/getElementsByClassName
[document.getElementsByClassName] returns an array-like object of all child elements which have all of the given class names.
You need to specify what class to select, and then you'd have to iterate over each element in the returned array.
Suppose you have this HTML:
<p class="foo">Hello</p>
<p class="foo">World</p>
Then you'd need something like this in JavaScript:
var foo_items = document.getElementsByClassName("foo");
for(var i = 0; i < foo_items.length; i++) {
foo_items[i].style.color = "#eee";
}
Of course, if you're using jQuery, this could be simplified to
$(".foo").css("color", "#eee")
Try using jquery loop or javascript loop. In jquery use $.each loop to parse through the loop elements and apply style to each element. I have added a sample code here using javascript and jQuery.
jQuery implementation.
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.1.1.min.js"></script>
</head>
<body>
<p class="itemclass">Element 1.</p>
<p class="itemclass">Element 2.</p>
<p class="itemclass">Element 3.</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
var items = document.getElementsByClassName("itemclass");
$.each(items, function(index, item){
item.style.backgroundColor = "red";
});
}
</script>
</body>
</html>
Javascript Implementation
<!DOCTYPE html>
<html>
<body>
<p class="itemclass">Element 1.</p>
<p class="itemclass">Element 2.</p>
<p class="itemclass">Element 3.</p>
<button onclick="myFunction()">Try it</button>
<script>
function myFunction() {
var items = document.getElementsByClassName("itemclass");
var loopVar = 0;
var loopLength = items.length;
for(loopVar = 0; loopVar < loopLength; loopVar++){
items[loopVar].style.backgroundColor = "red";
}
}
</script>
</body>
</html>
Try this in your browser console.
function getAllLinks() {
return document.getElementsByTagName('a')
}
var links = getAllLinks()
function colorElements(elements, value) {
for(var i = 0; i < elements.length; i++) {
elements[i].style.color = 'red';
}
}
colorElements(links, 'red')
Code above should fetch all the links on the page and color them red.
Now with better ES6+
// this code requires links from the code above
var allLinks = Array.from(links)
allLinks.forEach(link => link.style.color = 'green')
Code above should take all the links on the page and color them green.
Advice: Do not touch browser or users anchor colors for accessibility reasons.

Showing hidden div if checkbox is checked

I have two checkboxes. The checkBoxValidate function triggered by "onclick" assures that the two checkboxes cannot be both selected at the same time. The showMe function, also triggered by "onclick", displays a hidden div when check box is clicked. Everything just fine.
The problem:
When clicking on checkbox1 and then on checkbox2, the div triggered by checkbox1 is not automatically hidden. The idea is than when a checkbox is not selected the div triggered by it should not be visible... Please look at the demo.
Thank you!
DEMO:
http://jsbin.com/iNuPAREq/1/edit?html,js,output
HTML:
<form action="whatever" name="comanda11" method="post" onsubmit="return validate(this)">
<input type="checkbox" name="c1" onclick="showMe('content1'); checkBoxValidate(0);">
<input type="checkbox" name="c1" onclick=" showMe('content2'); checkBoxValidate(1);">
<div id="content1" style="display:none">
Content 1
</div>
<div id="content2" style="display:none">
Content 2
</div>
</form>
JS:
function showMe(box) {
var chboxs = document.getElementsByName("c1");
var vis = "none";
for (var i = 0; i < chboxs.length; i++) {
if (chboxs[i].checked) {
vis = "block";
break;
}
}
document.getElementById(box).style.display = vis;
}
function checkBoxValidate(cb) {
for (j = 0; j < 8; j++) {
if (eval("document.comanda11.c1[" + j + "].checked") == true) {
document.comanda11.c1[j].checked = false;
if (j == cb) {
document.comanda11.c1[j].checked = true;
}
}
}
}
change the markup to use radio buttons, and remove the inline javascript:
<form action="whatever" name="comanda11" method="post">
<input type="radio" name="c1" data-rel="content1" />
<input type="radio" name="c1" data-rel="content2" />
<div id="content1" style="display:none">Content 1</div>
<div id="content2" style="display:none">Content 2</div>
</form>
then do
var elems = document.getElementsByName('c1');
for (var i=elems.length; i--;) {
if (elems[i].addEventListener) {
elems[i].addEventListener ('change',fn,false);
}else if (elems[i].attachEvent) {
elems[i].attachEvent ('onchange',fn);
}
}
function fn() {
var rel = this.getAttribute('data-rel');
document.getElementById(rel=='content1'?'content2':'content1').style.display = 'none';
document.getElementById(rel).style.display = 'block';
}
FIDDLE
If you just have to use checkboxes, here's a working solution:
var elems = document.getElementsByName('c1');
for (var i=elems.length; i--;) {
if (elems[i].addEventListener) {
elems[i].addEventListener ('change',fn,false);
}else if (elems[i].attachEvent) {
elems[i].attachEvent ('onchange',fn);
}
}
function fn() {
var rel = this.getAttribute('data-rel');
for (var i=elems.length; i--;) {
if (elems[i] != this) elems[i].checked = false;
var id = elems[i].getAttribute('data-rel');
document.getElementById(id).style.display = elems[i].checked ? 'block' : 'none';
}
}
FIDDLE
Not an elegant solution but it works for your situation
function showMe (box) {
var chboxs = document.getElementsByName("c1");
var vis = "none";
document.getElementById("content1").style.display = "none";
document.getElementById("content2").style.display = "none";
for(var i=0;i<chboxs.length;i++)
{
if(chboxs[i].checked)
{
vis = "block";
break;
}
}
document.getElementById(box).style.display = vis;
}
The simplest way to get this to behave correctly is to set all divs to hidden before setting the div selected to block.
var divs = [document.getElementsByName("content1"),document.getElementsByName("content2")];
for(var i=0; i < divs.length; i++_ {
divs[i].style.display = 'none'
}
The above code should go above
document.getElementById(box).style.display = vis;
Note that There are much better ways to work with DOM elements. I would recommend looking into jQuery as a much simpler way of doing this. Also, manually building an array of two div elements is not the best way to do this, but I don't want to risk grabbing other divs that might be in your document.
In this situation, I set a global variable to the div being displayed at the time it is "unhidden". lets call it "lastdiv" as an example.
var lastdiv=false;
function showme(){
if(lastdiv){lastdiv.style.display='none';}
lastdiv=?????? // your code to find the div to unhide
lastdiv.style.display='block';
}
You have lots of other issues in your code to work out including the use of eval in a situation where it is clearly not warranted. There are better ways to do it without using eval.

Categories