Position of clicked element (no jQuery) - javascript

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

Related

How to use html tag inside a java script?

I want to display elements like this I'm creating an array and pushing some numbers into that array using javascript. After pushing a number I'm trying to use a html tag which displays that number inside a circle. But I'm facing trouble while doing that.
This is my javascript for pushing elements into array:
data.push(5);
data.push(6);
data.push(4);
Now the array will consists of the elements 5,6,4. Now I want to display these elements using some html tag.
The html tag I'm using to display these elements are:
<span class="w3-badge">5</span>
<span class="w3-badge">6</span>
<span class="w3-badge">4</span>
Then these elements will display in a circle. This is static because I'm giving numbers in the html tags.Actually I want to load these numbers using javascript.
I'm trying in this way,but it is not working:
"<span class="w3-badge">"data.push(5);"</span>"
"<span class="w3-badge">"data.push(6);"</span>"
"<span class="w3-badge">"data.push(5);"</span>"
Can Someone help me with this???
Are you filling this HTML with javascript?
"<span class=\"w3-badge\">" + data.push(5) + "</span>"
You will need to use javascript to find the DOM elements and populate them. You will get to get the elements by class name and then loop through them to reassign the inner html.
var doms = getElementsByClassName( 'w3-badge' );
for( var i = 0; i < doms.length; i++ ) {
doms[ i ].innerHTML = data[ i ];
}
Why don't you simply add those numbers to the array if you say it's something static, and then parse the array with a for loop to add the HTML tags? You need to correctly escape using the right quotes and concatenate:
var test = [];
var data = [5, 6, 4];
for(var i = 0; i < data.length; i++){
test += "<span class='w3-badge'>" + data[i] + "</span>";
}
document.getElementById('container').innerHTML = test;
<div id='container'>
</div>
as you've tagged jquery, i will show you a jQuery way:
you must have a parent element, assuming it's a div with id "numbers", you could just:
var numbers = $('#numbers');
for(var i = 0; i < data.length; i++) {
numbers.append($('<span class="w3-badge">'+data[i]+'</span>'));
}
With data.push(num) you push num to the next free index in the array.
With data[index] you get the value (num) at given index.
Next point:
You can't use unescaped double quotationmarks inside double quotationmarks.
Use single questionmarks instead of one of them.
And you have to use a + to connect two strings.
I think, you don't got the fundamental basics of Javascript.
You should work trough something like this before you start fiddling around: http://jqfundamentals.com/chapter/javascript-basics (~ 5-15 min reading)
You can either use javaScript
var test = "<span class='w3-badge'>"+data.push(5)+"</span>";
or the ES6 attempt, this will work inline
var test = `<span class='w3-badge'>${data.push(5)}</span>`;
To insert a DOM described as above into the HTML first do:
var span1 = document.createElement("span");
span1.className = "w3-badge";
span1.innerHTML = 5; //create a span as above and set 5 between it
document.body.append(span1); //add completed span obj to document body
<body></body>
You can also create a string s with the html code you want, and call
document.body.append(s);
to add the span to the body of the document
there are a lot of ways to get the values of DOMS as well.
most of them begin with document.getElementsBy and can be found here
each of these returns an array of all of the html doms that match your query.
document.getElementById() in particular will return one element only, since only one element should have a given id in the html.
you can then call .innerHTML to a particular DOM selected with any of those methods
so in yours
var data = [];
var spans = document.getElementsByClassName("w3-badge");
for( var i =0; i < spans.length; i++){
data.push(spans[i].innerHTML);
}
console.log(data);
<span class="w3-badge">5</span>
<span class="w3-badge">6</span>
<span class="w3-badge">4</span>
As you have tagged JQuery, here is a clean version which loops over every element with the class w3-badge:
var data = [];
data.push(5);
data.push(6);
data.push(4);
$('.w3-badge').each(function(i, obj) {
document.getElementById(i).innerHTML = data[i];
});
JSFiddle Demo
Snippet (with CSS Circle):
var data = [];
data.push(5);
data.push(6);
data.push(4);
$('.w3-badge').each(function(i, obj) {
document.getElementById(i).innerHTML = data[i];
});
.cl {
border-radius: 50%;
behavior: url(PIE.htc);
width: 36px; height: 36px;
padding: 8px;
background: #fff;
border: 2px solid #666;
color: #666;
text-align: center;
font: 32px Arial, sans-serif;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<span id="0" class="cl w3-badge">0</span>
<span id="1" class="cl w3-badge">0</span>
<span id="2" class="cl w3-badge">0</span>
Pure JavaScript version:
Note: You have to give every element an ID beginning from zero.
This isn't a that beautiful version but it works:
var data = [];
data.push(5);
data.push(6);
data.push(4);
for (i = 0; i < data.length; i++){
console.log(i + " = " + data[i]);
document.getElementById(i).innerHTML = data[i];
}
Demo:
var data = [];
data.push(5);
data.push(6);
data.push(4);
for (i = 0; i < data.length; i++){
console.log(i + " = " + data[i]);
document.getElementById(i).innerHTML = data[i];
}
.cl {
border-radius: 50%;
behavior: url(PIE.htc);
width: 36px; height: 36px;
padding: 8px;
background: #fff;
border: 2px solid #666;
color: #666;
text-align: center;
font: 32px Arial, sans-serif;
}
<span id="0" class="cl w3-badge">0</span>
<span id="1" class="cl w3-badge">0</span>
<span id="2" class="cl w3-badge">0</span>
JSFiddle Demo

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">

How to sequentially .append() created elements to the previously added element

The code
JavaScript:
var recurringF = (function(){
this.$el = $("#target");
this.arg = arguments[0];
this.spl = (!_.isEmpty(this.arg)) ? this.arg.split(" ") : false;
if(this.spl){
for(var i=0;i<this.spl.length;i++){
if(i===0){
this.$el.append(document.createElement(this.spl[i]));
}else{
this.$el.children().last().append(document.createElement(this.spl[i]));
}
}
}
return {
"$":this.$el
}
});
var t = new recurringF("div h1 span");
HTML-Body:
<body>
<div id="target"></div>
</body>
The Goal
I'd like to append elements sequentially to an parent element $("#target") so that the end result in the HTML is the following:
<body>
<div id="target">
<div>
<h1>
<span></span>
</h1>
</div>
</div>
</body>
The loop does not append the created elements to the the last appended element, but to the in loop cycle 1 created element 'div' like the following:
<div id="target">
<div>
<h1></h1>
<span></span>
</div>
</div>
What am I missing?
By using .children(), you'll only get the immediate div on every iteration after the first, thus resulting in
<div id="target">
<div>
<h1></h1>
<span></span>
<alltherest></alltherest>
</div>
</div>
because .children only looks at children, not all descendants. What you want is .find(*) so that it will get the deepest nested descendant on each iteration.
this.$el.find('*').last().append(document.createElement(this.spl[i]));
https://jsfiddle.net/f3fb997h/
That said, it would be better if you just stored a reference to the last created element and append to it, rather than having to reselect it every iteration.
var $tempEl = this.$el, newEl;
if(this.spl){
for(var i=0;i<this.spl.length;i++){
newEl = document.createElement(this.spl[i]);
$tempEl.append(newEl);
$tempEl = $(newEl);
}
}
https://jsfiddle.net/f3fb997h/1/
Note that at this point you're not really benefiting from jQuery at all, so a small tweak and you're not depending on it.
var recurringF = (function(){
this.el = document.getElementById('target');
this.arg = arguments[0];
this.spl = (!_.isEmpty(this.arg)) ? this.arg.split(" ") : false;
console.log(this.spl);
var tempEl = this.el, newEl;
if(this.spl){
for(var i=0;i<this.spl.length;i++){
newEl = document.createElement(this.spl[i]);
tempEl.appendChild(newEl);
tempEl = newEl;
}
}
return {
"el":this.el
}
});
You can try using regular javascript functionality, as it has child appending built in:
const recurseElement = (elementString, target) => {
const elements = elementString.split(' ');
elements.forEach(function(ele) {
const domElement = document.createElement(ele); // create the element
target.appendChild(domElement); // append to the target
target = domElement; // this element is the new target
});
}
So now you can use it like so:
recurseElement('div h1 span', document.getElementById('target'));
const recurseElement = (elementString, target) => {
const elements = elementString.split(' ');
elements.forEach(function(ele) {
const domElement = document.createElement(ele); // create the element
target.appendChild(domElement); // append to the target
target = domElement; // this element is the new target
});
};
recurseElement('div h1 span', document.getElementById('target'));
#target div {
background: green;
height: 16px; width: 128px; padding: 10px;
}
#target div h1 {
background: red;
height: 16px; width: 64px; padding: 10px;
}
#target div h1 span {
background: purple; display: block;
height: 16px; width: 32px; padding: 10px;
}
<div id="target"></div>
It should be noted that arrow functions are available for Chrome 45+, Firefox 22.0+, Edge, and Opera. They do not work in IE or Safari. Or they will work if you have a transpiler (like babel)

Javascript DOM issue. (getElementsByClassName) [duplicate]

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/

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.

Categories