small mouseover script

Discussion in 'JavaScript' started by camjohnson95, Dec 6, 2009.

  1. #1
    Here is a small script that I created for a project, for anyone to use. Basically it adds little pointers '>>' '<<' around a link when there is a mouseover, for menu's etc.
    
        var mnulinks = document.getElementById("mnuBar").getElementsByTagName("a");
        for (k in mnulinks) {
            mnulinks[k].onmouseover = function() {
                this.innerHTML = "&gt;&gt " + this.innerHTML + " &lt;&lt;";
            }
            mnulinks[k].onmouseout = function() {
                this.innerHTML = this.innerHTML.substr(9,this.innerHTML.length - 18);
            }
        }
    
    Code (markup):
    'mnuBar' is the id of the object that contains the links... It looks best if the links are centered so that they don't move around at all. Anyway, someone might find it useful.

    I tried to use 'for each' but apparently that only works in firefox and not IE7... dont know about IE8..
     
    camjohnson95, Dec 6, 2009 IP
  2. dimitar christoff

    dimitar christoff Active Member

    Messages:
    882
    Likes Received:
    62
    Best Answers:
    0
    Trophy Points:
    90
    #2
    you can make older browsers compatible with new js 1.6 array methods like so:
    
    (function() {
        // scope for fixing Array
        // provides: Array.forEach, Array.contains, Array.indexOf for 
        // browsers where they are not native.
        if (!Array.prototype.forEach) {
            Array.prototype.forEach = function (a) {
                var b = this.length >>> 0;
                if (typeof a != "function") throw new TypeError();
                var c = arguments[1];
                for (var i = 0; i < b; i++) {
                    if (i in this) a.call(c, this[i], i, this);
                }
            }
        }
        if (!Array.prototype.indexOf) {
            Array.prototype.indexOf = function (a) {
                for (var i = 0; i < this.length; i++) {
                    if (this[i] === a) {
                        return i;
                    }
                }
                return -1;
            }
        }
        if (!Array.prototype.contains) {
            Array.prototype.contains = function (a, b) {
                return this.indexOf(a, b) != -1;
            }
        }
    })();
    
    Code (javascript):
    that's my point about frameworks, they abstract such browser differences and let you just do what you need. otherwise, you need to include such 'fixes' and it's not always safe.

    for example, here is how the code above from the prototype can affect your loops of an array as an object:
    
    var myArray = [];
    myArray['foo'] = 'bar';
    
    for(var k in myArray) {
        alert(k); // expecting foo
    }
    
    Code (javascript):
    this will output "foo" but also "forEach", "contains" etc, if they get defined. of course, this is why you should NEVER use for ( in ) on an array but on objects only. which is something that you do - your script will break horribly on any page that also has Prototype or Mootools etc. The reason that for ... in works on Arrays at all is that javascript does not have an Array data type as such, Arrays are basically objects created through a different constructor (check typeof mnulinks == "object")

    if you HAVE to use the for ... in, which is the only way to get the KEY of an array element (or an object property) that I know of, then you need to use hasOwnProperty like so:
    
    for(var k in myArray) {
        if (myArray.hasOwnProperty(k))
            console.log(k, myArray[k]); // will ONLY do foo -> bar and not .contains, for example.
    }
    
    Code (javascript):
    another bad thing about for (var k in blah) - and always put var k else it does a global variable... - it does not care about the order of elements, i.e. there's no guarantee which property will come out first.
    in javascript the FASTEST loop of an array is a while(counter--).

    for this script it goes:
    
    var mnulinks = document.getElementById("mnuBar").getElementsByTagName("a"), menuSize = mnulinks.length;
    while(menuSize--) {
        // do something with mnulinks[menuSize];
    }
    Code (javascript):
     
    Last edited: Dec 6, 2009
    dimitar christoff, Dec 6, 2009 IP
  3. camjohnson95

    camjohnson95 Active Member

    Messages:
    737
    Likes Received:
    17
    Best Answers:
    0
    Trophy Points:
    60
    #3
    Thanks for the info, I will just go back to a standard for loop. Which is what I normally use, but I seen someone else use for...in and it looked handy so I thought I'd use it instead.

    That's handy to know, but I don't think that speed is really an issue with this script. Good for future reference though....

    Here is my new code:
    
        var mnulinks = document.getElementById("mnuBar").getElementsByTagName("a");
        for (i=0;i<mnulinks.length;i++) {
            mnulinks[i].onmouseover = function() {
                this.innerHTML = "&gt;&gt " + this.innerHTML + " &lt;&lt;";
            }
            mnulinks[i].onmouseout = function() {
                this.innerHTML = this.innerHTML.substr(9,this.innerHTML.length - 18);
            }
        }
    
    Code (markup):
     
    camjohnson95, Dec 9, 2009 IP