javascript Backbone.js 悬停事件未触发

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/8926885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 05:01:50  来源:igfitidea点击:

Backbone.js hover event not triggering

javascriptjquerybackbone.js

提问by Deleteman

I'm trying to use Backbone.js for the first time and I'm having some trouble. I don't know if my problem is that I'm not understanding how backbone is supposed to work or if it's just a code problem.

我第一次尝试使用 Backbone.js,但遇到了一些麻烦。我不知道我的问题是我不了解主干应该如何工作,还是只是代码问题。

I'm trying to create a dynamic menu, and I have no problem creating the main menu bar with it's items, but I can't get the hover event to trigger whenever I hover one of the menu items.

我正在尝试创建一个动态菜单,并且使用它的项目创建主菜单栏没有问题,但是每当我悬停其中一个菜单项时,我都无法触发悬停事件。

Views

观看次数

var MenuView = Backbone.View.extend({
    initialize: function(items) {
        this.menu = items;
        //Main navigation bar
        this.el = $("#main-nav");
        this.trigger('start');
        this.render();
    },
    render: function() {
        var me = this;
        _.each(this.menu, function(mi) {
            mi.render(me.el);
        });
        return this;
    },
    handleHover: function(e) {
        console.debug(e);
    }
});

var MenuItemView = Backbone.View.extend({
    tagName: 'li',
    className:'menu-item',
    events: { //none of these work
        'hover a':'handleHover',
        'mouseover a':'handleHover',
        'mouseover':'handleHover',
        'click': 'handleHover',
        'click a': 'handleHover'
    },
    initialize: function(mi) {
        this.menuItem = mi;
        this.el = $("<li class=\"menu-item\"></li>")
    }, 
    render: function(parent) {
        this.el.append('<a href="' + this.menuItem.get("link") + '">' + this.menuItem.get("text") + '</a>');
        parent.append(this.el);
        return this;
    },

    handleHover: function(ev) {
        console.debug("Hovering! " + ev + this.menuItem.get("cid"));
        console.debug(ev);
        return false;
    }
});

Model

模型

var MenuItem = Backbone.Model.extend({
    defaults: {
        parent: null,
        children: [],
        link: "",
        text: ""
    }   
});

Startup code

启动代码

$(document).ready(function() {
    var menu = new MenuView([
        new MenuItemView( new MenuItem({link: "/", text: "Home"})),
        new MenuItemView( new MenuItem({link: "/", text: "Users"})),
        new MenuItemView( new MenuItem({link: "/", text: "Configuration"}))
    ]);
});

Any help will be appreciated!

任何帮助将不胜感激!

Thanks!

谢谢!

Update

更新

Ok, after taking the definition of eloutside of the initializemethod on the MenuItemView view, it works, BUT that same element gets reused on all instances of the view, so I had to change the view to the following code in order to make it work the way I want it:

好的,在MenuItemView 视图上el采用initialize方法之外的定义后,它可以工作,但是相同的元素在视图的所有实例上被重用,所以我不得不将视图更改为以下代码以使其工作我想要的方式:

 var MenuItemView = Backbone.View.extend({

    events: { //none of these work
        'hover a':'handleHover',
        'mouseover a':'handleHover',
        'mouseover':'handleHover',
        'click': 'handleHover',
        'click a': 'handleHover'
    },
    el: $('<li class="menu-item"></li>'),
    initialize: function(mi) {
        this.menuItem = mi;
        this.el = $(this.el).clone(true);
    }, 
    render: function(parent) {
        this.el.append('<a href="' + this.menuItem.get("link") + '">' + this.menuItem.get("text") + '</a>');
        parent.append(this.el);
        return this;
    },

    handleHover: function(ev) {
        console.debug("Hovering! " + ev + this.menuItem.get("cid"));
        console.debug(ev);
        return false;
    }
});

Wny do I have to clone the element on a new instance?

我必须在新实例上克隆元素吗?

