Javascript Loop to Call a Function - javascript

Trying to figure out onmouseover, onmouseout and onclick with several pictures all having the same ID tag. To do that, I understand I need a .length loop.
This code works without the length loop...
window.onload = setPictures;
function setPictures() {
var img = document.getElementById("pictureBox");
img.onmouseover = mouseOverImage;
img.onmouseout= mouseOutImage;
}
function mouseOverImage() {
var img = document.getElementById("myImg");
img.style.opacity = .5;
}
function mouseOutImage() {
var img = document.getElementById("myImg");
img.style.opacity = 1;
}
This is the loop function I attempted that is not working.
window.onload = setPictures;
function setPictures() {
var img = document.getElementById("pictureBox");
for (var i=0; i<img.length; i++) {
img[i].onmouseover = mouseOverImage;
img[i].onmouseout= mouseOutImage;}
}
Please advise, and thank you in advance for your help!

getElementById only returns one element, as ID's should be unique.
Instead, add a class to each element and select them by class. Callbacks can rely on this's context for your mouse events:
function mouseOverImage() {
this.style.opacity = .5;
}
function mouseOutImage() {
this.style.opacity = 1;
}
window.onload = function setPictures() {
var imageCollection = document.getElementsByClassName('pictureBox');
for (var i=0; i < imageCollection.length; i++) {
imageCollection[i].onmouseover = mouseOverImage;
imageCollection[i].onmouseout = mouseOutImage;
}
}

As it has been said, getElementById return only one element.
This below could help you:
window.onload = setPictures;
function setPictures() {
var img = document.getElementById("pictureBox0");
for (var i=1; img != null; i++) {
img.onmouseover = mouseOverImage;
img.onmouseout= mouseOutImage;
img = document.getElementById("pictureBox"+i);
}
}

Related

How To Remove JoinPouch Pop-Ups From Showing On My Site

There extension shows content on my site and I want to block it using JavaScript. Is there anyone that knows how to block these div classes from being created?
Try This Code:
function Init () {
var body = document.body;
if (body.addEventListener) {
body.addEventListener ('DOMNodeInsertedIntoDocument', OnNodeInsertedIntoDocument, false);
}
}
function OnNodeInsertedIntoDocument () {
var elements = ["mainPouchDiv", "pouchNotifyHeader", "nsPouchCrossPromotionContainer"];
var element = null;
var i = 0;
for (i = 0; i < elements.length; i++) {
element = document.getElementById(elements[i]);
if (element) {
document.body.removeChild(element);
element = null;
}
}
}

How to add event to every image using ES5

I am adding event listener to every image in document.
for (var i = 0; i < document.images.length; i++) {
let img = document.images[i];
img.addEventListener('click', function (event) {
var data = {uri: img.src};
});
}
But I can't use es6 so let is making me issue. If I put var instead of let only last image has event.
How to use es5 to add event to each image?
You could do it this way using var and this:
for (var i = 0; i < document.images.length; i++) {
document.images[i].addEventListener('click', function(event) {
var data = {
uri: this.src
};
});
}
for (var i = 0; i < document.images.length; i++) {
document.images[i].addEventListener('click', function(event) {
var data = {
uri: this.src
};
console.log(data)
});
}
<img src="http://www.placehold.it/100x100">
<img src="http://www.placehold.it/100x200">
<img src="http://www.placehold.it/100x300">
Here's an example of creating elements and adding an event listener to each using regular old ES5.
function createClickableElements() {
var arr = [];
for (var i = 0; i < 5; i++) {
var div = document.createElement('div');
div.innerHTML = 'Click Here!';
arr.push(div);
}
return arr;
}
var elems = createClickableElements();
var createClickHandler = function(arg) {
return function() {
console.log(arg);
};
}
for (var i = 0; i < elems.length; i++) {
elems[i].onclick = createClickHandler(i);
document.getElementById('container').appendChild(elems[i]);
}
<div id='container'></div>
Unlike other examples suggest, there is no need of creating a closure for each image, or assigning a new anonymous function to each image. And ES5 already offers Array.from and Array.prototype.forEach. Making use of it supports writing better readable code that just uses two functions - one for assigning the click handler and another one that will handle the data creation of any image, thus offering a less memory consuming approach too ...
function createImageData(evt) {
var data = { uri: evt.target.src };
console.log('createImageData - data : ', data);
}
function assignClickHandler(elmImage) {
elmImage.addEventListener('click', createImageData, false);
console.log('assignClickHandler - elmImage : ', elmImage);
}
Array.from(document.images).forEach(assignClickHandler);
.as-console-wrapper { top: 0; }
<img src="https://placehold.it/100x100">
<img src="https://placehold.it/100x200">
<img src="https://placehold.it/100x300">
... one might even think about making use of event delegation

