简体   繁体   中英

Multiple click handlers for a single element

I've written a few events to handle opening and closing of a snap js drawer. This code below works, but I feel it could be written more efficiently. Any suggestions?

function openMobileMenu() {
    event.preventDefault();
    snapper.open('left');
    $('#btn-menu').off('click', openMobileMenu);
    $('#btn-menu').on('click', closeMobileMenu);
}

function closeMobileMenu() {
    event.preventDefault();
    snapper.close('left');
    $('#btn-menu').on('click', openMobileMenu);
    $('#btn-menu').off('click', closeMobileMenu);
}

$('#btn-menu').on('click', openMobileMenu);

Use a variable to keep track of the state:

var menu_open = false;
$("#btn-menu").on('click', function(event) {
    event.preventDefault();
    if (menu_open) {
        snapper.close('left');
    } else {
        snapper.open('left');
    }
    menu_open = !menu_open; // toggle variable
});

snap has a .state() method, which returns an object stuffed with properties, one of which is .state .

I think you want :

$('#btn-menu').on('click', function() {
    if(snapper.state().state == "closed") {
        snapper.open('left');
    } else {
        snapper.close('left');
    }
});

Or, in one line :

$('#btn-menu').on('click', function() {
    snapper[['close','open'][+(snapper.state().state == 'closed')]]('left');
});

Also, check How do I make a toggle button? in the documentation.

Make your code modular and your concepts explicit.

You can start by creating a MobileMenu object which encapsulates the logic.

Note: The following code was not tested.

var MobileMenu = {
    _snapper: null,
    _$button: null,
    _direction: 'left',
    init: function (button, snapper, direction) {
        this._$button = $(button);
        this._snapper = snapper;
        if (direction) this._direction = direction;

        this._toggleSnapperVisibilityWhenButtonClicked();
    },
    _toggleSnapperVisibilityWhenbuttonClicked: function () {
        this._$button.click($.proxy(this.toggle, this));
    },
    toggle: function () {
        var snapperClosed = this._snapper.state().state == 'closed',
            operation = snapperClosed? 'open' : 'closed';

        this._snapper[operation](this._direction);
    }
};

Then in your page you can just do the following to initialize your feature:

var mobileMenu = Object.create(MobileMenu).init('#btn-menu', snapper);

Modularizing your code will make it more maintainable and understandable in the long run, but also allow you to unit test it. You also gain a lot more flexibily because of the exposed API of your component which allows other code to interact with it.

Eg you can now toggle the menu visibility with mobileMenu.toggle() .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM