Sahar
Sahar

Reputation: 63

Why cannot access to variable inside function that assigned jquery object

I cannot access button or container variable inside the functions. What's the problem?

var Site = {
    init: function () {
        $(".site .head .nav-bar .nav-button").click(function () {
            Site.Navigation.toggle();
            return false;
        });
    },
    Navigation: {
        container: $(".site .head .nav-bar .navigation"),
        button: $(".site .head .nav-bar .nav-button"),
        toggle: function () {
            if (this.button.hasClass("active")) {
                this.hide();
            }
            else {
                this.show();
            }
        },
        show: function () {
            this.button.addClass("active");
            this.container.slideDown();
            return false;
        },
        hide: function () {
            this.button.removeClass("active");
            this.container.slideUp();
            return false;
        }
        //another stuff
    }

}

$(document).ready(function () {
    Site.init();
});

Upvotes: 4

Views: 149

Answers (2)

bfavaretto
bfavaretto

Reputation: 71939

I'm not absolutely sure, but I believe what's happening is that your selectors are not matching any elements, because they're called before the elements are added to the DOM. I mean these:

container: $(".site .head .nav-bar .navigation"),
button: $(".site .head .nav-bar .nav-button"),

Try moving your whole JavaScript to the end of the body (right before </body>).

Another possible solution is to only populate those properties from Site.init (currently, they're populated immediately when the object literal is declared:

var Site = {
    init: function () {

        this.Navigation.container = $(".site .head .nav-bar .navigation");
        this.Navigation.button = $(".site .head .nav-bar .nav-button");

        $(".site .head .nav-bar .nav-button").click(function () {
            Site.Navigation.toggle();
            return false;
        });
    },
    Navigation: {
        container: null,
        button: null,
        toggle: function () {
            if (this.button.hasClass("active")) {
                this.hide();
            }
            else {
                this.show();
            }
        },
        show: function () {
            this.button.addClass("active");
            this.container.slideDown();
            return false;
        },
        hide: function () {
            this.button.removeClass("active");
            this.container.slideUp();
            return false;
        }
        //another stuff
    }

}

Upvotes: 4

plalx
plalx

Reputation: 43738

It's because your elements probably don't exist yet when your object is defined, since the code isin't running after the DOM is ready.

You could modify your Site.init function to accept these element references as argument however.

   init: function (container, button) {
        var nav = this.Navigation;

        nav.container = container;
        nav.button = button;
    }

Then pass in the elements:

$(document).ready(function () {
    Site.init(/*containerEl*/, /*buttonEl*/);
});

Upvotes: 2

Related Questions