How to ssign Variable with div element's name - javascript

So I got multiple divs with different images embedded. Each one has its unique name attributes. I'm trying to apply the hover effect to each divs by changing the image source. I don't want to write multiple scripts, rather I'm trying to write a just one block of script that would effect every div.
<div id="div1" >
<img id="img1" name="img1" src="img1_up.jpg" />
</div>
<div id="div2">
<img id="img2" name="img2" src="img2_up.jpg" />
</div>...and so on
Now here is the script that I currently have for the rollover effects
<script>
var var1 = document.getElementById("div1");
var1.addEventListener("mouseover", changeImage1);
var1.addEventListener("mouseout", restoreImage1);
function changeImage1() {
document.getElementById("img1").src = "img1_ro.jpg";
}
function restoreImage1() {
document.getElementById("img1").src = "img1_up.jpg";
}
var var2 = document.getElementById("div2");
var2.addEventListener("mouseover", changeImage2);
var2.addEventListener("mouseout", restoreImage2);
function changeImage2() {
document.getElementById("img2").src = "img2_ro.jpg";
}
function restoreImage2() {
document.getElementById("img2").src = "img2_up.jpg";
}...and so on
</script>
I would like to use the name attributes from each images to create dynamic code to apply to all images. Here is what I have in mind but not sure the exact way to write it. PLEASE HELP
...
var dynamicVar = ????
dynamicVar.addEventListener("mouseover", changeImage();
dynamicVar.addEventListener("mouseout", restoreImage();
function changeImage() {
document.getElementById(dynamicVar).src = dynamicVar + "_ro.jpg";
}
function restoreImage() {
document.getElementById(dynamicVar).src = dynamicVar + "_up.jpg";
}

You can use loop to add event, don't need to specify id for each div:
var inputs = document.getElementsByTagName("div");
for(var i = 0; i < inputs.length; i++) {
if(inputs[i].id.indexOf('div') >= 0) {
inputs[i].addEventListener("mouseover", changeImage);
inputs[i].addEventListener("mouseout", restoreImage);
}
}
function changeImage(){
var tmpStr = this.id;
var divIndex = tmpStr.substring(3, tmpStr.length);
document.getElementById("img" + divIndex).src = divIndex + "_ro.jpg";
}
function restoreImage(){
var tmpStr = this.id;
var divIndex = tmpStr.substring(3, tmpStr.length);
document.getElementById("img" + divIndex).src = divIndex + "_up.jpg";
}
See on fiddle: Link

try this
var parent = document.getElementById("parent");
var childs = parent.getElementsByTagName('div');
for (var i = 0; i < childs.length; i++) {
(function () {
var e = childs[i];
e.addEventListener("mouseover", function () {
changeImage(e);
});
e.addEventListener("mouseout", function () {
restoreImage(e);
});
}());
}
function changeImage(element) {
var imgs = element.getElementsByTagName('img');
for (var i = 0; i < imgs.length; i++) {
alert(imgs[i].id);
}
}
function restoreImage(element) {
var imgs = element.getElementsByTagName('img');
for (var i = 0; i < imgs.length; i++) {
imgs[i].src = img_ro;
}
}
you can check this fiddle

Related

How get next element after "this" - pure javascript

I have code:
var links = document.querySelectorAll('a[data-lightbox]');
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click', function() {
event.preventDefault();
var imgLink = this.getAttribute('href');
var imgTitle = this.getAttribute('title');
var dataLightbox= this.getAttribute('data-lightbox');
console.log(); //next element after "this." something like "links[i+1]" or i don't know...
}, false);
}
I want to get 'data-lightbox' attribute for next element which I clicked currently. How to do it?
Using a IIFE can do the trick to preserve the i scope
var links = document.querySelectorAll('a[data-lightbox]');
for (var i = 0; i < links.length; i++) {
(function(i){
links[i].addEventListener('click', function() {
event.preventDefault();
var imgLink = this.getAttribute('href');
var imgTitle = this.getAttribute('title');
var dataLightbox= this.getAttribute('data-lightbox');
console.log(links[i + 1]);
}, false);
})(i)
}
This is a scope issue.
You can use bind (which would fix the scope issue) for the onclick event binding,while this you can send i to the method and you can access the next element using i+1
check the following snippet
window.onload = function() {
var links = document.querySelectorAll('a[data-lightbox]');
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click', onclick.bind(links[i], i));
}
function onclick(i) {
var imgLink = this.getAttribute('href');
var imgTitle = this.getAttribute('title');
var dataLightbox = this.getAttribute('data-lightbox');
if(links[i+1]!=undefined){
var nextLightbox = links[i + 1].getAttribute('data-lightbox');
}
console.log(imgLink);
console.log(dataLightbox);
console.log(nextLightbox);
}
}
<a href="#" data-lightbox=10>link1</a>
<a href="#" data-lightbox=20>link2</a><a href="#" data-lightbox=30>link3</a><a href="#" data-lightbox=40>link4</a><a href="#" data-lightbox=50>link5</a>
Hope it helps
You can try to get the next element in the way you thought: links[i + 1], although the i is an unique hoisted variable by this loop. You can, however, re-generate this i in the loop body, using variable declaration of let (only supported in ES6+) or using a new function scope inside that loop.
let acts like we were in a new scope, but not. It won't affect the previous i in this example, it'll only replace its presence at the block statement.
var links = document.querySelectorAll('a[data-lightbox]');
for (var i = 0; i < links.length; i++) {
let i = i;
links[i].addEventListener('click', function() {
event.preventDefault();
var imgLink = this.getAttribute('href');
var imgTitle = this.getAttribute('title');
var dataLightbox= this.getAttribute('data-lightbox');
console.log(links[i + 1]);
}, false);
}
In addition to what others have mentioned, another way to go about this is using nextSibling on this.
var links = document.querySelectorAll('a[data-lightbox]');
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click', function() {
event.preventDefault();
var imgLink = this.getAttribute('href');
var imgTitle = this.getAttribute('title');
var dataLightbox= this.getAttribute('data-lightbox');
console.log(this.nextElementSibling);
}, false);
}

