使用backbone.js和jQuery绑定事件点击

6
我需要在我的backbone.js视图中绑定两个事件,以切换菜单。我想法是,如果点击id为#toggler的按钮,则菜单出现,而单击#menu元素之外的任何内容都将隐藏菜单。

不幸的是,我无法使用backbone的事件绑定使得outsideMenuHandler()仅在我单击#menu元素之外的地方才被调用。

我应该做出哪些改变才能使这个工作?

以下是我在backbone.js中所做的,但没有达到预期效果:

myView = Backbone.View.extend({

    events: {
        'click #menu': 'insideMenuHandler',
        'click':       'outsideMenuHandler'
    }

    insideMenuHandler: function(e) {}, // Called when clicking #menu
    outsideMenuHandler: function(e) {} // Called on every click both on and off #menu

}
 

仅供参考,以下是我使用仅限于jQuery的解决方案:

$(document).click(function(event) {
    if ( $(event.target).closest('#menu').get(0) == null ) {
        $("#menu").slideUp();
    }
});   
2个回答

14

你需要解决几个问题。

首先,如果你的insideMenuHandler返回false或调用e.stopPropogation(),那么对于#menu的点击就不会调用outsideMenuHandler。例如:

http://jsfiddle.net/ambiguous/8GjdS/

但这并不是你的全部问题。只有当你的视图上发生点击时,你的outsideMenuHandler才会被调用;因此,如果某人在视图外部的页面上点击了,你的outsideMenuHandler就不会被调用,从而导致菜单无法关闭。如果你希望当有人点击#menu之外的任何地方时,菜单都能关闭,那么你就需要手动绑定到body,并在销毁视图时手动解除绑定。大概像这样:

var myView = Backbone.View.extend({
    events: {
        'click #menu': 'insideMenuHandler'
    },

    initialize: function() {
        _.bindAll(this, 'insideMenuHandler', 'outsideMenuHandler');
    },

    render: function() {
        // Both <body> and <html> for paranoia.
        $('body, html').on('click', this.outsideMenuHandler);
        // ...
        return this;
    },

    remove: function() {
        // Clean up after ourselves.
        $('body, html').off('click', this.outsideMenuHandler);
        // ...
    },

    // ...
    outsideMenuHandler: function(e) {
        // ...
        return false;
    }
});

然后一定要正确地移除你的视图。例如:

http://jsfiddle.net/ambiguous/MgkWG/1/


非常感谢您的回答。非常感激!一个快速的问题——我理解,让单击事件返回“false”将防止发生任何“默认事件”,这意味着所有其他单击将被禁用,因为outsideMenuHandler返回false。如果在执行逻辑(隐藏我的菜单)后让我的outsideMenuHandler返回true,那么我会遇到麻烦吗? - Industrial
1
@工业界:你最终会在body, html绑定中调用两次outsideMenuHandler,但这可能不是问题。你可能只需要将outsideMenuHandler绑定到html上,但你需要进行浏览器检查以确保它在所有你关心的浏览器中都能正常工作。 - mu is too short

-1
问题在于,您将事件绑定到定义为视图el的DOM元素上。因此,如果这不是像您的jquery示例中的window.document,则无法注意到任何单击事件。在您的示例中,最简单的方法是使用jquery手动添加事件,而不是使用backbone。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接