Abstracting repetitive addEventListener('click'... functions to optimize code

EDIT: Looking for a non-Jquery Answer
As it stands this code is incredibly long for how simple it is. The only difference between specific instances is a number indicating the ID of the target. Is there a way to accomplish the same result with a single function that gets fed variable based on which div is clicked?
var $ = Sizzle,
p0 = $("#p0")[0];
p1 = $("#p1")[0];
p2 = $("#p2")[0];
p3 = $("#p3")[0];
p4 = $("#p4")[0];
p5 = $("#p5")[0];
p6 = $("#p6")[0];
p7 = $("#p7")[0];
lp0 = $("#productMenu li")[0];
lp1 = $("#productMenu li")[1];
lp2 = $("#productMenu li")[2];
lp3 = $("#productMenu li")[3];
lp4 = $("#productMenu li")[4];
lp5 = $("#productMenu li")[5];
lp6 = $("#productMenu li")[6];
lp7 = $("#productMenu li")[7];
lp0.addEventListener('click',open0,false);
lp1.addEventListener('click',open1,false);
lp2.addEventListener('click',open2,false);
lp3.addEventListener('click',open3,false);
lp4.addEventListener('click',open4,false);
lp5.addEventListener('click',open5,false);
lp6.addEventListener('click',open6,false);
lp7.addEventListener('click',open7,false);
function open0(){
p0.classList.toggle('off');
}
function open1(){
p1.classList.toggle('off');
}
function open2(){
p2.classList.toggle('off');
}
function open3(){
p3.classList.toggle('off');
}
function open4(){
p4.classList.toggle('off');
}
function open5(){
p5.classList.toggle('off');
}
function open6(){
p6.classList.toggle('off');
}
function open7(){
p7.classList.toggle('off');
}
You can try this code:
$('#productMenu li').on('click', function () {
var index = $("#productMenu li").index($(this));
$('#p' + index).toggleClass('off');
});
In plain script, something like the following should work:
// Helper to convert a list to an array
function toArray(list) {
var array = [];
for (var i=0, iLen=list.length; i<iLen; i++) {
array[i] = list[i];
}
return array;
}
// Helper to add a listener without closure
function addFunction(source, target) {
source.addEventListener('click', function(){target.classList.toggle('off')}, false);
}
function addListeners() {
var nodes = [];
for (var i=0; i<8; i++) {
pNodes.push(document.getElementById('p' + i));
}
var lpNodes = toArray(document.getElementById('productMenu').getElementsByTagName('li'));
for (var j=0, jLen=lpNodes.length; j<jLen; j++) {
addFunction(lpNodes[j],pNodes[j]);
}
}
Untested of course, but the approach should help. It isn't really necessary to convert the NodeList returned by getElementsByTagName to an array, but it may be help performance.
There are other approaches to this, most obviously to use event delegation and put a single listener on a parent element (an UL?) that sees where the click came from, then toggles the related element if required. e.g. if the click came from lp0, toggle p0 (though you should probaby be using classes for this, not IDs).
Something like:
function handleClick(event) {
var element;
var target = event.target;
if (target.tagName && target.tagName.toLowerCase() == 'li') {
var id = target.id.match(/\d+/$);
if (id) {
element = document.getElementById('p' + id[0]);
}
if (element) {
element.classList.toggle('off');
}
}
}
window.onload = function() {
document.getElementById('productMenu').addEventListener('click', handleClick, false);
}

Attaching single event to multiple elements stored in an array, native JS

Everyone is suggesting some framework, but I'd like to know how it can be done in native JavaScript. I've tried this code and some other things, no effect. Seems that I'm unaware of some basic underlying concept. Any help would be appreciated.
window.onload = function() {
var trCurrent
var main = document.getElementById('main');
var tr = main.getElementsByTagName('tr');
function hl() {
trCurrent.setAttribute('class', 'highlight');
};
for (var x = 0; x < tr.lenght; x++) {
trCurrent = tr[x];
trCurrent.addEventListener ('mousedown', hl, false);
}
};
You have to change trCurrent to this at your function h1, becayse trCurrent points to the last defined TR element (trCurrent = tr[x] for a high x).
Use .length instead of .lenght.
Final code:
window.onload = function() {
var main = document.getElementById('main');
var tr = main.getElementsByTagName('tr');
function hl() {
this.setAttribute('class', 'highlight');
};
for (var x = 0; x < tr.length; x++) {
tr[x].addEventListener ('mousedown', hl, false);
}
};
If you want to use an variable which is subject to change during a loop, it's required to wrap the body in an (anonymous) function:
window.onload = function() {
var main = document.getElementById('main');
var tr = main.getElementsByTagName('tr');
for (var x = 0; x < tr.length; x++) {
(function(trCurrent){ //Anonymous wrapper, first argument: `trCurrent`
function hl() {
trCurrent.setAttribute('class', 'highlight');
};
trCurrent.addEventListener ('mousedown', hl, false);
})(tr[x]); //Passing a reference to `tr[x]`
}
};

Assigning event functions with a loop in JS

Here is the script I have:
And I'm trying to assign event to each element in an array.
window.onload = sliding;
function sliding() {
document.getElementById('tag1').onmouseover = slideout;
document.getElementById('tag1').onmouseout = slidein;
}
And I tried do using the code below but that didn't work. It would trigger all the function buy it self.
window.onload = sliding;
var tags = new Array('tag1','tag2','tag3','tag4','tag5','tag6','tag7','tag8');// List of headings
var pics = new Array('popout1','popout2','popout3','popout4','popout5','popout6','popout7','popout8');// list of images that slide out
function sliding() {
for (var i = 0; i < tags.length; ++i) {
document.getElementById('tag1').onmouseover = setslideout(tags[i],pics[i]);
document.getElementById('tag1').onmouseout= setslidein(tags[i],pics[i]);
}
}
Here is full code
window.onload = sliding;
var tags = new Array('tag1','tag2','tag3','tag4','tag5','tag6','tag7','tag8');// List of headings
var pics = new Array('popout1','popout2','popout3','popout4','popout5','popout6','popout7','popout8');// list of images that slide out
function sliding() {
/*for (var i = 0; i < tags.length; ++i) {
setslideout(tags[i],pics[i]);
}/*/
document.getElementById('tag1').onmouseover = slideout;
document.getElementById('tag1').onmouseout = slidein;
}/*
function setslideout(tagsid,picsid){
document.getElementById(tagsid).onmouseover = slideout(tagsid,picsid);
}*/
function slideout(){
//alert('over '+ lid);
if(currpos('popout1') < 200){
document.getElementById('popout1').style.left = currpos('popout1') + 10 + "px";
var timer = setTimeout(slideout,10)
}else{
clearTimeout(timer);
}
}
function slidein(){
//alert('over '+ lid);
if(currpos('popout1') > 0){
document.getElementById('popout1').style.left = currpos('popout1') - 20 + "px";
var timer2 = setTimeout(slidein,10)
}else{
clearTimeout(timer2);
}
}
function currpos(element){
return document.getElementById(element).offsetLeft;
}
Here what im trying to to http://signsourceak.com/index2.html (first link in the drop down works )
Here's a version of your code modified to use closures, hopefully this does the trick:
window.onload = sliding;
var tags = new Array('tag1','tag2','tag3','tag4','tag5','tag6','tag7','tag8');// List of headings
var pics = new Array('popout1','popout2','popout3','popout4','popout5','popout6','popout7','popout8');// list of images that slide out
function sliding() {
for (var i = 0; i < tags.length; ++i) {
document.getElementById(tags[i]).onmouseover = (function(j){
return function(){
setslideout(tags[j], pics[j]);
}
})(i);
document.getElementById(tags[i]).onmouseout = (function(j){
return function(){
setslidein(tags[j], pics[j]);
}
})(i);
}
}

Categories