Have a script that changes div after time interval need to alter so it only runs once

I have the following js that changes div content at a time interval, I love how it works but need to alter it so script only runs once how do I do this?
<script type="text/javascript">
function initChangeText()
{
var time = 10;
setInterval('changeText();',time*1000);
}
function changeText()
{
var divs_ = document.getElementsByTagName("div")
for (var i = 0;i<divs_.length;i++)
if (divs_[i].className == "change")
changeULText(divs_[i]);
}
function changeULText(obj)
{
var ul = obj.getElementsByTagName("ul")[0];
var li = obj.getElementsByTagName("li");
for (var i=0;i<li.length;i++)
{
if (li[i].className == "show")
{
li[i].className = "";
li[(i+1)%li.length].className = "show";
return ;
}
}
}
window.onload = initChangeText;
</script>
Thanks
Tim
You can use setTimeout instead of setInterval
function initChangeText(){
var time = 10;
setTimeout(changeText,time*1000);
}
function changeText(){
var divs_ = document.getElementsByTagName("div")
for (var i = 0;i<divs_.length;i++)
if (divs_[i].className == "change")
changeULText(divs_[i]);
}
function changeULText(obj) {
var ul = obj.getElementsByTagName("ul")[0];
var li = obj.getElementsByTagName("li");
for (var i=0;i<li.length;i++){
if (li[i].className == "show"){
li[i].className = "";
li[(i+1)%li.length].className = "show";
return ;
}
}
}
window.onload = initChangeText;
</script>

vanilla javascript: element.close() not working on element