回答by Chris Aitchison

hover is not a normal event, but a 'convenience' event provided by jquery. It is a combination of mouseenter and mouseleave.

悬停不是正常事件,而是 jquery 提供的“便利”事件。它是 mouseenter 和 mouseleave 的组合。

Binding to mouseenter and mouseleave instead of hover will do what you need.

绑定到 mouseenter 和 mouseleave 而不是悬停将满足您的需求。

回答by mu is too short

Re: "Why do I have to clone the element on a new instance?"

回复:“为什么我必须在新实例上克隆元素?”

The underlying problem is right here:

根本问题就在这里:

var MenuItemView = Backbone.View.extend({
    // ...
    el: $('<li class="menu-item"></li>'),

The $('<li class="menu-item"></li>')call is executed when MenuItemViewis being defined so you end up with only one $('<li>')being shared across all instances of MenuItemView.

$('<li class="menu-item"></li>')调用MenuItemView在定义时执行,因此您最终只会$('<li>')MenuItemView.

If you create the elinside initializeor renderthen you'll have to bind the events by hand using delegateEvents:

如果您创建el内部,initialize否则render您必须使用delegateEvents以下方法手动绑定事件:

By default, delegateEventsis called within the View's constructor for you [...]

默认情况下,delegateEvents在视图的构造函数中为您调用 [...]

So if you create this.elyourself then you'll have to call this.delegateEvents()yourself. For example:

所以,如果你创造了this.el自己,那么你就必须给this.delegateEvents()自己打电话。例如:

var MenuItemView = Backbone.View.extend({
    // ...
    render: function() {
        this.el = $('<li class="menu-item"><a>' + this.cid + '</a></li>');
        this.delegateEvents();
        return this;
    },
    //...
});

Demo: http://jsfiddle.net/ambiguous/RPqMh/2/

演示:http: //jsfiddle.net/ambiguous/RPqMh/2/

However, if you cloneyour this.elwith the withDataAndEventsflag on, then you should be fine:

但是,如果clonethis.elwithDataAndEvents的标志,那么你应该罚款:

var MenuItemView = Backbone.View.extend({
    el: $('<li class="menu-item"></li>'),
    // ...
    initialize: function() {
        this.el = this.el.clone(true);
        this.el.append('<a>' + this.cid + '</a>');
    }, 
    //...
});

Demo: http://jsfiddle.net/ambiguous/hCW3F/1/

演示:http: //jsfiddle.net/ambiguous/hCW3F/1/

But if you just this.el.clone(), it won't work because the delegatewon't be bound to the clone:

但是如果你只是this.el.clone(),它不会工作,因为delegate不会绑定到克隆:

var MenuItemView = Backbone.View.extend({
    el: $('<li class="menu-item"></li>'),
    // ...
    initialize: function() {
        this.el = this.el.clone();
        this.el.append('<a>' + this.cid + '</a>');
    }, 
    // ...
});

Demo: http://jsfiddle.net/ambiguous/KZNPA/

演示:http: //jsfiddle.net/ambiguous/KZNPA/

But if you add your own delegateEventscall, you'll be okay:

但是如果你添加自己的delegateEvents电话,你会没事的:

var MenuItemView = Backbone.View.extend({
    el: $('<li class="menu-item"></li>'),
    // ...
    initialize: function() {
        this.el = this.el.clone();
        this.el.append('<a>' + this.cid + '</a>');
    },
    render: function() {
        this.delegateEvents();
        return this;
    },
    // ...
});

Demo: http://jsfiddle.net/ambiguous/KZNPA/1/

演示:http: //jsfiddle.net/ambiguous/KZNPA/1/

回答by dfsq

It seems to me that you don't need this properties:

在我看来,您不需要此属性:

tagName: 'li',
className:'menu-item'

in MenuItemView if you specify this.el = $('<li class="menu-item"></li>');

在 MenuItemView 中,如果您指定this.el = $('<li class="menu-item"></li>')