SLB
SLB

Reputation: 111

JavaScript Object Literal "this" keyword jQuery Callbacks Argument Passing

What am I doing wrong here? I'm super frustrated here. I'm stuck @ when I call Menu.mouseHandler and since it's being passed an argument it seems to lose its value of this?

Code: http://jsfiddle.net/W6KsU/19/

var Menu = Menu || {};

Menu = {
    docHeight: jQuery("document").height(),
    menuOffset: jQuery("#menu").offset(),
    index:0,
    menuItem:"",
    menuItemName:"",
    menuItemPure:"",
    killMenu: function () {
        jQuery.each(['#menuApplyForCredit', '#menuBuyOrLease', '#menuVehicleProtection', '#menuCommercialFinancing', '#menuFinanceTools'], function () {
            jQuery(menuItem).unbind("mouseenter mouseleave", function () {
                console.log("NO CLICK! DO NOTHING~");
            });
        });
    },

    initialize: function () {
        if (jQuery.browser.ios) {
            jQuery.each(['#menuApplyForCredit', '#menuBuyOrLease', '#menuVehicleProtection', '#menuCommercialFinancing', '#menuFinanceTools'], this.touchHandler);
        } else {
            jQuery.each(['#menuApplyForCredit', '#menuBuyOrLease', '#menuVehicleProtection', '#menuCommercialFinancing', '#menuFinanceTools'], this.mouseHandler);
        }
    },

    touchHandler: function (i, v) {
        var _that = this,
        this.index = i;
        this.menuItem = v;
        this.menuItemPure = menuItem.replace('#menu', '');
        jQuery(menuItem).bind("touchstart touchend", _that.onTouch);
    },

    mouseHandler: function (i, v) {
        this.index = i;
        this.menuItem = v;
        console.log("mouseHandler: menuItem= "+this.menuItem);
        this.menuItemName = jQuery(this.menuItem).find("a:first img").attr("src");
        this.menuItemPure = this.menuItem.replace('#menu', '');

        console.log("menuItemName=" + this.menuItemName);
        console.log("menuItemPure=" + this.menuItemPure);

        jQuery(this.menuItem).bind("mouseenter", Menu.onEnter);
        //console.log(jQuery(this.menuItem).bind("mouseenter", Menu.onEnter))
        //jQuery(this.menuItem).bind("mouseenter", jQuery.proxy(Menu.onEnter, Menu));
        jQuery(this.menuItem).bind("mouseleave", jQuery.proxy(Menu.onLeave, Menu));
    },

    onEnter: function () {
          console.log("CALLED!");
        //console.log("evt= "+this);
        //console.log("this= "+this);
        //console.log("onEnter menuItem= " + menuItem);
        jQuery('#menu_overlay').clearQueue().stop().css({
            'display': 'block'
        }).animate({
            opacity: '.3'
        }, 200).height(this.docHeight);
        //console.log("onEnter menuItemPure= "+ menuItemPure);
        jQuery("#megaMenu" + menuItemPure + "Div").addClass("hovering");
        jQuery(menuItem).find("a:first").find("img").attr("src", "images/bttn" + menuItemPure + "Over.png").css({
            "z-index": "99"
        });
    },

    onLeave: function () {
        var _that = this;
        console.log("onLeave= "+ menuItem);
        var relX = Math.round(evt.pageX - this.menuOffset.left),
            relY = evt.pageY - this.offsetTop;
        if ((relX < 960 && relX > 0) && (relY < 41 && relY > 0)) {
            jQuery("#megaMenu" + menuItemPure + "Div").removeClass("hovering");
            if (menuItemName.indexOf("Stay") > -1) {
                jQuery(menuItem).find("a:first").find("img").attr("src", "images/bttn" + menuItemPure + "Stay.png").css({
                    "z-index": "1"
                });
            } else {
                jQuery(menuItem).find("a:first").find("img").attr("src", "images/bttn" + menuItemPure + ".png").css({
                    "z-index": "1"
                });
            }
        } else {
            jQuery('#menu_overlay').css({
                'display': 'none'
            }).animate({
                opacity: '0'
            }, 100);
            jQuery("#megaMenu" + menuItemPure + "Div").removeClass("hovering");
            if (menuItemName.indexOf("Stay") > -1) {
                jQuery(menuItem).find("a:first").find("img").attr("src", "images/bttn" + menuItemPure + "Stay.png").css({
                    "z-index": "1"
                });
            } else {
                jQuery(menuItem).find("a:first").find("img").attr("src", "images/bttn" + menuItemPure + ".png").css({
                    "z-index": "1"
                });
            }
        }
    },

    onTouch: function () {
        jQuery('#menu_overlay').clearQueue().stop().hide().css({
            'display': 'block'
        }).animate({
            opacity: '.3'
        }, 200).height(this.docHeight);
        jQuery("#megaMenu" + menuItemPure + "Div").removeClass("hovering").addClass("hovering");
        jQuery(menuItem).find("a:first").find("img").attr("src", "images/bttn" + menuItemPure + "Over.png").css({
            'z-index': '99'
        });
    }
}

Menu.initialize();

Upvotes: 2

Views: 970

Answers (1)

JMM
JMM

Reputation: 26837

With your code, this should refer to the value of the current item of the array you pass as the first argument. If you want this to refer to Menu, try:

jQuery.each(

  [

    '#menuApplyForCredit',

    '#menuBuyOrLease',

    '#menuVehicleProtection',

    '#menuCommercialFinancing',

    '#menuFinanceTools'

  ],

  jQuery.proxy( this.mouseHandler, this )

);

See jQuery.each() docs.

In the case of an array, the callback is passed an array index and a corresponding array value each time. (The value can also be accessed through the this keyword

And see the docs for the jQuery.proxy( function, context ) version of jQuery.proxy().

Upvotes: 1

Related Questions