This is a Sudoko generator I'm programming in vanilla javascript:
Fiddle with code
Nicer looking full screen fiddle
If you click on one of the fields, a popup will be shown with 3x3 fields from 1 to 9. The problem is this popup can't be closed anymore, although I'm applying the close dialog.
The code how I'm generating the Sudoku board:
// create sudoku
function tableCreate() {
var body = document.getElementsByClassName("frame")[0];
var containerDiv = body.appendChild(document.createElement('div'))
containerDiv.className = 'container';
// create single cells with numbers
function createInnnerCells(parent, xx, yy) {
for (var x = 1; x <= 3; x++) {
for (var y = 1; y <= 3; y++) {
var abc = function () {
var div = parent.appendChild(document.createElement('div'))
var X = y+yy;
var Y = x+xx;
var id = 'x' + [X] + 'y' + [Y];
var cellValue = sudoku[X][Y]['value'] || '';
div.style.background = sudoku[X][Y]['background'] || 'white'
div.className = 'cell';
div.id = id;
var popover = createDialog(id);
popover.onclick = function() {
popover.close();
};
div.onclick = function() {
popover.show();
};
div.appendChild(popover);
div.appendChild(document.createTextNode(cellValue));
};
abc();
}
}
}
// create big cells for 3x3 single cells
for (var i = 0; i <= 6; i+=3) {
for (var j = 0; j <= 6; j+=3) {
var div = containerDiv.appendChild(document.createElement('div'))
div.className = 'block';
createInnnerCells(div, i, j);
}
}
}
Note that I apply the close() function to each cell:
popover.onclick = function() {
popover.close();
};
The code how I create the popup:
// create dialog
function createDialog(position){
var dialog = document.createElement('dialog');
dialog.id ='window_'+ position;
var dialogblock = dialog.appendChild(document.createElement('div'));
dialogblock.className = 'dialogblock';
for (var z = 1; z <= 9; z++) {
var div = dialogblock.appendChild(document.createElement('div'));
div.className = 'dialogcell';
div.id = position + 'z'+ z;
div.appendChild(document.createTextNode(position));
}
dialog.onclick = function() {
dialog.close();
};
return dialog;
}
I applied the close() dialog here as well
dialog.onclick = function() {
dialog.close();
};
I don't know why show() is working, but close() not?
DOM events bubble up the DOM through its parents. In your code, the dialog is a child of div. Therefore, a click event happens on dialog and then again on div which means you're closing and then opening the dialog.
You can stop the propagation of the event by using event.stopPropagation.
You can change your code like this:
popover.onclick = function(e) {
e.stopPropagation();
popover.close();
};
and
dialog.onclick = function(e) {
e.stopPropagation();
dialog.close();
};
modified your fiddle: http://jsfiddle.net/p40oahkd/9/
There's no method close() on the element you are trying to hide. You should either do element.style.display = "none" if you need to hide. Or do the following:
dialog.addEventListener('click', function() {
this.remove();
});
Check out this edit to your fiddle.

Find index in array different from the array that loaded

Line 35, just before the alert, returns -1. I also tried $(this).index() with the same result. Here is what it should do: Clicking EN.gif should return 4, then grand_array_pics[4] should give me en_array_pics and load the .gifs in that array.
$(document).ready(function () {
var main_pics = ["AN.gif", "BN.gif", "CN.gif", "DN.gif", "EN.gif", "GN.gif"];
var starting_pics = ["AN.gif", "CN.gif", "EN.gif"];
var an_array_pics = ["BN.gif", "EN.gif", "GN.gif", "AN.gif","DN.gif"];
var bn_array_pics = ["CN.gif", "DN.gif", "GN.gif"];
var cn_array_pics = ["DN.gif", "GN.gif", "AN.gif", "CN.gif"];
var dn_array_pics = ["EN.gif", "AN.gif", "CN.gif"];
var en_array_pics = ["GN.gif", "AN.gif", "CN.gif", "EN.gif"];
var gn_array_pics = ["AN.gif", "CN.gif", "EN.gif", "GN.gif"];
var grand_array_pics = [
an_array_pics,
bn_array_pics,
cn_array_pics,
dn_array_pics,
en_array_pics,
gn_array_pics
];
var i = 0;
for (i = 0; i < starting_pics.length; i++) {
$("<img/>").attr("src", "images/" + starting_pics[i]).load(function () {
$(this).appendTo("#main");
$(this).addClass("pics");
});
}
$("#main").on("click", ".pics", function () {
var j = $.inArray(this, main_pics);
alert(j);
$("#sidebar .pics").remove();
$(this).clone().appendTo("#train");
$(this).clone().appendTo("#sidebar");
$("#main .pics").remove();
var chosen_pics_array = grand_array_pics[j];
var count = chosen_pics_array.length;
var k = 0;
for (k = 0; k < count; k++) {
$("<img/>").attr("src", "images/" + chosen_pics_array[k]).load(function () {
$(this).appendTo("#main");
$(this).addClass("pics");
});
}
});
}); //end ready
this is the DOM <img> element, while main_pics is an array of strings. It will never be found inside there. Use
var j = $.inArray(this.src.split("/").pop(), main_pics);
Give this a try. You need to get the name of the file and you're passing the element itself into $.inArray
var j = $.inArray(this.src.substring(this.src.lastIndexOf('/')+1), main_pics);

