SitePoint Sponsor

User Tag List

Results 1 to 12 of 12
  1. #1
    Designer
    Join Date
    Jun 2006
    Location
    Manila
    Posts
    590
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    JS Noob Needs Help - Element calls a function to self, how?

    I'll try to explain it better through a scenario:

    Imagine a list of links being generated dynamically, so you wouldn't know how many there are, and incrementally naming them would be a bit on the heavy side, so you've embedded a function into each of them to do something during onMouseOver.

    How do I make that function only target the element currently being "hovered" on?

    (For simplicity's sake, let's say I want that function to change that link's color).

    is it: this.style.color = value?

  2. #2
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Yep. Pretty much. If you had an addEvent function that looked like this (fixed for IE too):
    Code:
    function addEvent(el, type, fn) {
      if (window.addEventListener) {
        el.addEventListener(type, fn, false);
      } else if (window.attachEvent) {
        var f = function() {
          fn.call(el, window.event);
        };
        el.attachEvent('on'+type, f);
      }
    }
    You could then add mouseover events like this and change their styles etc...

    Code:
    <div id="example">
      Hello World
    </div>
    <script>
    var example = document.getElementById('example');
    addEvent(example, 'mouseover', function(e) {
      this.style.color = 'blue';
    });
    addEvent(example, 'mouseout', function(e) {
      this.style.color = 'orange';
    });
    </script>

  3. #3
    Designer
    Join Date
    Jun 2006
    Location
    Manila
    Posts
    590
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    *nods head*

    Your code makes mine look like spaghetti.

    So let's say my HTML looks like:

    Code:
    <div id="example">
      <a>Hello World 01</a>
      <a>Hello World 02</a>
      <a>Hello World 03</a>
    </div>
    If I target the div 'example' in my JS (say I'm going by your code), and I hover over the 1st link (notice there are no names or id's for the anchors), will I -only- change the 1st link's color? Because that's essentially what I'm trying to do. Your code has getElementById('example'), which basically means you know you're waiting for example to be called - what happens if, like in my HTML above, you don't have an ID, and you have several elements that are similar (20 anchors for example) - how do you apply the color change ONLY to the anchor you moused over?

    Sorry if I'm being redundant. I just like to understand the "why" as well as the "how".

  4. #4
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well then. You've jumped into something more complex, but nothing that a little "ninjary" can fix. There is a technique called event delegation (read up if you're more interested - otherwise I'm going to tell you how it works right now).

    Basically, you can pass in a parent element (going with your HTML) into the 'addEvent' function (div id=example), and grab the 'target' that fires the event. That works like this:

    Code:
    function get(el) {
      return document.getElementById(el);
    }
    addEvent(get('example'), 'mouseover', function(ev) {
      // grab the event object that was passed to your callback
      var target = ev.target || ev.srcElement; // abstraction for IE
      // target is your <a> element
      if (target.tagName.toLowerCase() == 'a') {
        this.style.color = 'blue';
      }
    });
    
    addEvent(get('example'), 'mouseout', function(ev) {
      // grab the event object that was passed to your callback
      var target = ev.target || ev.srcElement; // abstraction for IE
      // target is your <a> element
      if (target.tagName.toLowerCase() == 'a') {
        this.style.color = 'orange';
      }
    });
    If you don't want to do the event delegation example, you could always attach a listener to each and every anchor element within your (div id=example). It 'costs' more, but it's usually 'sometimes' easier to manage. That would look like this:

    Code:
    // i'll break out the functions too, instead of anonymous functions
    function changeToOrange() {
      this.style.color = 'orange';
    }
    function changeToBlue() {
      this.style.color = 'blue';
    }
    var anchorElements = get('example').getElementsByTagName('a');
    for ( var i=0, el; el=anchorElements[i]; i++) {
      addEvent(el, 'mouseover', changeToOrange);
      addEvent(el, 'mouseout', changeToBlue);
    }
    You can take it a step further and make a generic color changing function using a curried style:

    Code:
    function changeColor(color) {
      return function() {
        this.style.color = color;
      }
    }
    addEvent(example, 'mouseover', changeColor('orange'));
    addEvent(example, 'mouseout', changeColor('blue'));
    Since JavaScript has support for First-Class functions, you can used curried style functions (functions that take in an argument, and pass it on to a returned function). That's why JavaScript rules so much.

  5. #5
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, luckily we have jquery

    Code:
    <div id="links_div">
       <a href...
       <a href...
       etc
    </div>
    
    <script>
    // set mouseover for all <a>'s inside links_div
    $("#links_div a").mouseover(function(e) { 
       "this" points to the corresponding <a> element
    })
    </script>
    That's basically all you need to know to get started.

  6. #6
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Stereofrog: It's posts like yours that don't actually help the JavaScript learning curve. It's quite obvious that jQuery, Prototype, YUI, Dojo, or whathaveyou, can do quite an array of tasks, quite simply. These forum posts are about learning. Technically, if you wanted to go the jQuery route and forget everything posted, you would have used the 'hover' method
    Code:
    $('#example a').hover(function() {
      // mouseover
    }, function() {
      // mouseout
    });

  7. #7
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This forum is for people helping each other. Since OP didn't say explicitly (s)he wants to know anything about "curried style functions" or similar, I guessed that (s)he, like most posters here, just needs to get the job done, and in the javascript world using a de-facto standard library is the best way to achieve this.

  8. #8
    Google Engineer polvero's Avatar
    Join Date
    Oct 2003
    Location
    Mountain View
    Posts
    567
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Haha. Since when did jQuery become defacto?
    Actually, nevermind, I'm done with this thread. XLCowBoy got what he wanted.

  9. #9
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, honestly, all he's got is a bunch of confusing spaghetti code that isn't even remotely useful in practice. I fail to see how someone can learn anything from that.

  10. #10
    Designer
    Join Date
    Jun 2006
    Location
    Manila
    Posts
    590
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    @stereofrog - I appreciate the help, but I don't actually see polvero's code as "spaghetti", he/she actually explained the logic pretty well (I do understand Javascript - as polvero just showed, I stumbled upon something rather beyond my knowledge). Although I agree that having JS frameworks are a great deal of help (as I use MooTools often enough to know), I wouldn't want to become reliant on frameworks, because they are just tools - not the answer to every solution. (For example, MooTools and Opera aren't friends for example) Same reason why I don't like using CSS frameworks.

    @polvero - much appreciated. I've bookmarked the event delegation link. I think I'll go purchase your book after I'm done reading your stablemate's (Christian Heilmann) one.

  11. #11
    SitePoint Wizard stereofrog's Avatar
    Join Date
    Apr 2004
    Location
    germany
    Posts
    4,324
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    You introduced yourself as "js noob" and posted a really simple question, that's why I suggested the use of framework. I understand your aspiration to learn more about how the things work, for my part I can suggest two classic resources that may help you further

    http://www.crockford.com/javascript (javascript language)
    http://www.quirksmode.org (cross-browser stuff)

  12. #12
    Designer
    Join Date
    Jun 2006
    Location
    Manila
    Posts
    590
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by stereofrog View Post
    You introduced yourself as "js noob" and posted a really simple question, that's why I suggested the use of framework. I understand your aspiration to learn more about how the things work, for my part I can suggest two classic resources that may help you further

    http://www.crockford.com/javascript (javascript language)
    http://www.quirksmode.org (cross-browser stuff)
    Many thanks and much appreciated. I posted as a noob because I thought the solution that I was looking for was something slightly more seasoned JS users already knew about.

    I guess I should have thought as much when I couldn't find a solution in the book I'm reading or online.


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
  •