1

This is probably a very simple question. How would you reasonably simplify this awesome code? I am going to add much more eventhandlers and list items, and I can not believe, it is the only "solution". I am new to javascript (but not in programming).

    function MouseOver(elem)
    {
    elem.style = "font-weight:800;";
    }

    function MouseOut(elem)
    {
    elem.style = "font-weight:100;";
    }
...
    <ul class="signs_UL" style="color:#039">
        <li class="signs_LI" onmouseover="MouseOver(this);" onmouseout="MouseOut(this);">G</li>
        <li class="signs_LI" onmouseover="MouseOver(this);" onmouseout="MouseOut(this);">D</li>
        <li class="signs_LI" onmouseover="MouseOver(this);" onmouseout="MouseOut(this);">DD</li>
        <li class="signs_LI" onmouseover="MouseOver(this);" onmouseout="MouseOut(this);">Dzw</li>
        <li class="signs_LI" onmouseover="MouseOver(this);" onmouseout="MouseOut(this);">Do</li>
        <li class="signs_LI" onmouseover="MouseOver(this);" onmouseout="MouseOut(this);">Gkomb</li>
        <li class="signs_LI" onmouseover="MouseOver(this);" onmouseout="MouseOut(this);">DGkomb</li>
        <li class="signs_LI" onmouseover="MouseOver(this);" onmouseout="MouseOut(this);">DGkonf</li>
        <li class="signs_LI" onmouseover="MouseOver(this);" onmouseout="MouseOut(this);">DGkont</li>    
    </ul> 

thanx a lot

6
  • i know that with jQuery you can assign handler to all elements of class (signs_LI) with one line. but i don't know how :( Commented Feb 13, 2011 at 22:03
  • 1
    Do you mind using jQuery? or do you want to stick with classic JS? Commented Feb 13, 2011 at 22:03
  • 1
    this would be relatively easy to do with jQuery... Commented Feb 13, 2011 at 22:05
  • I downloaded jQuery today (couple hours ago), I do not mind to use it.... :-) Commented Feb 13, 2011 at 22:10
  • 1
    use css :hover. its much more ideal IMO. Commented Feb 13, 2011 at 22:13

6 Answers 6

7

If all you want to do is related to styling, you should use css instead of javascript:

ul.signs_UL li {
    font-weight: 100;
}

ul.signs_UL li:hover {
    font-weight: 800;
}

Will automatically change the font-weight on hovering over any list item in a signs_UL list.

Sign up to request clarification or add additional context in comments.

5 Comments

eh, i see... nightmare... what would you do in my case? jquery?
@lyborko: I would drop support for IE6 ;) :D
@lyborko: If you need IE6 support, wrap the content of the <li> elements with an <a>, then place the :hover on that. ul.signs_UL li a:hover You'll also need to adjust the CSS of the <a> to expand it to the same size as the parent <li> so you get the effect when hovering any part of the <li>.
Also, be careful if you are using other classes inside that ul, Bart did not specify the class for the li to reduce redundancy, but you might have different types of lis listed.
Or don't support IE 6. Seriously. Even Microsoft wants it to die. ie6countdown.com <-- site made by Microsoft. I have a page I show for IE 6 users that explains the security risks of their browser, links to upgrade pages
3

in jQuery you can do it with

$('li.signs_LI').mouseover(MouseOver).mouseout(MouseOut);

You can also do it with

$('li.signs_LI').hover(MouseOver, MouseOut);

but this would bind the events to mouseenter and mouseleave not to mouseover and mouseout.

I'm sure you know that you can do this with CSS with the pseudo class :hover to change the style on mouse hovering.

4 Comments