Replace image with different image/button - javascript

within a function, I'm trying to replace a image/button with another image/button.
<img src="images/14.gif" id="ImageButton1" onClick="showLoad()">
<img src="images/getld.png" id="ImageButton2" alt="Get Last Digits" style="display:none;" onClick="showLock()" />
<script type="text/javascript" language="javascript">
function swapButton(){
document.getElementById('ImageButton1').src = document.getElementById('ImageButton2').src;
}
</script>
But I have the problem that there is two of the same button, (button 2) when it is replaced! (one at the top of the page, and one where it is meant to be). I was wondering if there is a way of getting rid of the extra button at the top, or creating the button element within the javascript function?
Thanks for any help.
You can remove an element in javascript using
var el = document.getElementById('id');
var remElement = (el.parentNode).removeChild(el);
You can hide the first button, not only change the image source. The code below shows one way of doing that.
<img src="images/14.gif" id="ImageButton1" onClick="swapButtons(false)" style="visibility: visible;" />
<img src="images/getld.png" id="ImageButton2" alt="Get Last Digits" style="visibility: hidden;" onClick="swapButtons(true)" />
<script type="text/javascript" language="javascript">
function swapButtons(show1) {
document.getElementById('ImageButton1').style.visibility = show1 ? 'visible' : 'hidden';
document.getElementById('ImageButton2').style.visibility = show1 ? 'hidden' : 'visible';
}
</script>
I'd suggest something akin to the following:
function swapImageSrc(elem, nextElemId) {
if (!elem) {
return false;
}
if (!nextElemId || !document.getElementById(nextElemId)) {
var id = elem.id.replace(/\d+/, ''),
nextNum = parseInt(elem.id.match(/\d+/), 10) + 1,
next = document.getElementById(id + nextNum).src;
}
else {
var next = document.getElementById(nextElemId).src;
}
elem.src = next;
}
var images = document.getElementsByTagName('img');
for (var i = 0, len = images.length; i < len; i++) {
images[i].onclick = function() {
swapImageSrc(this,imgButton2);
};
}​
JS Fiddle demo.
Edited to add that, while it is possible to switch the src attribute of an image it seems needless, since both images are present in the DOM. The alternative approach is to simply hide the clicked image and show the next:
function swapImageSrc(elem, nextElemId) {
if (!elem) {
return false;
}
if (!nextElemId || !document.getElementById(nextElemId)) {
var id = elem.id.replace(/\d+/, ''),
nextNum = parseInt(elem.id.match(/\d+/), 10) + 1,
next = document.getElementById(id + nextNum);
}
else {
var next = document.getElementById(nextElemId);
}
if (!next){
return false;
}
elem.style.display = 'none';
next.style.display = 'inline-block';
}
var images = document.getElementsByTagName('img');
for (var i = 0, len = images.length; i < len; i++) {
images[i].onclick = function() {
swapImageSrc(this,imgButton2);
};
}​
JS Fiddle demo.
Edited to offer an alternate approach, which moves the next element to the same location as the clicked image element:
function swapImageSrc(elem, nextElemId) {
if (!elem) {
return false;
}
if (!nextElemId || !document.getElementById(nextElemId)) {
var id = elem.id.replace(/\d+/, ''),
nextNum = parseInt(elem.id.match(/\d+/), 10) + 1,
next = document.getElementById(id + nextNum);
}
else {
var next = document.getElementById(nextElemId);
}
if (!next){
return false;
}
elem.parentNode.insertBefore(next,elem.nextSibling);
elem.style.display = 'none';
next.style.display = 'inline-block';
}
var images = document.getElementsByTagName('img');
for (var i = 0, len = images.length; i < len; i++) {
images[i].onclick = function() {
swapImageSrc(this,imgButton2);
};
}​
JS Fiddle demo.

Categories

Resources