Javascript DOM issue. (getElementsByClassName) [duplicate] - javascript

This question already has answers here:
What do querySelectorAll and getElementsBy* methods return?
(12 answers)
Closed 7 years ago.
I have 3 divs , the first one is with id , the second two with same class. I've written an EventListeners with javascript for these 3 divs. The eventlistener for my first div , which is related with an ID works , but the second function which is related to getElementsByClassName() doesn't work. Here's my code
document.addEventListener("DOMContentLoaded", function() {
var firstElement = document.getElementById('firstOne');
firstOne.addEventListener('mouseout', function() {
this.style.backgroundColor = 'red';
this.style.border = '5px outset #00FF1E';
});
var secondElements = document.getElementsByClassName('secondOne');
secondElements.addEventListener('click', function() {
for (var i = 0; i < secondElements.length; i++) {
secondElements[i].style.backgroundColor = 'red';
}
});
});
#firstOne {
height: 240px;
width: 240px;
border: 5px solid blue;
background-color: orange;
display: inline-block;
}
.secondOne {
height: 240px;
width: 240px;
border: 5px solid green;
background-color: skyblue;
display: inline-block;
}
<div id="firstOne"></div>
<div class="secondOne"></div>
<div class="secondOne"></div>

document.getElementsByClassName returns a NodeList. Since you are doing secondElements.addEventListener, it will throw an error
because you cannot attach events to a NodeList. You always attach events to a Node.
To fix this, loop over the elements of the NodeList using a for-loop (or a .apply-forEach combo if you are comfortable with that), and attach event listener individually.
document.getElementById always returns a Node (since there can only be one element with a particular id in the DOM) and so firstOne.addEventListener works.
Code sample:
var secondElements = document.getElementsByClassName('secondOne');
for(var i = 0, len = secondElements.length, elm; i < len; i++){
elm = secondElements[i];
elm.addEventListener('click', your_handler_function_here);
}

getElementsByClassName() return an array-like object of all child elements which have all of the given class names.
use for() to loop it, and add click event;
var secondElements = document.getElementsByClassName('secondOne');
for (var i=0;i<secondElements.length; i++) {
secondElements[i].addEventListener('click',function(){
for(var i = 0; i < secondElements.length ; i++){
secondElements[i].style.backgroundColor = 'red';
}
});
}
demo http://jsfiddle.net/yqec6aqs/

Related

cannot change class of <img> tag

