Thread: Explorer errors

Page 1 of 2 12 Last
  • Jump to page:
    #1
  1. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2004
    Posts
    292
    Rep Power
    15

    Explorer errors


    Works fine in firefox and safari, am not a javascript developer but know a little. This will probably be easy to spot. I have a simple rollover script which works fine, finally managed to debug the problem to at least see what it is in explorer 6 and 7.

    I just get error on page and found that it is to do with my code within the html.

    Here is the code for the html page:

    Code:
    <a href="backbox/images/solution_01.jpg" rel="lightbox[slide]" caption="1 : Priming big pumps<br>&lt;a href=&quot;pdfs/solution_01.pdf&quot;&gt;Click here for more information&lt;/a&gt;" onMouseOver="change('solution01','backbox/images/rolls/solution01roll.gif');" onMouseOut="change('solution01','backbox/images/rolls/solution01.gif');"><img name="solution01" src="backbox/images/rolls/solution01.gif"></a>
    
    <a href="backbox/images/solution_02.jpg" rel="lightbox[slide]" caption="2 : Well pointing<br>&lt;a href=&quot;pdfs/solution_02.pdf&quot;&gt;Click here for more information&lt;/a&gt;" onMouseOver="change('solution02','backbox/images/rolls/solution02roll.gif');" onMouseOut="change('solution02','backbox/images/rolls/solution02.gif');"><img name="solution02" src="backbox/images/rolls/solution02.gif"></a>
    I get an error in explorer... it is within the code here as the external js file gives no errors.
  2. #2
  3. 4:04 Time Not Found
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Jan 2004
    Location
    Northern Virginia
    Posts
    2,273
    Rep Power
    343
    You didn't really provide enough information to determine what the issue is... providing us with the full "change" function would be useful.
    I am so smart, I am so smart, S.M.R.T ... I mean S.M.A.R.T.

    Stop Using Pop-Ups
  4. #3
  5. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2004
    Posts
    292
    Rep Power
    15
    Here is the actual js script below. I only posted up 2 of the images in my previous code.

    After testing the page it is the code I gave where the error is, as that is what explorer 6 and 7 tell me.

    Code:
    function newImage( imgSrc ){
    	var imgName = new Image();
    	imgName.src = imgSrc;
    	return imgName;
    }
    function change( imgName, imgLocation )
    {
    	document[imgName].src = imgLocation ;
    }
    var preloadFlag = false;
    function loadImages()
    {
    	if (document.images)
    	{
    	//****Edit this list to include rollover state images ****
    	//****Example: aboutus_over = newImage( "images/aboutus-over.gif" );
    		solution01 = newImage("backbox/images/rolls/solution01roll.gif");
    		solution02 = newImage("backbox/images/rolls/solution02roll.gif");
    		solution03 = newImage("backbox/images/rolls/solution03roll.gif");
    		solution04 = newImage("backbox/images/rolls/solution04roll.gif");
    		solution05 = newImage("backbox/images/rolls/solution05roll.gif");
    		solution06 = newImage("backbox/images/rolls/solution06roll.gif");
    		solution07 = newImage("backbox/images/rolls/solution07roll.gif");
    		solution08 = newImage("backbox/images/rolls/solution08roll.gif");
    		solution09 = newImage("backbox/images/rolls/solution09roll.gif");
    		solution10 = newImage("backbox/images/rolls/solution10roll.gif");
    		solution11 = newImage("backbox/images/rolls/solution11roll.gif");
    		solution12 = newImage("backbox/images/rolls/solution12roll.gif");
    		solution13 = newImage("backbox/images/rolls/solution13roll.gif");
    		solution14 = newImage("backbox/images/rolls/solution14roll.gif");
    		solution15 = newImage("backbox/images/rolls/solution15roll.gif");
    		solution16 = newImage("backbox/images/rolls/solution16roll.gif");
    		solution17 = newImage("backbox/images/rolls/solution17roll.gif");
    		solution18 = newImage("backbox/images/rolls/solution18roll.gif");
    		preloadFlag = true;
    	}
    }
  6. #4
  7. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2004
    Posts
    292
    Rep Power
    15
    Please note the code in the html has another function. There is minimal javascript.
  8. #5
  9. 4:04 Time Not Found
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Jan 2004
    Location
    Northern Virginia
    Posts
    2,273
    Rep Power
    343
    To start with some stuff I didn't see, before I asked for your code..

    This HTML is totally invalid for two reasons: (I can't even guess what you're trying to do with it)
    1. You cannot put HTML tags into HTML attributes, it is forbidden. It will probably also cause the browser to render your code really oddly.
    2. caption is not a valid attribute of the A Element, see the W3C specification for more information.
    Code:
    <a 
    	href="backbox/images/solution_01.jpg" 
    	rel="lightbox[slide]" 
    	caption="1 : Priming big pumps<br><a href="pdfs/solution_01.pdf">Click here for more information</a>" 
    	onMouseOver="change('solution01','backbox/images/rolls/solution01roll.gif');" 
    	onMouseOut="change('solution01','backbox/images/rolls/solution01.gif');"
    >
    	<img name="solution01" src="backbox/images/rolls/solution01.gif">
    </a>
    
    <a 
    	href="backbox/images/solution_02.jpg" 
    	rel="lightbox[slide]" 
    	caption="2 : Well pointing<br><a href="pdfs/solution_02.pdf">Click here for more information</a>" 
    	onMouseOver="change('solution02','backbox/images/rolls/solution02roll.gif');" 
    	onMouseOut="change('solution02','backbox/images/rolls/solution02.gif');"
    >
    	<img name="solution02" src="backbox/images/rolls/solution02.gif">
    </a>
    Here's a modified version of your code, which will probably work a bit better for you.
    Using a simplified version of your anchor, you can add the other stuff in, when you get it sorted out.
    Code:
    <a href="backbox/images/solution_01.jpg"
    	onmouseover="imageChange('solution01',mouseOver[0]);" 
    	onmouseout="imageChange('solution01',mouseOut[0]);">
    	<img id="solution01" src="backbox/images/rolls/solution01.gif">
    </a>
    And some JavaScript, this probably isn't the best way to write this, but I don't feel like mucking around with it anymore.
    Code:
    function buildImage(src){
    	var imgElement = new Image();
    	imgElement.src = src;
    	return imgElement;
    }
    function imageChange(imgID,requestedImage) {
    	document.getElementById(imgName).src = requestedImage.src;
    }
    
    function loadImages() {
    	var mouseOver = new Array();
    	    mouseOver[0]  = buildImage("backbox/images/rolls/solution01roll.gif");
    	    mouseOver[1]  = buildImage("backbox/images/rolls/solution02roll.gif");
    	    mouseOver[2]  = buildImage("backbox/images/rolls/solution03roll.gif");
    	    mouseOver[3]  = buildImage("backbox/images/rolls/solution04roll.gif");
    	    mouseOver[4]  = buildImage("backbox/images/rolls/solution05roll.gif");
    	    mouseOver[5]  = buildImage("backbox/images/rolls/solution06roll.gif");
    	    mouseOver[6]  = buildImage("backbox/images/rolls/solution07roll.gif");
    	    mouseOver[7]  = buildImage("backbox/images/rolls/solution08roll.gif");
    	    mouseOver[8]  = buildImage("backbox/images/rolls/solution09roll.gif");
    	    mouseOver[9]  = buildImage("backbox/images/rolls/solution10roll.gif");
    	    mouseOver[10] = buildImage("backbox/images/rolls/solution11roll.gif");
    	    mouseOver[11] = buildImage("backbox/images/rolls/solution12roll.gif");
    	    mouseOver[12] = buildImage("backbox/images/rolls/solution13roll.gif");
    	    mouseOver[13] = buildImage("backbox/images/rolls/solution14roll.gif");
    	    mouseOver[14] = buildImage("backbox/images/rolls/solution15roll.gif");
    	    mouseOver[15] = buildImage("backbox/images/rolls/solution16roll.gif");
    	    mouseOver[16] = buildImage("backbox/images/rolls/solution17roll.gif");
    	    mouseOver[17] = buildImage("backbox/images/rolls/solution18roll.gif");
    	    
    	var mouseOut = new Array();
    	    mouseOut[0]  = buildImage("backbox/images/rolls/solution01.gif");
    	    mouseOut[1]  = buildImage("backbox/images/rolls/solution02.gif");
    	    mouseOut[2]  = buildImage("backbox/images/rolls/solution03.gif");
    	    mouseOut[3]  = buildImage("backbox/images/rolls/solution04.gif");
    	    mouseOut[4]  = buildImage("backbox/images/rolls/solution05.gif");
    	    mouseOut[5]  = buildImage("backbox/images/rolls/solution06.gif");
    	    mouseOut[6]  = buildImage("backbox/images/rolls/solution07.gif");
    	    mouseOut[7]  = buildImage("backbox/images/rolls/solution08.gif");
    	    mouseOut[8]  = buildImage("backbox/images/rolls/solution09.gif");
    	    mouseOut[9]  = buildImage("backbox/images/rolls/solution10.gif");
    	    mouseOut[10] = buildImage("backbox/images/rolls/solution11.gif");
    	    mouseOut[11] = buildImage("backbox/images/rolls/solution12.gif");
    	    mouseOut[12] = buildImage("backbox/images/rolls/solution13.gif");
    	    mouseOut[13] = buildImage("backbox/images/rolls/solution14.gif");
    	    mouseOut[14] = buildImage("backbox/images/rolls/solution15.gif");
    	    mouseOut[15] = buildImage("backbox/images/rolls/solution16.gif");
    	    mouseOut[16] = buildImage("backbox/images/rolls/solution17.gif");
    	    mouseOut[17] = buildImage("backbox/images/rolls/solution18.gif");
    }               
    loadImages();
    I am so smart, I am so smart, S.M.R.T ... I mean S.M.A.R.T.

    Stop Using Pop-Ups
  10. #6
  11. c0der
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2005
    Location
    Vancouver
    Posts
    664
    Rep Power
    159
    Originally Posted by vbrtrmn
    And some JavaScript, this probably isn't the best way to write this, but I don't feel like mucking around with it anymore.
    Okay, please forgive me, but I can't resist...

    Code:
    function loadImages() {
    	var mouseOver = new Array();
    	    mouseOver[0]  = buildImage("backbox/images/rolls/solution01roll.gif");
    	    mouseOver[1]  = buildImage("backbox/images/rolls/solution02roll.gif");
    	    mouseOver[2]  = buildImage("backbox/images/rolls/solution03roll.gif");
    	    mouseOver[3]  = buildImage("backbox/images/rolls/solution04roll.gif");
    	    mouseOver[4]  = buildImage("backbox/images/rolls/solution05roll.gif");
    	    mouseOver[5]  = buildImage("backbox/images/rolls/solution06roll.gif");
    	    mouseOver[6]  = buildImage("backbox/images/rolls/solution07roll.gif");
    	    mouseOver[7]  = buildImage("backbox/images/rolls/solution08roll.gif");
    	    mouseOver[8]  = buildImage("backbox/images/rolls/solution09roll.gif");
    	    mouseOver[9]  = buildImage("backbox/images/rolls/solution10roll.gif");
    	    mouseOver[10] = buildImage("backbox/images/rolls/solution11roll.gif");
    	    mouseOver[11] = buildImage("backbox/images/rolls/solution12roll.gif");
    	    mouseOver[12] = buildImage("backbox/images/rolls/solution13roll.gif");
    	    mouseOver[13] = buildImage("backbox/images/rolls/solution14roll.gif");
    	    mouseOver[14] = buildImage("backbox/images/rolls/solution15roll.gif");
    	    mouseOver[15] = buildImage("backbox/images/rolls/solution16roll.gif");
    	    mouseOver[16] = buildImage("backbox/images/rolls/solution17roll.gif");
    	    mouseOver[17] = buildImage("backbox/images/rolls/solution18roll.gif");
    	    
    	var mouseOut = new Array();
    	    mouseOut[0]  = buildImage("backbox/images/rolls/solution01.gif");
    	    mouseOut[1]  = buildImage("backbox/images/rolls/solution02.gif");
    	    mouseOut[2]  = buildImage("backbox/images/rolls/solution03.gif");
    	    mouseOut[3]  = buildImage("backbox/images/rolls/solution04.gif");
    	    mouseOut[4]  = buildImage("backbox/images/rolls/solution05.gif");
    	    mouseOut[5]  = buildImage("backbox/images/rolls/solution06.gif");
    	    mouseOut[6]  = buildImage("backbox/images/rolls/solution07.gif");
    	    mouseOut[7]  = buildImage("backbox/images/rolls/solution08.gif");
    	    mouseOut[8]  = buildImage("backbox/images/rolls/solution09.gif");
    	    mouseOut[9]  = buildImage("backbox/images/rolls/solution10.gif");
    	    mouseOut[10] = buildImage("backbox/images/rolls/solution11.gif");
    	    mouseOut[11] = buildImage("backbox/images/rolls/solution12.gif");
    	    mouseOut[12] = buildImage("backbox/images/rolls/solution13.gif");
    	    mouseOut[13] = buildImage("backbox/images/rolls/solution14.gif");
    	    mouseOut[14] = buildImage("backbox/images/rolls/solution15.gif");
    	    mouseOut[15] = buildImage("backbox/images/rolls/solution16.gif");
    	    mouseOut[16] = buildImage("backbox/images/rolls/solution17.gif");
    	    mouseOut[17] = buildImage("backbox/images/rolls/solution18.gif");
    }
    Joining us from the planet Refactoron, it's Captain Obvious, on code review! Everyone pay attention, because once Captain Obvious has spoken, he tends to depart in a flash! "You should have used a loop there." *shhoof*

    Code:
    function loadImages() {
      var mouseOver = [];
      var mouseOut  = [];
    
      for (var i = 1; i <= 18; i++) {
        mouseOver.push(
          buildImage("backbox/images/rolls/solution" + (i < 10 ? "0" : "") + i + "roll.gif")
        );
        mouseOut.push(
          buildImage("backbox/images/rolls/solution" + (i < 10 ? "0" : "") + i + ".gif")
        );
      }
    }
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //    You know, I think that just might have saved us some typing.
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    //
    In fact, since we're just leaving the mouseOver/mouseOut arrays for the garbage collector, and since there's no reason to preload images twice, we might as well reduce it further:

    Code:
    for (var i = 1; i <= 18; i++) {
      buildImage("backbox/images/rolls/solution" + (i < 10 ? "0" : "") + i + "roll.gif")
      buildImage("backbox/images/rolls/solution" + (i < 10 ? "0" : "") + i + ".gif")
    }
    That's provided of course that the mouseover's are being done using the OPs choice method, by spelling out the URLs all over again. With your technique though, vbrtrm, I guess that function's alright but mouseOver and mouseOut would really have to be global variables (or exposed globally some other way).

    Comments on this post

    • GameYin agrees : LOL
    Last edited by Joseph Taylor; May 21st, 2008 at 01:36 AM.
  12. #7
  13. Contributing User
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Aug 2005
    Location
    Bucharest ROMANIA
    Posts
    2,524
    Rep Power
    609
    If so, and as it is nothing but a rollover, why not a simple dynamic code. I put a penny on an even shorter rollover solution:
    Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"  "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <title>Untitled Document</title>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <meta http-equiv="Content-Style-Type" content="text/css">
    <meta http-equiv="Content-Script-Type" content="text/javascript">
    <title>Untitled Document</title>
    <script type="text/javascript">
    function rollon(){
    this.src=this.src.replace(/\.gif/,'roll.gif');
    }
    function rolloff(){
    this.src=this.src.replace(/roll\.gif/,'.gif');
    }
    onload=function(){
    var i=1, img;
    while(img=document.getElementsByName('solution0'+[i++])[0]){
    img.onmouseover=rollon;
    img.onmouseout=rolloff;
    }
    }
    </script>
    </head>
    <body>
    <a href="backbox/images/solution_01.jpg"><img name="solution01" src="backbox/images/rolls/solution01.gif"></a>
    <a href="backbox/images/solution_02.jpg"><img name="solution02" src="backbox/images/rolls/solution02.gif"></a>
    ...
    </body>
    </html>

    Comments on this post

    • Joseph Taylor agrees : Much simpler overall. Somewhere in the pruning process it lost the image preloading feature, but that could be added easily enough.
  14. #8
  15. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2004
    Posts
    292
    Rep Power
    15
    I got this working but now my script I use for the pop up images is not. I have tried 2 version, the rollover code you just gave me and one without any rollovers to see if it was a problem.

    So, I now have the rollover one when you click the image it opens up as I wanted it to in SAFARI and FIREFOX but fails in Internet Explorer. Then I have the version without the rollover and it behaves as it should.

    So there must be something in the javascript code you just gave me that is causing confusion or stopping the other code from working.

    Can you take a look and let me know as I am a complete novice at javascript

    ROLLOVER VERSION:
    http://www.liquivac.co.uk/development/identify_your_solution.html

    Non ROLLEVER VERSION
    http://www.liquivac.co.uk/development/identify_your_solution2.html

    You can see what I mean if you view both of these pages in explorer 6 or 7. If you click the non rollover version first you will see how it should function

    Then if you click the rollover version you can see it does not function as it should.

    Help appreciated as been trying to solve this for 2 days.
    Last edited by zimmo; May 21st, 2008 at 08:16 AM.
  16. #9
  17. c0der
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2005
    Location
    Vancouver
    Posts
    664
    Rep Power
    159
    Originally Posted by KorRedDevil
    I put a penny on an even shorter rollover solution:
    I think mine wins. It's fairly easy to use, too. If you place this script at the end of the body tag (or in the head, calling it onload), all images in a "rollovers" directory will be replaced with their mouseover counterpart. The counterpart's URL is equal to the original's URL, but its filename has "-hover" appended. To give an example, an image situated at http://www.example.com/images/rollovers/roll17.png will become http://www.example.com/images/rollovers/roll17-hover.png when in a hover state. My script doesn't do any preloading, but it could with another couple of lines. The overarching goal was to keep the code shorter than KorRedDevil's. It succeeds partly because it's two lines shorter, but primarily because you don't have to plod through pages of markup to give images names like "solution03".

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!-- Probably shouldn't be text/html... -->
      
      <title>Test Rollover</title>
    </head>
    <body>
      <img src="images/rollovers/solution.jpg" alt="Homework answers?" /><br />
      <img src="images/rollovers/solution42.png" alt="Move your mouse over this image to see the answer to the life the universe and everything.  (It's 42.)" /><br />
      <img src="old_images/rollovers/solution007.gif" alt="A picture of James Bond.  Move your mouse here and die!" /><br />
      <img src="disgusting_images/rollovers/goatse.jpeg" alt="If you're blind, consider yourself lucky." />
      <script type="text/javascript">
      (function() { // This wrapper function could be left out if you don't mind polluting the global namespace
        for (var elements = document.getElementsByTagName("*"), i = elements.length - 1; i >= 0; i--) { 
          (function() { // I need this anonymous function for the closure.  If only closures didn't cost two lines!
             var e = elements[i], m = null;
             if (e.src && (m = e.src.match(/^((?:.*\/)?rollovers\/.+)(\.(?:.+))?$/))) { // The file extension doesn't really matter.  It could be .php for all I care.
               e.onmouseover = function() { e.src = m[1] + "-hover" + m[2]; }; // This dodges a bug in KorRedDevil's code; images break when moused over twice without a mouseout in between
               e.onmouseout  = function() { e.src = m[1] +            m[2]; };
             }
          })();
        }
      })();
      </script>
    </body>
    </html>
    Last edited by Joseph Taylor; May 22nd, 2008 at 01:10 AM.
  18. #10
  19. c0der
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2005
    Location
    Vancouver
    Posts
    664
    Rep Power
    159
    I merged parts of the previous script with KorRedDevil's and ended up with an even shorter version.

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
    <head>
      <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <!-- Probably shouldn't be text/html... -->
      
      <title>Test Rollover</title>
    </head>
    <body>
      <img name="solution1" src="images/rollovers/solution.jpg" alt="Homework answers?" /><br />
      <img name="solution2" src="images/rollovers/solution42.png" alt="Move your mouse over this image to see the answer to the life the universe and everything.  (It's 42.)" /><br />
      <img name="solution3" src="old_images/rollovers/solution007.gif" alt="A picture of James Bond.  Move your mouse here and die!" /><br />
      <img name="solution4" src="disgusting_images/rollovers/goatse.jpeg" alt="If you're blind, consider yourself lucky." />
      <script type="text/javascript">
      for (var n = 1, img = null; img = document.getElementsByName("solution" + n)[0]; n++) {
        img.onmouseover = function() { this.src = this.src.replace(/(\..+)$/, '-hover$1'); };  // I'm not sure, but the use of "this" here might cause IE to fail
        img.onmouseout  = function() { this.src = this.src.replace(/-hover(\..+)$/, '$1'); };
      }
      </script>
    </body>
    </html>
    This is basically the same as Kor's answer, but the mouseover/mouseout functions have been rewritten as inline anonymous functions, and the while loop has been reborn as a for loop; this saves a line of code but marginally increases complexity (and adds to the byte-count). The global namespace has been polluted with a few variables, but there's nothing stopping you from wrapping the whole shebang in a function (lowering the line-count was my number one goal.) I removed the pointless file extension requirement (you're not limited to GIFs now) and made it so the mouseover image names end in "-hover" instead of "roll". You still have to tangle with image naming, but you no longer have to put "0" in front of the solution number. The numbers have to be sequential though! If at any point along your chain there's a missing link, the rest of the chain will fall off (lose hover functionality).

    I still like the previous script better, but depending on what level you're at with JavaScript, this short one might be more manageable.
    Last edited by Joseph Taylor; May 22nd, 2008 at 02:48 AM.
  20. #11
  21. Contributing User
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Aug 2005
    Location
    Bucharest ROMANIA
    Posts
    2,524
    Rep Power
    609
    I don't think there was any bug in my code.

    Now, regarding your variant. It appears to be simpler, but it is not
    Code:
        img.onmouseover = function() { this.src = this.src.replace(/(\..+)$/, 'roll$1'); };  // I'm not sure, but the use of "this" here might cause IE to fail
        img.onmouseout  = function() { this.src = this.src.replace(/roll(\..+)$/, '$1'); };
      }
    this self reference works almost the same, as it means almost the same thing, in both variants (finally, this is the the DOMElement). Now, your variant has a major disadvantage. It it based on a closure which uses a circular reference

    DOMElement -> function -> DOMElement
    Code:
    element.handler=function(){alert(this)}
    This is a circular reference. The JavaScript language specification (mostly known as ECMAScript) defines this behavior like this: when two (or more) objects refer to each other yet no other object refers to any of them, they can all be removed. Therefore, when the page is refreshed the element should get out of scope (should be removed from the DOM) and the handler should go with it, even it's a closure. In any browser except IE, this works as expected.

    IE also, will detect and correctly remove objects creating circular references, except when one or more of those objects are DOM nodes or ActiveX objects.

    This will not influence the browser's brehavior in case of 1 or 2 closures, but will do that for sure in case of many of them

    As a result, the garbage collector will rise which will provoke a memory leak. I've heard that IE7 corrected that bug, but I will not bet on this.

    Now, there are several ways to avoid closures. The simple way is to use an external function:
    Code:
    DOM.element.handler=someFunction;
    someFunction(){
    alert(this)
    }
    In this variant there is no more circular reference, because the function is now a distinct object, not an anonymous.

    This is the reason for I used two external functions, rollon() and rolloff()

    Comments on this post

    • Joseph Taylor agrees
    Last edited by KorRedDevil; May 22nd, 2008 at 03:14 AM.
  22. #12
  23. c0der
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2005
    Location
    Vancouver
    Posts
    664
    Rep Power
    159
    You're absolutely right. Here I was thinking you used rollon() because you didn't understand closures. It seems to have been the other way around.

    It's a travesty in my mind that IE6 would have people give up closures. I've heard of workarounds for the leakage problem that don't involve avoiding closures, but in all honesty, my mind on the issue (mainly because I haven't coded much production JavaScript lately) has been "You want to leak memory, IE? Go ahead. But if you expect to take my closures away you can pry them out of my cold dead hands." I see this as a bug in the browser, not my code, and unless I had a very large, popular website I'd say it's Microsoft's responsibility to fix the issue, not mine. If the end user doesn't want a leaky browser (well, not as leaky) they can use Firefox. I know I'm coming across as stubborn and old fashioned (not unlike the web-masters of yore who coded exclusively for IE) but I don't think the average user will actually associate the slowness of their computer with my site. If the brand isn't affected, it really is Internet Explorer's problem.

    Anyway, thank you for the detailed write up. Memory leaks are definitely something to be mindful of (even if one chooses not to fix them) and your script is indeed better for that reason. I concede defeat.

    However, I do think that if any browser can trigger a mouseover without following up with a mouseout, your script will break. I thought I had seen it happen (by alt-tabbing, or something) but I haven't been able to replicate it on my system so perhaps I'm wrong about that too. Another "bug" (misfeature?) is that the numbering goes from solution01 to solution02 to solution0149 (eventually). That zero has no business being there.
    Last edited by Joseph Taylor; May 22nd, 2008 at 04:05 AM.
  24. #13
  25. c0der
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2005
    Location
    Vancouver
    Posts
    664
    Rep Power
    159
    javascript Code:
    for (var n = 1, img = null; img = document.getElementsByName("solution" + n)[0]; n++) {
      img.onmouseover = function() { this.src = this.src.replace(/(\..+)$/, '-hover$1'); };  // I'm not sure, but the use of "this" here might cause IE to fail
      img.onmouseout  = function() { this.src = this.src.replace(/-hover(\..+)$/, '$1'); };
    }


    Wait a minute... I don't see any closures in the above code. The inner functions do not reference any locally scoped variables, ergo they are not closures. I'll have to test this out on IE next time I'm near the awful mess of a browser (or maybe there's a Mac/Unix tool to test for "closureness"?) There are certainly closures (and circular references) in my first variant, so it's hooped as far as memory management goes--but perhaps there's hope for this second variant?

    I'd like to close with a fun fact.

    Code:
    <input type crash>
    The above code, if included anywhere on an HTML page, will crash IE6.
    Last edited by Joseph Taylor; May 22nd, 2008 at 04:25 AM.
  26. #14
  27. Contributing User
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Aug 2005
    Location
    Bucharest ROMANIA
    Posts
    2,524
    Rep Power
    609
    There is a closure. Watch carefully. You have 2 objects, the DOM element and the function in which the DOM element is self referred again. There is no third object which refers one of those 2. This is one of the definitions for a closure.

    closure:
    object1 calls an anonymous function which calls back the object1

    nonclosure:
    object1 calls object2
    object2 calls by reference a function which calls back the object1
    Last edited by KorRedDevil; May 22nd, 2008 at 07:02 AM.
  28. #15
  29. c0der
    Devshed Novice (500 - 999 posts)

    Join Date
    Jun 2005
    Location
    Vancouver
    Posts
    664
    Rep Power
    159
    Originally Posted by KorRedDevil
    There is a closure. Watch carefully.
    I don't think there is a closure there. The definition you gave does not describe closures as I know them. I'm going to try and explain why, but before I continue please realize that I have no knowledge of JavaScript's inner workings; I have never read a JavaScript interpreter's source, not even that of Narcissus. My grasp of closures didn't even come from studying JavaScript--I acquired my closure chops only after I started to learn Scheme and Lisp.

    A closure is basically a set of local variables preserved for access from outside their local scope. It's not an anonymous inner function, but anonymous inner functions often create closures. For a closure to exist, the following requirements must be met:

    1. You need a "wrapper function". This is just an ordinary function. (No container, no closure.)
    2. There needs to be at least one variable local to the scope created by the wrapper function. (No empty closures. However unlikely, there is a possibility that implementations stupidly ignore this rule.)
    3. Another function needs to be defined within the wrapper function's scope. (You need something to capture the scope.)
    4. This second function must somehow be made accessible from outside of the wrapper function. This can happen a number of ways; you can make it a global variable, return it, set it to a property on an object somewhere else, or use it as an event handler on a DOM element. (If the capturer of the scope dies, the captured scope--the closure--dies with it.)
    I'm not sure (because, like I said, I haven't read the source code to a JavaScript interpreter) but the function from point three may also have to reference a variable local to the container function. This makes conceptual sense, but there's a chance the JavaScript interpreter isn't smart enough to make the optimization--it might just go ahead and create a closure anyhow. I'll call this rule bonus point five, just in case it's true.

    Anyhow, my variation on your script does not fulfill the criteria from point one, point two, or bonus point five. By my own (hopefully correct) definition, this means it is not a closure. But does it cause a memory leak? Possibly. IE memory leakage is something I have a less than complete understanding of; you probably grok this far better than I.

    If you're certain I've got this whole closure thing wrong, I'd very much appreciate a source for the definition you provided (quoted below). I would hate to transmit my misunderstanding of the concept to someone else.

    Originally Posted by KorRedDevil
    You have 2 objects, the DOM element and the function in which the DOM element is self referred again. There is no third object which refers one of those 2. This is one of the definitions for a closure.
    That's enough about closures for now. Here, have another rollover generating script.

    Code:
    // This one attaches rollover functionality to all images with a class-name of "rollover-image".  It probably works, but is untested.
    for (var i = 0, img = null, imgs = document.images; (img = imgs[i]) && /(?:^|\s)rollover-image(?:$|\s)/.test(img.className||""); i++) {
      img.onmouseover = function() { this.src = this.src.replace(/(\..+)$/, '-hover$1'); };
      img.onmouseout  = function() { this.src = this.src.replace(/-hover(\..+)$/, '$1'); };
    }
    Last edited by Joseph Taylor; May 23rd, 2008 at 03:29 AM. Reason: Script was missing a necessary pair of parentheses.
Page 1 of 2 12 Last
  • Jump to page:

IMN logo majestic logo threadwatch logo seochat tools logo