This would apply the mouseover/mouseout handler to all LI tags on the page, which is probably not what OP wants.
I didn't down-vote this because he endorsed CSS, but you shouldn't abuse jQuery by assigning event listeners to so many nodes (See @Felix King's answer).
me. I don't think you can call it like that, you have to pass a parameter to the function. In jQuery this isn't automatically supplied see my answer
@vol7ron: Actually, this in event handlers (in jQuery) always refers to the element the event is raised on (or the event handler is attached to). That is why you see $(this) so often in event handlers. Of course in order to make it work with the OPs code, elem must be renamed to this.
3

As you assign the same event handlers to every li object, it would be much better to assign them to the parent ul element instead, making use of event bubbling. This is called event delegation:

function MouseOver(event) {
    event = event || window.event; // IE uses window.event
    var target = event.target || event.srcElement; // IE uses event.srcElement
    if(target.nodeName === 'LI') {
        target.style.fontWeight = "800";
    }
}

function MouseOut(event) {
    event = event || window.event;
    var target = event.target || event.srcElement;
    if(target.nodeName === 'LI') {
        target.style.fontWeight = "100";
    }
}


// get a reference to the UL element somehow
ulElement.onmouseover = MouseOver;
ulElement.onmouseout = MouseOut;

(the node test might have to be tweaked (or even removed), this is just an example)

As mentioned in an other answer, if you just perform style adjustments, you could solve this with pure CSS. Nevertheless, event delegation is an important concept to avoid unnecessary event handler assignment.

Read more about event handling.

2 Comments

Thanx a lot for your link above, (it is somewhat exhausting to read through the tons of webpages to find good explanation). I did not know how to catch events in the general manner.
@lyborko: Make sure you also read the other pages about events on quirksmode: quirksmode.org/js/events_order.html, quirksmode.org/js/events_early.html, quirksmode.org/js/events_advanced.html I think it is a very good explanation and also mentions all the cross browser issues. You will have a much better understanding of event handling.
1

In case you want to change the style of an element you should use CSS as @Bart said.

But for the record, you can use one event handler on a root element like so:

var ul = document.getElementById("signs_UL"); // or select by other means.
ul.onmouseover = function (e) {
  e = e || window.event;
  var elem = e.target || e.srcElement;

  // ...
};

ul.onmouseout = function (e) {
  // ...
};

1 Comment

I was just in the process of adding this answer. +1
1

Here's classic javascript:

var onOver = function(e){
    e = e || window.event;
    var el = e.target || e.srcElement;
    el.style.fontWeight = 800;
}
var onOut = function(e){
    e = e || window.event;
    var el = e.target || e.srcElement;
    el.style.fontWeight = 100;
}
if (document.getElementsByClassName)
  var li = document.getElementsByClassName("signs_LI");
else{
  var li = [], lii = document.getElementsByTagName('LI');
  for (var l = 0; l < lii.length; l++){
    if (/\bsigns_LI\b/.test(lii[l].className))
      li.push(lii[l]);
  }
}
for (var e = 0; e < li.length; e++){
    var el = li[e];
    if (el.addEventListener) {
        el.addEventListener ("mouseover",onOver,false);
        el.addEventListener ("mouseout",onOut,false);
    } else if (el.attachEvent) {
        el.attachEvent ("onmouseover",onOver);
        el.attachEvent ("onmouseout",onOut);
    } else {
        el.onmouseover = onOver;
        el.onmouseout = onOut;
    }
}

But begs the question why you don't use standard css' :hover pseudo-class (javascript appears too heavy for this kind of manipulation).

6 Comments

Just a couple problems. Your handler functions are using this to reference the element, but attachEvent doesn't make this reference the element. It'll be window instead. You'd need to wrap it in a function that calls the onOver/Out functions with the proper context. Also, IE doesn't support getElementsByClassName (well IE9 does). :o)
@patrickdw: Hrm, tested in on my side and it worked. Just went with it. ;p This is why I tend to stick with jQuery "Focus on the code". ;p
But you tested in Firefox or Chrome or something, right? Those should work fine. Just IE would need to be tweaked.
@Brad Christie : do you mean, jquery is "platform proof"?
@patrickdw: See if that update works. Does here--I promise.
|
0

While CSS might be what you want in your example, JavaScript/jQuery will allow you to do more, which you might want. This includes calling other functions and performing calculations.

function on(elem) { elem.style.color="#0cf"; }
function off(elem){ elem.style.color="#000"; }

// calling mouseover/out
$('.signs_LI').mouseover( function(){ on(this); })
              .mouseout( function(){ off(this); });


// hover example
$('.signs_LI').hover( function(){ on(this);  }
                    , function(){ off(this); } );

5 Comments

this is just an example. i appreciate negative votes to say why they are negative
This would not work, you would have to pass this to MouseOver, not $(this).
fixed, i think that's what I had originally, but I changed it. I tested the above.
It would be easier to define the functions as function on() {this.style....} and just pass this function as event handler: $(..).mouseover(on).mouseout(off)... saves some function objects. Of course if you want to keep on and off as general purpose functions, than it is better to pass the element...
@Felix: yes, but for scalability, I don't like doing that. In my opinion it'd be better to attach this to an object and pass the object to the function, but this is a proof of concept

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.