I'm trying to find all tags on the page and change their class from 'multiimage' to 'mySpace' but i cannot see any changes on the page and when I log this elemets into console I can see ther className set as 'multiimage'.
My code:
window.onload = function(){
// to store all <img> elements
var arrayOfMultiImages = new Array();
var multiImageNumber = document.getElementsByClassName("multiimage").length;
// store <img> tag in array
for(var i = 0; i < multiImageNumber; i++){
arrayOfMultiImages.push(document.getElementsByClassName("multiimage")[i]);
}
// change className of <img> elements
for(var x = 0; x < multiImageNumber.length; x++){
arrayOfMultiImages[x].className = "mySpace";
}
// cannot see any changes
console.log(arrayOfMultiImages);
};
Don't you have any idea what is wrong there?
multiImageNumber variable is already a number, following line of code doesn't have any kind of sense:
for(var x = 0; x < multiImageNumber.length; x++){
Another case - document.getElementsByClassName() returns an array-like object, containing all elements with specified class. There's no need to iterate over it and push every single element into a new array.
If you want to change an array-like object into an array, use Array#from.
It's a build-in function, coming from ES6.
var arrayOfMultiImages = document.getElementsByClassName('multiimage');
var array = Array.from(arrayOfMultiImages);
Once you have changed your array-like object into an array, you can use e.g. Array#forEach function to simply and quickly iterate over it's elements.
array.forEach(elem => elem.className = "mySpace")
Simple example:
let elems = document.getElementsByClassName('box');
Array.from(elems).forEach(v => v.className = 'mySpace');
.box {
background: blue;
height: 100px;
width: 100px;
}
.mySpace {
background: green;
height: 100px;
width: 100px;
margin: 5px;
}
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
You can simplify this code by looping through the collection returned by getElementsByClassName(), then change the className from that loop.
var multiImageNumber = document.getElementsByClassName("multiimage");
for (var x = 0; x < multiImageNumber.length; x++) {
multiImageNumber[x].className = "mySpace";
}
.mySpace {
border: 1px solid red;
}
<img src="http://kenwheeler.github.io/slick/img/fonz1.png" class="foo">
<img src="http://kenwheeler.github.io/slick/img/fonz1.png" class="multiimage">
<img src="http://kenwheeler.github.io/slick/img/fonz1.png" class="bar">

Position of clicked element (no jQuery)

In my example fiddle I get the .innerText of my clicked Element. How can I get on this way (or a better?) the index of my clicked item?
Without jQuery would be awesome because I want to learn living without jQuery :D
var el = document.getElementsByClassName("lol");
for(var i = 0; i < el.length; i++ ) {
el[i].addEventListener("click", function(e) {
console.log(e.target.innerText)
});
}
https://jsfiddle.net/y6s8c1y8/2/
getElementsByClassName Returns an array-like object of all child elements which have all of the given class names. As we are suppose to use Array#indexOf method, input has to be array
Use Array#from, it creates a new Array instance from an array-like or iterable object.
Use Array#indexOf to get the index of element
var el = document.getElementsByClassName("lol");
var arrElems = Array.from(el);
//Or var arrElems = [].slice.call(el);
for (var i = 0; i < el.length; i++) {
el[i].addEventListener("click", function(e) {
console.log("text is: " + e.target.innerText);
console.log("Index is: " + arrElems.indexOf(e.target));
});
}
.lol {
width: 100px;
height: 100px;
background: #000;
float: left;
margin-right: 5px;
}
<div class="lol">
1
</div>
<div class="lol">
2
</div>
<div class="lol">
3
</div>
<div class="lol">
4
</div>
Fiddle Demo

How to write css code in javascript? (Uncaught TypeError: Cannot set property "height" of undefined)

How to write css code in javascript? (Uncaught TypeError: Cannot set property "height" of undefined)
javascript
document.getElementById("slideshow").getElementsByClassName("arrow").style.height = "86px";
css
#slideshow .arrow{
height:86px;
width:60px;
position:absolute;
background:url('arrows.png') no-repeat;
top:50%;
margin-top: -43px;
cursor: pointer;
z-index: 5000;
}
The key here is the pluralisation of getElementsByClassName - elements. This method returns an array-like object of elements, not just one element.
To apply the style to each, you need to loop through this array-like object and add the styles to each individual element returned:
var elems = document.getElementById("slideshow").getElementsByClassName("arrow");
for (var i = 0; i < elems.length; i++)
elems[i].style.height = "86px";
document.getElementsByClassName returns an array.
You have to loop through it, or if you know the index, do this:
document.getElementById("slideshow").getElementsByClassName("arrow")[0].style.height = "86px";
or
document.getElementById("slideshow").getElementsByClassName("arrow")[i].style.height = "86px";
i being your loop variable.
A bit of theory:
Changing HTML Style
To change the style of an HTML element, use this syntax:
document.getElementById(id).style.property=new style
Here is the example:
// JavaScript demonstration
var changeBg = function (event) {
console.log("method called");
var me = event.target
, square = document.getElementById("square");
square.style.backgroundColor = "#ffaa44";
me.setAttribute("disabled", "disabled");
setTimeout(clearDemo, 2000);
}
function clearDemo(button) {
var square = document.getElementById("square");
square.style.backgroundColor = "transparent";
button.removeAttribute("disabled");
}
var button = document.querySelector("button");
button.addEventListener("click", changeBg);
console.log(button);
#square {
width: 20em;
height: 20em;
border: 2px inset gray;
margin-bottom: 1em;
}
button {
padding: .5em 2em;
}
<h1>JavaScript sample</h1>
<div id="square"></div>
<button>Click Me</button>
JavaScript-Based Style Sheets - http://www.w3.org/Submission/1996/1/WD-jsss-960822
Mozzila's Web Developer guide - https://developer.mozilla.org/en-US/docs/Web/Guide/CSS/Getting_started/JavaScript
While I've started with explanation and theory #James Donnelly already provided my answer, which I've wanted to use:
var elements = document.getElementById("slideshow").getElementsByClassName("arrow");
for (var i = 0; i < elems.length; i++) {
elems[i].style.height = "86px";
.
As someone already pointed out,
document.getElementsByClassName returns an array (N Objects)
while
document.getElementById returns an element (ONE object)
This is because N elements can have the same class but only ONE item can have a particular ID.
Since you can't edit more items' attribute at once, you must cycle them and edit the attribute of each one by one
document.getElementById("slideshow").getElementsByClassName("arrow")[0].style.height = "86px";
document.getElementById("slideshow").getElementsByClassName("arrow")[1].style.height = "86px";
document.getElementById("slideshow").getElementsByClassName("arrow")[2].style.height = "86px";
.....
document.getElementById("slideshow").getElementsByClassName("arrow")[N].style.height = "86px";
This can be achieved by using a for cycle or a each one.

how can I detect the css value with jquery? [duplicate]

This question already has answers here:
Can jQuery get all CSS styles associated with an element?
(5 answers)
Closed 8 years ago.
Suppose in my style sheet:
.test{width: 20px; height: 50px; color: blue;}
.some-test{padding: 20px; margin: 10px;}
.even-test{font-size: 20px; color: red;}
Is it possible to detect the 20px value of each css properties so that I could replace it?
I'm supposing to detect something like this:
$('.selector').filter(function() {
return $(this).css(property) === '20px';
}).css(property, value);
Isn't there anything something like: style.arguments[] ?
You can use the filter function in jQuery to find all elements that have that width.
$('.allYourSelectors').filter(function() {
return $(this).css('width') === '20px';
}).css("width", newWidth);
However, it would be much better to just give them all the same class that you can modify.
To search through CSS styles (not sure if this gets style="..." styles):
var parseStyle = function(rules) {
for (var i = 0; i < rules.length; ++i)
{
console.log(rules[i].style.width);
}
};
//care needs to be taken as to when this executes - styles may not have been loaded yet
for (var i = 0; i < document.styleSheets.length; ++i)
if (document.styleSheets[i].rules && document.styleSheets[i].rules.length > 0)
parseStyle(document.styleSheets[i].rules);
If it's not the CSS properties you want but the result of the style on an element, this might be more what you're after...
var element = ... jquery or whatever
var elementStyle = element.currentStyle || getComputedStyle(element);
console.log(elementStyle.width);

Add CSS Class Property through Javascript

I have an HTML page having css class for a control with following definition:
.ms-crm-Inline-Edit select.ms-crm-SelectBox {
border: 1px solid #CCCCCC;
font-size: 12px;
margin: 1px 0 0 1px;
width: 100%;
}
I need to add a new attribute to this class as follows:
height: "120px !important";
This has to be done through Javascript. I can't modify origional class definition that's why I have to add Javascript function which does this job. For that purpose I have written Jscript method but its not working.
function CustomizePicklistHeight ()
{
document.getElementsByClassName('ms-crm-Inline-Edit select.ms-crm-SelectBox').style.height = '120px !important';
}
I guess, first we have to add height attribute to this class but I dont know how to do that in JScript. Please suggest.
document.getElementsByClassName returns an array of all items with that class.
Try this:
function CustomizePicklistHeight()
{
// Store elements for each class differently. Just in case :)
var elements1 = document.getElementsByClassName('ms-crm-Inline-Edit');
var elements2 = document.getElementsByClassName('ms-crm-SelectBox');
// Since you cant affect the array directly, you use a loop to do the operation on each individual element
for (var i = 0; i < elements1.length; i++)
{
element1[i].style.height = '120px !important';
};
for (var j = 0; j < elements2.length; j++)
{
element1[j].style.height = '120px !important';
};
}​
Hope this helps.. :)
var matches = document.querySelectorAll(".ms-crm-Inline-Edit, select.ms-crm-SelectBox");
for(i=0; i<matches.length; i++)
{
matches[i].style.height = '120px !important';
}
Reference: https://developer.mozilla.org/en-US/docs/Web/API/Document.querySelectorAll
ClassName means "class name" (ms-crm-SelectBox) not "Entire selector". (querySelector and querySelectorAll let you use complete selectors though.
Elements means "elements" (plural) not "Element". It returns a NodeList, which you can loop over like an array.
If, on the other hand, you want to the modify the CSS rule-set instead of the styles applied directly to the HTML elements, then you need to look at document.styleSheets instead.
you will have to make a loop by setting each item, and if you have not "! important" earlier you do not need it.

Categories