SitePoint Sponsor

User Tag List

Results 1 to 11 of 11

Thread: OK, I blew it!

  1. #1
    SitePoint Zealot matches's Avatar
    Join Date
    Aug 2006
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    OK, I blew it!

    I should have just posted my real problem rather than a mocked up version of it. Here is my original post:

    http://www.sitepoint.com/forums/showthread.php?t=513439

    Anyway, in my real world situation. I have this CMS that I am using to monitor my front door. What I am trying to do is loop through all of the div ids and add an onclick to all the a tags within that div. on line 15, the alert() is added to the link. The reference to the mboxes array is undefined because for some reason the value of i is not available.

    What am I doing wrong?

    Thanks a lot!


    HTML Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <html>
    	<head>
    		<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
    		<title>Untitled Document</title>
    		<script type="text/javascript">
    			function start(){
    				var pageSections = ["header", "candy_cane", "left-column", "featured_products", "shoppingPicks"];
    	      var mboxes = ["FDmonitorTopNav", "FDmonitorPromo", "FDmonitorLeftNav", "FDmonitorFeaturedProducts", "FDmonitorBlogListings", "FDmonitorTopProducts"]
            for (var i=0; i < pageSections.length; i++) {
              var elementLink = document.getElementById(pageSections[i]).getElementsByTagName('a');
              for (var x=0; x < elementLink.length; x++) {
              elementLink[x].onclick = function()
              {
                alert('MS-FDmonitor', mboxes[i]);
              }
            	}
          	}
    			}			
    		</script>
    	</head>
    	<body onload="start()">
    		<div id="header">
    			<a href="#">test</a>
    		</div>
    		<div id="candy_cane">
    			<a href="#">test</a>
    		</div>
    		<div id="left-column">
    			<a href="#">test</a>
    		</div>
    		<div id="featured_products">
    			<a href="#">test</a>
    		</div>
    		<div id="shoppingPicks">
    			<a href="#">test</a>
    		</div>
    	</body>
    </html>
    Last edited by matches; Nov 9, 2007 at 16:16. Reason: I had a 0 in an assignment (var elementLink = document.getElementById(pageSections[i]).getElementsByTagName('a');)

  2. #2
    SitePoint Zealot matches's Avatar
    Join Date
    Aug 2006
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    One thing I have noticed is, if I on have the array in in the alert function then I display the "a value from the array" it just happens to be the wrong value. I showing the last element of that pageSections array. I realize that probably ahas something to do with alert function. I not actually trying to call an alert. It makes too hard to test with the real function.

    edited: Yep, turns out the biggest issue with this script is that fact mboxes[i] is always the last element of the array. If I can get that figured out then this script should work perfectly.
    Last edited by matches; Nov 9, 2007 at 16:45.

  3. #3
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Can you explain what mboxes is? Are those IDs of other elements? Is something going to happen to them when you click those links in the divs (pageSections) that you're attaching the click events to?

  4. #4
    SitePoint Zealot matches's Avatar
    Join Date
    Aug 2006
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi Raffles,

    mboxes are little JS functions that record clicks through this CMS called Offermatica. Instead of that alert that is there right now there would be a function called mboxTrackClick(). So basically when mboxTrackClick() called it looks for an mbox that would referenced by the whatever element is at mboxes[i]. Hope that makes sense.

    Thanks again for all your help.

  5. #5
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    I can't say I perfectly understand what you mean... what exactly is supposed to happen when a link is clicked?

  6. #6
    SitePoint Zealot matches's Avatar
    Join Date
    Aug 2006
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    OK, well the that script is supposed loop through and add an onclick to all links within a page. When the link is clicked it calls mboxTrackClick() and passes MS-FDmonitor and mboxes[i] (could = FDmonitorPromo for instance.) Then record that mboxTrackClick().

    But, the big issue is why mboxes[i] is always set the last element of mboxes[].

    Thanks again

  7. #7
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Right, so are "FDmonitorTopNav", "FDmonitorPromo", "FDmonitorLeftNav", etc. elements on the page?

    Also, are there going to be more than one link in each pageSection (at the moment there is only one, the "test" links)?

    The reason mboxes[i] is the last one is because of closures. I'm not going to pretend I completely understand them, but in this case the thing is that javascript loops through the elements and then stops, leaving the value of mboxes[i] as the last one. So when the event actually happens, you get the last one every time. The solution is to use this.

    Code Javascript:
    function start(){
    	var pageSections = ["header", "candy_cane", "left-column", "featured_products", "shoppingPicks"];
      var mboxes = ["FDmonitorTopNav", "FDmonitorPromo", "FDmonitorLeftNav", "FDmonitorFeaturedProducts", "FDmonitorBlogListings", "FDmonitorTopProducts"]
      for (var i=0; i < pageSections.length; i++) {
        var elementLink = document.getElementById(pageSections[i]).getElementsByTagName('a');
        for (var x=0; x < elementLink.length; x++) {
          elementLink[x].onclick = func;
      	}
    	}
    }
    function func() {
      this.style.backgroundColor = 'red'; // "this" refers to the link that was actually clicked
    }
    So the link that was clicked will get a red background.
    But I still don't understand the relationship between mboxes and pageSections. The thing is, it's difficult to get the value of the iterator in the previous loop. so if you can walk the DOM in order to access the mbox that is related to the link that was clicked, that is the best solution. But I still don't know what mboxes are - are they elements on the page? If so it would be useful to see the HTML for them. You could also use a "rel" attribute in the links to make the connection with mboxes. Then you wouldn't need an array in your javascript and you could add links as you please and it would still work.

  8. #8
    SitePoint Zealot matches's Avatar
    Join Date
    Aug 2006
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks Raffles!

    mboxes ("FDmonitorTopNav", "FDmonitorPromo", "FDmonitorLeftNav", etc.) are just variables to identify that a a link was clicked within a pageSection. They are passed to another function that tracks the click

    There will be more than one link in each section.

    In the solution that you gave. How can I use this. to add a function with variables rather than change the background color?

    Thanks again for all your help

  9. #9
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    OK, so then:
    • #header is the same as FDMonitorTopNav
    • #candy_cane = FDmonitorPromo
    • #left-column = FDmonitorLeftNav
    • #featured_products = FDmonitorFeaturedProducts
    • ??? = FDmonitorBlogListings
    • #shoppingPicks = FDmonitorTopProducts
    Is that right? If so, it is stupid to be doing it like you are doing it. This does what you want:
    Code Javascript:
    <html>
    <head>
    <script>
    function init(){
      var pageSections = ["a", "b", "c", "d"];
      for (var i=0; i < pageSections.length; i++) {
        handleClicks(i, document.getElementById(pageSections[i]));
      }
    }
    function handleClicks(i, section) {
      var mboxes = ["FDmonitorTopNav", "FDmonitorPromo", "FDmonitorLeftNav", "FDmonitorFeaturedProducts", "FDmonitorBlogListings", "FDmonitorTopProducts"];
      var elementLink = section.getElementsByTagName('a');
      for (var x=0; x < elementLink.length; x++) {
        elementLink[x].onclick = function() {
          alert(mboxes[i]);
        }
      }
    }
    window.onload = init;
    </script>
    <style>div {margin:1em 0; border:1px solid red;}</style>
    </head>
    <body>
    <div id="a">
    <a href="#">test</a>
    <a href="#">test</a>
    <a href="#">test</a>
    </div>
    <div id="b">
    <a href="#">test</a>
    <a href="#">test</a>
    <a href="#">test</a>
    </div>
    <div id="c">
    <a href="#">test</a>
    <a href="#">test</a>
    </div>
    <div id="d">
    <a href="#">test</a>
    <a href="#">test</a>
    </div>
    </body>
    </html>
    So instead of the alert(), you have your link tracking function. By far the most sensible thing to do, though, would be to give each mbox with "FDxxx" names the section id. Then you could do this:
    Code Javascript:
    <html>
    <head>
    <script>
    function init(){
      var pageSections = ["FDmonitorTopNav", "FDmonitorPromo", "FDmonitorLeftNav", "FDmonitorFeaturedProducts", "FDmonitorBlogListings", "FDmonitorTopProducts"];
      for (var i=0; i < pageSections.length; i++) {
        handleClicks(i, document.getElementById(pageSections[i]));
      }
    }
    function handleClicks(i, section) {
      var elementLink = section.getElementsByTagName('a');
      for (var x=0; x < elementLink.length; x++) {
        elementLink[x].onclick = function() {
          alert(section.id);
        }
      }
    }
    window.onload = init;
    </script>
    <style>div {margin:1em 0; border:1px solid red;}</style>
    </head>
    <body>
    <div id="FDmonitorTopNav">
    <a href="#">test</a>
    <a href="#">test</a>
    <a href="#">test</a>
    </div>
    <div id="FDmonitorPromo">
    <a href="#">test</a>
    <a href="#">test</a>
    <a href="#">test</a>
    </div>
    <div id="FDmonitorLeftNav">
    <a href="#">test</a>
    <a href="#">test</a>
    </div>
    <div id="FDmonitorFeaturedProducts">
    <a href="#">test</a>
    <a href="#">test</a>
    </div>
    <div id="FDmonitorBlogListings">
    <a href="#">test</a>
    <a href="#">test</a>
    </div>
    <div id="FDmonitorTopProducts">
    <a href="#">test</a>
    <a href="#">test</a>
    </div>
    </body>
    </html>
    It makes more sense than having two sets of names that refer to the same thing and keep switching between them.

  10. #10
    SitePoint Zealot matches's Avatar
    Join Date
    Aug 2006
    Posts
    196
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Great, worked perfectly.

    Quote Originally Posted by Raffles View Post
    By far the most sensible thing to do, though, would be to give each mbox with "FDxxx" names the section id.
    Quote Originally Posted by Raffles View Post
    It makes more sense than having two sets of names that refer to the same thing and keep switching between them.
    I totally agree with your comment, but sometimes you can't have a perfect situation like that. I have to share this tracking account and need easily identifiable variables (FDmonitorTopNav, works for us) and the div ids are already in place. Not to mention the rest of the minutia involved.

    In any case thanks a bunch!

  11. #11
    I meant that to happen silver trophybronze trophy Raffles's Avatar
    Join Date
    Sep 2005
    Location
    Tanzania
    Posts
    4,662
    Mentioned
    2 Post(s)
    Tagged
    0 Thread(s)
    Fair enough. Can't have everything.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •