Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Backbone.js hover event not triggering

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.

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 el outside of the initialize method 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:

 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?

like image 983
Deleteman Avatar asked Nov 30 '22 06:11

Deleteman


1 Answers

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

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

like image 117
Chris Aitchison Avatar answered Dec 05 '22 15:12

Chris Aitchison