javascript array images link error - javascript
I'm trying to create a mini-book of images using a clip of code i found online which refreshes a set of predefined images onclick via a basic form button, however I can't figure out why the images i've specified in the array are not appearing in the div below. I've confirmed that the url addresses are correct path - but I must be doing something wrong with the linkage ? ?
<html>
<head>
<title></title>
<script>
var bookImages = new Array();
bookImages[0] = "fsheet1.jpg"
bookImages[1] = "fsheet2.jpg"
bookImages[2] = "fsheet3.jpg"
bookImages[3] = "fsheet4.jpg"
bookImages[4] = "fsheet5.jpg"
bookImages[5] = "fsheet6.jpg"
var i = 0
function updateImg() {
var i = i + 1;
var url = 'url(' + bookImages[i] + ')';
document.getElementById('bookImg').style.backgroundImage = url;
}
</script>
<style type="text/css">
#bookImg {
background-img: url();
background-repeat: no-repeat;
background-color: #CF23FA;
text-align: left;
width: 150px;
height: 200px;
margin-top: 10px;
margin-left: 15px;
}
</style>
</head>
<body>
<div id='bookImg'>
<form>
<input type="button" value=">" onClick="updateImg()">
</form>
</div>
</body>
</html>
The problem:
you are redifining i inside the function updateImg. Technically your function is equivalent to this:
function updateImg() {
var i; // redeclaring i (i is not initialised so the value is undefined)
i = i + 1; // undefined + 1
var url = 'url(' + bookImages[i] + ')'; // url(undefined)
document.getElementById('bookImg').style.backgroundImage = url;
}
The fix:
function updateImg() {
i = i + 1; // don't redeclare i just use the outer one (the one above)
var url = 'url(' + bookImages[i] + ')';
document.getElementById('bookImg').style.backgroundImage = url;
}
Note:
The above code will increment i without checking if it gone beyond the array boundaries (after 6 clicks i will be 7 and there is no image at index 7 in the array). If you want to go back to 0 when i reaches the end then replace i = i + 1; by i = (i + 1) % bookImages.length;!
Complete code:
<html>
<head>
<title></title>
<script>
// array litterals: a better way
var bookImages = [
"http://placehold.it/201x100",
"http://placehold.it/202x100",
"http://placehold.it/203x100",
"http://placehold.it/204x100",
"http://placehold.it/205x100",
"http://placehold.it/206x100"
];
var i = 0;
function updateImg() {
var url = 'url(' + bookImages[i] + ')';
document.getElementById('bookImg').style.backgroundImage = url;
i = (i + 1) % bookImages.length; // increment at the end
}
window.addEventListener("load", updateImg); // call it once the document is ready
</script>
<style type="text/css">
#bookImg {
background-repeat: no-repeat;
background-color: #CF23FA;
text-align: left;
width: 150px;
height: 200px;
margin-top: 10px;
margin-left: 15px;
}
</style>
</head>
<body>
<div id='bookImg'>
<form>
<input type="button" value=">" onClick="updateImg()">
</form>
</div>
</body>
</html>
Related
How to make a barcode smaller in HTML for printing on one page?
So I am having trouble making my bar codes smaller to fit on one page. There are supposed to be 3 bar codes per row and when I view it on the screen it looks fine.However, when I go to preview how it will look when it prints they get stuck together.If I make their width too small they no longer scan. So, how do I make them smaller to fit on one page while they are still able to be scanned? I have included the main part of my code below it is an HTML file but includes both HTML and JavaScript. I can't put the JavaScript in another file and have it as a source because everything has to be in one file. Any help is appreciated! <body> <div width = 100%> <table class="no-spacing" cellspacing="0"> <tr> <td width = 25%> <div id="barcodecontainer" style="width:125%"> <div id="inputdata" >123456123</div> <!-- Enter the NIIN for the barcode here --> Description : Code128A<br /><!-- Enter the description for the barcode here--> </div></div> </td><br/> <td width = 25%> <div id="barcodecontainer" style="width:125%"> <div id="inputdata1" >456789123</div> <!-- Enter the NIIN for the barcode here --> Description : Code128A<br /><!-- Enter the description for the barcode here--> </div> </div> </td> <td width = 25%> <div id="barcodecontainer" style="width:125%"> <div id="inputdata2" >111111123</div> <!-- Enter the NIIN for the barcode here --> Description : Code128A<br /><!-- Enter the description for the barcode here--> </div> </div> </td> </tr> </table> <script type="text/javascript"> /* <![CDATA[ */ function get_object(id) { var object = null; if (document.layers) { object = document.layers[id]; } else if (document.all) { object = document.all[id]; } else if (document.getElementById) { object = document.getElementById(id); } return object; get_object("inputdata").innerHTML=DrawHTMLBarcode_Code128A(get_object("inputdata").innerHTML,"yes","in",0,2.5,.6,"bottom","center","","black","white"); get_object("inputdata1").innerHTML=DrawHTMLBarcode_Code128A(get_object("inputdata1").innerHTML,"yes","in",0,2.3,.6,"bottom","center","","black","white"); get_object("inputdata2").innerHTML=DrawHTMLBarcode_Code128A(get_object("inputdata2").innerHTML,"yes","in",0,2.4,.6,"bottom","center","","black","white"</script>
Not sure if this will be any help, but I use CSS to control label size and page formatting. <!doctype html> <html lang="en"> <head> <title>Plain Vanilla JS Code 128B Barcodes</title> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" > <style type="text/css"> <!- CSS adapted from article: boulderinformationservices.wordpress.com/2011/08/25/print-avery-labels-using-css-and-html/ -> body { margin-top: 0in; margin-left: 0in; } .page { width: 8.5in; height: 10.5in; margin-top: 0.5in; margin-left: 0.25in; } .label { width: 2.1in; height: .9in; padding: .125in .3in 0; margin-right: 0.125in; float: left; text-align: center; overflow: hidden; } .page-break { clear: left; display:block; page-break-after:always; } </style> </head> <body> <div id="result"></div> <script type="text/javascript"> // The MIT License (MIT) // Copyright (c) 2017, Notionovus, LLC. // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv var arrayCode128Bin = [ '11011001100', '11001101100', '11001100110', '10010011000', '10010001100', '10001001100', '10011001000', '10011000100', '10001100100', '11001001000', '11001000100', '11000100100', '10110011100', '10011011100', '10011001110', '10111001100', '10011101100', '10011100110', '11001110010', '11001011100', '11001001110', '11011100100', '11001110100', '11101101110', '11101001100', '11100101100', '11100100110', '11101100100', '11100110100', '11100110010', '11011011000', '11011000110', '11000110110', '10100011000', '10001011000', '10001000110', '10110001000', '10001101000', '10001100010', '11010001000', '11000101000', '11000100010', '10110111000', '10110001110', '10001101110', '10111011000', '10111000110', '10001110110', '11101110110', '11010001110', '11000101110', '11011101000', '11011100010', '11011101110', '11101011000', '11101000110', '11100010110', '11101101000', '11101100010', '11100011010', '11101111010', '11001000010', '11110001010', '10100110000', '10100001100', '10010110000', '10010000110', '10000101100', '10000100110', '10110010000', '10110000100', '10011010000', '10011000010', '10000110100', '10000110010', '11000010010', '11001010000', '11110111010', '11000010100', '10001111010', '10100111100', '10010111100', '10010011110', '10111100100', '10011110100', '10011110010', '11110100100', '11110010100', '11110010010', '11011011110', '11011110110', '11110110110', '10101111000', '10100011110', '10001011110', '10111101000', '10111100010', '11110101000', '11110100010', '10111011110', '10111101110', '11101011110', '11110101110', '11010000100', '11010010000', '11010011100', '1100011101011', '11010111000']; var array5bit_A = [ 'f//AAAAAAAAAAAAAAAAAAAA', 'f//AAAAAAAAAAAAAAAAAAAB', 'f//AAAAAAAAAAAAAAEAAAD/', 'f//AAAAAAAAAAAAAAEAAAAA', 'f//AAAAAAAAAQAAAP8AAAAA', 'f//AAAAAAAAAQAAAP8AAAAB', 'f//AAAAAAAAAQAAAAAAAAD/', 'f//AAAAAAAAAQAAAAAAAAAA', 'f//AAABAAAA/wAAAAAAAAAA', 'f//AAABAAAA/wAAAAAAAAAB', 'f//AAABAAAA/wAAAAEAAAD/', 'f//AAABAAAA/wAAAAEAAAAA', 'f//AAABAAAAAAAAAP8AAAAA', 'f//AAABAAAAAAAAAP8AAAAB', 'f//AAABAAAAAAAAAAAAAAD/', 'f//AAABAAAAAAAAAAAAAAAA', 'QD/AAD/AAAAAAAAAAAAAAAA', 'QD/AAD/AAAAAAAAAAAAAAAB', 'QD/AAD/AAAAAAAAAAEAAAD/', 'QD/AAD/AAAAAAAAAAEAAAAA', 'QD/AAD/AAAAAQAAAP8AAAAA', 'QD/AAD/AAAAAQAAAP8AAAAB', 'QD/AAD/AAAAAQAAAAAAAAD/', 'QD/AAD/AAAAAQAAAAAAAAAA', 'QD/AAAAAAAA/wAAAAAAAAAA', 'QD/AAAAAAAA/wAAAAAAAAAB', 'SL/AADeAAAA/gAAAAIAAAD+', 'QD/AAAAAAAA/wAAAAEAAAAA', 'QD/AAAAAAAAAAAAAP8AAAAA', 'QD/AAAAAAAAAAAAAP8AAAAB', 'QD/AAAAAAAAAAAAAAAAAAD/', 'QD/AAAAAAAAAAAAAAAAAAAA']; var array5bit_B = [ 'US0CAuSD38g', 'UUYCA7QBErs', 'ajEDAm49ReY', 'UUoCA+juogg', 'bjEDAjQrOn0', 'bkoDA3iPVH4', 'ajUDAt82atY', 'UU4CA1nljTg', 'cjEDAghkmFU', 'ckoDA0TA9lY', 'izUEAhrxcbg', 'ck4DAxY8F10', 'bjUDAlvFFR8', 'bk4DAxdhexw', 'ajkDAr7LFAw', 'UVICAyQ+UJI', 'TTECAq7UnEM', 'TUoCA+Jw8kA', 'ZjUDAmZGozo', 'TU4CA7CME0s', 'ajUDAvnk9E4', 'ak4DA7VAmk0', 'ZjkDAtle3bI', 'TVICAxOyzrM', 'STUCAqHeHtM', 'SU4CA+16cNA', 'h6QEAZKdo54', 'SVICA62zYxM', 'RTkCAqx1lb4', 'RVICA/z3WM0', 'QT0CAkdoxRU', 'KFYBA46vJCA']; var stringStart = '<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAoAAAACCAQAAADLaIVbAAAANUlEQVQIHQEqANX/A'; var stringMid = 'AAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAA'; var stringEnd = 'AAAAASUVORK5CYII=" style="width:'; function genBarcode(inputString, intWidth, intHeight) { var arraySeq = [], i, intChunks, resultString; var intRawmod = inputString.length % 5; for (i = 0; i < 5 - intRawmod; i += 1) { inputString += "0"; } intChunks = inputString.length / 5; for (i = 0; i < intChunks; i += 1) { arraySeq[i] = parseInt(inputString.substr(i * 5, 5), 2); } resultString = ""; for (i = 0; i < arraySeq.length; i += 1) { resultString += stringStart + array5bit_A[arraySeq[i]] + stringMid + array5bit_B[arraySeq[i]] + stringEnd + intWidth + 'px;height:' + intHeight + 'px;">'; } return resultString; } function funcCode128B(strText) { var j, intWeight, intWtProd = 0; var strRaw = ""; var arrayData = []; arrayData[0] = 104; intWtProd = 104; for (j = 0; j < strText.length; j += 1) { arrayData[j + 1] = strText.charCodeAt(j) - 32; intWeight = j + 1; intWtProd += intWeight * arrayData[j + 1]; } arrayData[j + 1] = intWtProd % 103; arrayData[j + 2] = 106; for (j = 0; j < arrayData.length; j += 1) { strRaw += arrayCode128Bin[arrayData[j]]; } return(strRaw); } function fnNewPage(pageno) { var strNewPage, startNewPage = '<div class="page" id="page'; strNewPage = startNewPage + pageno + '">'; return strNewPage; } function fnEndPage() { var strEndPage = '<div class="page-break"></div></div>'; return strEndPage; } function fnNewLabel(barcode, txtHR) { var strNewLabel, startNewLabel = '<div class="label">'; strNewLabel = startNewLabel + barcode + '<br>' + txtHR + '</div>'; return strNewLabel; } function fnShowPage() { var outerLoop, innerLoop, indexBarcode, txtHumanReadable, strPage = ""; for (outerLoop = 0; outerLoop < 2; outerLoop += 1) { strPage += fnNewPage(outerLoop + 1); for (innerLoop = 0; innerLoop < 30; innerLoop += 1) { indexBarcode = (30 * outerLoop) + innerLoop + 400; switch (indexBarcode) { case 400: txtHumanReadable = '' + 123456123; break; case 401: txtHumanReadable = '' + 456789123; break; case 402: txtHumanReadable = '' + 111111123; break; default: txtHumanReadable = 'Test1' + indexBarcode; } txtBarcode = genBarcode(funcCode128B(txtHumanReadable), 6.5, 34); strPage += fnNewLabel(txtBarcode, txtHumanReadable) } strPage += fnEndPage(); } document.getElementById("result").innerHTML = strPage; } fnShowPage(); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ </script> </body> </html>
In order to prevent the DIVs from getting mixed up, you need to set the width of the divs with id="barcodecontainer" to 100%. This way its content won't get out of its parent <td>. <div id="barcodecontainer" style="width:100%"> Then just set the width of the "parent" DIVs to whatever percentage of the screen you want, preferable using the style attribute and vw units other than width and %: <td style="width:20vw"> and not: <td width = 25%> In general, I suggest you use CSS instead of repeating the style attributes for each element, especially because your code is already built in hierarchy. Here's a complete example.
Not to be super critical, but in my opinion you are using out dated web practices. I recommend not using table and using my little best friend flexbox. That being said, you are trying to shrink a bar code down without it losing its scan ability. I would try and make a few divs, then from their flex them into the location you want. From that make them a big or small as you want by resizing the divs. Hopefully, this helped.
It's hard to come up with a solution without seeing a running demo of the problem you are facing. (https://stackoverflow.com/help/mcve) (Moreover the script that you have included has some syntax errors as well. Missing closing brackets for function definition as well as on the last line. I assume these are just some typos you made while posting the question here.) Looking at the API documentation for DrawHTMLBarcode_Code128A # https://www.barcoderesource.com/htmlBarcodeAPI.shtml, I can see that the 4th param is minBarWidth. You have currently set it to 0. Instead you can set it to 2.5, same as the value for width param, and see if that helps. (You should combine this suggestion with the suggestions given by #GalAbra. Those are also valid points)
using jQuery to append div's and each div has a different ID
So I'm trying to to use jQuery to append a div which will generate a card using the assigned class. The problem is I need to create a different ID each time so I can put random number on the card. I'm sure there's an easier way to do this. So i'm posing two questions. how to make the code where it put the random number on the card go endlessly. and how to append divs with unique ID's. Sorry if my code isn't the best. It's my first project. <!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-1.11.2.min.js"></script> <title></title> <style> .cardLook { border: 1px solid black; width: 120px; height: 220px; border-radius: 5px; float: left; margin: 20px; padding: 5px; background-color: #fff; } #card1,#card2,#card3,#card4,#card5 { transform:rotate(180deg); } #cardTable { background-color: green; height: 270px } .reset { clear: both; } </style> <script src="//code.jquery.com/jquery-1.12.0.min.js"></script> </head> <body> <button id="deal">Deal</button> <button id="hit">hit</button> <button id="stand">Stand</button> <button id="hi">hi</button> <div id="number"></div> <div id="arrayOutput"></div> <div id="someId"></div> <div id="out2"></div> <div id="cardTable"> </div> <div class="reset"></div> <script> var what; //Services helper functon document.getElementById('deal').onclick = function deal() { var score1 = Math.floor(Math.random() *10 + 1); var score2 = Math.floor(Math.random() *10 + 1); var firstCard = score1; var secondCard = score2; //myNumberArray.push(firstCard, score2); //card1.innerHTML = myNumberArray[0]; //card2.innerHTML = myNumberArray[1]; $("#deal").click(function(){ $("#cardTable").append("<div class='cardLook' id='card1'></div>"); }); console.log(score2, score1) } var myNumberArray = []; $("#hit").click(function(){ $("#cardTable").append("<div class='cardLook' id="uniqueIdNumberOne"></div>"); if (myNumberArray > 1) { #cardTable } var card = Math.floor(Math.random() * 10) + 1; document.getElementById('number').innerHTML=card; myNumberArray.push(card); var number = myNumberArray.value; var arrayOutput = document.getElementById('number'); var someId = document.getElementById('someId'); someId.innerHTML = myNumberArray; card1.innerHTML = myNumberArray[0]; card2.innerHTML = myNumberArray[1]; card3.innerHTML = myNumberArray[2]; card4.innerHTML = myNumberArray[3]; card5.innerHTML = myNumberArray[4]; // console.log("myNumberArray: ", myNumberArray); what = calcTotal(myNumberArray); showMe(calcTotal(myNumberArray)); }); //var output = myNumberArray = calcTotal(list); function calcTotal(myNumberArray) { var total = 0; for(var i = 0; i < myNumberArray.length; i++){ total += myNumberArray[i]; } return total; } //document.getElementById('out2').innerHTML = out2; console.log("myNumberArray: ", myNumberArray); function showMe(VAL) { var parent = document.getElementById('out2'); parent.innerHTML = VAL; if (calcTotal(myNumberArray) > 21) { alert('you lose'); } }; document.getElementById('stand').onclick = function stand() { var compterDeal1 = Math.floor(Math.random() *10 + 1); var computerCards = compterDeal1; console.log(computerCards); computerArray.push(computerCards); if (computerCards < 21) { stand(); } } var computerArray = []; </script> </body> </html>
Use an unique class with all of then, and call then by class
Add a global integer: var cardNumber = 0; A function to generate an id: function newCardId() { cardNumber ++; return 'uniqueCardId' + cardNumber.toString(); } And use: var newId = newCardId(); $("#cardTable").append("<div class=\"cardLook\" id=\"" + newId + "\"></div>"); Finally to access your new div: $('#' + newId). Note: Escape quotes within a string using backslash!
Random number into div and then let delete divs in sequence. How?
So, i want to make game for my child. Have low experience in JS. Scenario: Have for example 4 square divs with blank bg. After refresh (or win) i want to: Generate random numbers into div (1...4). And show them in them. Then let player delete those divs by clicking on them, but in sequence how divs are numbered. *For example after refresh divs have those numbers 2 3 1 4. So, user has to have rights to delete first div numbered 1 (2 3 _ 4) and so on.* If he clicks on 2 it get error , div stays in place, and user can try again delete right one. It game for learning numbers. I have the begining. Index.html <!DOCTYPE html> <html> <head> <link rel="stylesheet" type="text/css" href="css.css"> <script src="http://code.jquery.com/jquery-latest.min.js" type="text/javascript"></script> </head> <body> <div class="grid"> <div id="Uleft"></div> <div id="Uright"></div> <div id="Dleft"></div> <div id="Dright"></div> </div> <script> $(".grid").children( "div" ).on("click", function(){ $(this).css("visibility", "hidden"); }); </script> </body> </html> css.css .grid { margin: 0 auto; width: 430px; } #Uleft, #Uright, #Dleft, #Dright { border: 1px solid black; width: 200px; height: 200px; margin: 5px; } #Uright { float: right; background-color: red; } #Uleft { float: left; background-color: blue; } #Dleft { float: left; background-color: green; } #Dright { float: right; background-color: yellow; } So, i guess i have use jQuery as well, but i dont know how to make it dynamic and different after refresh of page. Please help :) http://jsfiddle.net/bNa8Z/
There are a few things you have to do. First you have to create a random array which you use sort and Math.random() to do then, you need insert the text in the squares. Find the min of the visible squares and then remove/alert depending if its the min value. // sort by random var rnd = [1,2,3,4].sort(function() { return .5 - Math.random(); }); // map over each div in the grid $('.grid div').each(function(ii, div) { $(div).text(rnd[ii]); // set the text to the ii'th rnd }); function minVisible() { var min = 1e10; // a big number $('.grid div').each(function(ii, div) { // if not visible ignore if ($(div).css('visibility') === "hidden" ){ return; } // if new min, store var curFloatValue = parseFloat($(div).text()); console.log(curFloatValue); if (curFloatValue < min) { min = curFloatValue; } }); return min; } $(".grid").children( "div" ).on("click", function(){ var clickedFloatValue = parseFloat($(this).text()); if (clickedFloatValue == minVisible()) { $(this).css("visibility", "hidden"); } else { alert("sorry little tike"); } }); Updated jsfiddle http://jsfiddle.net/bNa8Z/2/
Roughly this is what it would look like: var selected = {}; $('.grid div').each(function(idx){ var is_done = false; do{ var rand = Math.floor((Math.random()*4)+1); if( selected[rand] == undefined ){ $(this).html(rand); selected[rand] = 1; is_done = true; } }while(!is_done); }); alert("Start the game"); var clicked = []; $('.grid').on('click', 'div.block', function(){ var num = $(this).html(); if( num == clicked.length + 1 ){ //alert(num + " is correct!"); clicked.push(num); $(this).addClass("hide"); }else{ alert("Failed!"); } if( clicked.length == 4 ){ alert("You Won!"); } }); HTML: <div class="grid"> <div class="block" id="Uleft"></div> <div class="block" id="Uright"></div> <div class="block" id="Dleft"></div> <div class="block" id="Dright"></div> </div> Added CSS: #Uleft, #Uright, #Dleft, #Dright { position:absolute; ... } #Uright { left:220px; top:0px; background-color: red; } #Uleft { left:0px; top:0px; background-color: blue; } #Dleft { left:0px; top:220px; background-color: green; } #Dright { left:220px; top:220px; background-color: yellow; } .hide { display: none; } See the working version at JSFiddle You will need to re-"run" the fiddle per game.
please try it. I think that It will help you. var generated_random_number_sequesce = function(){ var number_array = []; var number_string = ''; var is_true = true; while(is_true){ var ran_num = Math.round(1 + Math.random()*3); if(number_string.indexOf(ran_num) == -1 && ran_num < 5){ number_array[number_array.length] = ran_num; number_string = number_string + ran_num; if(number_array.length == 4){is_true = false;} } } return number_array; } var set_number_on_divs = function(){ var number_array = generated_random_number_sequesce(); $(".grid").children().each(function(index, element){ $(this).attr('data-div_number' , number_array[index]); }); } set_number_on_divs() var clicked = 0; $(".grid").children( "div" ).on("click", function(){ clicked += 1; var current_div_number = $(this).attr('data-div_number'); if( parseInt(current_div_number) == clicked){ $(this).css("visibility", "hidden"); } else{ clicked -= 1; alert('error'); } });
cannot input data using innerHTML
This code displays all numbers in the array on the left, odd numbers in the middle and the even ones on the right, but the div center does not accept the values. checked over it and debugged for about half an hour and nothing. The code used to input the data for left and right is the same but for center it does not work. when checking through the console center has the values stored just like left and right but it was not able to insert the stored values into the div. Any help would be greatly appreciated. <style> #left{ width : 30%; float: left; } #right{ width: 30%; float: left; } #center{ width: 30%; float: left; } </style> </head> <body> <div id = "left"></div> <div id = "right"></div> <div id = "center"></div> <script> var mya = new Array(50); var l = document.getElementById("left"); var r = document.getElementById("right"); var c = document.getElementById("center"); var left = ''; var right = ''; var center = ''; for(var c = 0;c<mya.length;c++){ mya[c] = parseInt(Math.random() * 100); left+="<li>" + mya[c] +"</li>"; if (mya[c]%2){right+="<li>" + mya[c] +"</li>";} else{center+="<li>" + mya[c] +"</li>";} } l.innerHTML+="<ul>" + left + "</ul>"; r.innerHTML+="<ul>" + right + "</ul>"; c.innerHTML+="<ul>" + center + "</ul>"; </script> </body>
(in addition to the typo I noted in the comments above) You're overwriting c in your loop and that's causing the issue. Change: var c = document.getElementById("center"); // and c.inerHTML to var ctr = document.getElementById("center"); // and ctr.innerHTML jsFiddle example
javascript onclick, anonymous function
I am a beginning javascript programmer. I am trying to create something similar to Lightbox 2, but much simpler. The only reason why I want to do it from scratch on my own is so that I can learn. However, I've been stuck on the last critical part where it displays the image. I believe the problem lies where I try to use onclick with assignment to an anonymous function:elem[i].onclick = function (){liteBoxFocus(imgSource,imgTitle); return false;}; . If you run my code and try clicking on the google logo it'll bring up the yahoo logo and title instead of google's logo and title. However when you click on the yahoo logo it works fine so it seems that the anonymous function only holds for the last loop. Thanks in advance!!! I have placed the entire CSS/JS/XHTML in one page for your convenience. <html> <head> <title>Erik's Script</title> <style type="text/css"> #liteBoxBg, #liteBox { display: none; } #liteBoxBg { background-color: #000000; height: 100%; width:100%; margin:0px; position: fixed; left:0px; top: 0px; filter:alpha(opacity=80); -moz-opacity:0.8; -khtml-opacity: 0.8; opacity: 0.8; z-index: 40; } #liteBox { background-color:#fff; padding: 10px; position:absolute; top:10%; border: 1px solid #ccc; width:auto; text-align:center; z-index: 50; } </style> <script type="text/javascript"> window.onload = start; function start(){ var imgTitle = "No title"; var imgSource; var elem = document.getElementsByTagName("a"); var i; //Dynamically insert the DIV's to produce effect var newDiv = document.createElement('div'); newDiv.setAttribute("id", "liteBox"); document.getElementsByTagName("body")[0].appendChild(newDiv); newDiv = document.createElement('div'); newDiv.setAttribute("id", "liteBoxBg"); document.getElementsByTagName("body")[0].appendChild(newDiv); //Check those anchors with rel=litebox for(i = 0;i < elem.length;i++){ if(elem[i].rel == "litebox"){ imgSource = elem[i].href.toString(); imgTitle = elem[i].title; elem[i].childNodes[0].style.border="0px solid #fff"; elem[i].onclick = function (){liteBoxFocus(imgSource,imgTitle); return false;}; } } //When foreground is clicked, close lite box document.getElementById("liteBoxBg").onclick = liteBoxClose; } //Brings up the image with focus function liteBoxFocus(source,title){ document.getElementById("liteBox").style.display = "block"; document.getElementById("liteBox").innerHTML = "<h1>" + title + "</h1>" + "<img src='" + source + "'/><br />" + "<a href='#' onclick='liteBoxClose();'><img src='images/litebox_close.gif' border='0' alt='close'/></a>"; document.getElementById("liteBoxBg").style.display = "block"; } //closes lite box function liteBoxClose(){ document.getElementById("liteBox").style.display = "none"; document.getElementById("liteBoxBg").style.display = "none"; return false; } </script> </head> <body> <img src="http://www.google.com/intl/en_ALL/images/logo.gif" alt="" /> <a href=" http://www.barbariangroup.com/assets/users/bruce/images/0000/4121/yahoo_logo.jpg" rel="litebox" title="Yahooo Logo"><img src=" http://www.barbariangroup.com/assets/users/bruce/images/0000/4121/yahoo_logo.jpg" alt="" /></a> </body> </html>
Your event handlers form a closure that remember a "live" pointer to the variables in the enclosing scope. So when they are actually executed, they have the last value imgSource and imgTitle had. Instead, you can use this pattern to localize the variable values. This will create copies of source and title inside getClickHandler each time it is called. The returned function hence remembers the values in that iteration of the loop. //Check those anchors with rel=litebox for(i = 0;i < elem.length;i++){ if(elem[i].rel == "litebox"){ imgSource = elem[i].href.toString(); imgTitle = elem[i].title; elem[i].childNodes[0].style.border="0px solid #fff"; elem[i].onclick = getClickHandler(imgSource, imgTitle); } } //Brings up the image with focus function getClickHandler(source,title){ return function() { document.getElementById("liteBox").style.display = "block"; document.getElementById("liteBox").innerHTML = "<h1>" + title + "</h1>" + "<img src='" + source + "'/><br />" + "<a href='#' onclick='liteBoxClose();'><img src='images/litebox_close.gif' border='0' alt='close'/></a>"; document.getElementById("liteBoxBg").style.display = "block"; } }