Search code examples
jquerybackbone.jsbindmouseentermouseleave

Backbone - View Element Continually Triggers Mouseenter/Mouseleave


Sorry bout all the code :S

The mouseenter/mouseleave binding on the element in HomeIconView continually keeps firing. Firebug runs out of lines for the console output in the mouseenter/mouseleave output. I simply want to achieve a rollover effect. I have to assume it is how I am using backbone. I have only started using this week. I've only tested in Firefox so far.

When the "HomeView" view is rendered, the "HomeIconView" views are dynamically inserted into the "HomeView" view. There's no prob with the "events" of HomeIconView being called, the problem is they are continually being called! Apparently, it doesn't matter if the mouse is actually entering or leaving. Backbone, after the initial mouseenter and up until the final mouseleave, just keeps iterating through renderRollOver() and renderRollOut() even when there is no mouse movement. :(

I've spent days searching for a solution. All I can find are threads where people can't bind the events, not threads where people are experiencing over active bound function calls.

In general I am open to any suggestion of better coding practice but in particular, please help put me out of my misery on this event bind mouseenter/leave thing.

Again, sry bout all the code, I wanted to leave no ambiguity.

...

window.HomeIconView = Backbone.View.extend ({

model: new HomeIconModel,

template: _.template([
                '<a href="#">',
                    '<div class="homeIcon" id="homeIcon-<%= id %>">',
                        '<img src="<%= homeIconSrc %>">',
                    '</div>',
                '</a>'
                ].join('')),

events: { 'mouseenter': 'renderRollOver', 'mouseleave': 'renderRollOut' },

initialize: function(md) {

    _.bindAll(this, 'render');
    this.id = 'Icon-' + md.c.id.toString();
    this.model.save(md.c);
},

render: function() {
    return this.$el.html(this.template(this.model.toJSON()));
},

renderRollOver: function() {

    console.log('rollover');
        $('#homeRollOver, #homeRollOver2').css({ 'display': 'block', 'opacity': 0.125 });
        $('#home' + this.id).stop().animate( { opacity: 1 }, 1000);
        var elOffset = $('#home' + this.id).offset();
        var elOffsetL = elOffset.left - 
                        (
                            (
                                parseInt($('#homeRollOver').css('width')) - 
                                parseInt($('#home' + this.id).css('width'))
                            ) / 2
                        );
        var elOffsetT = elOffset.top -
                        (
                            (
                                parseInt($('#homeRollOver').css('height')) - 
                                parseInt($('#home' + this.id).css('height'))
                            ) / 2
                        );
        $('#homeRollOver, #homeRollOver2').css(
            { 'marginLeft': elOffsetL, 'marginTop': elOffsetT }
        );
},

renderRollOut: function() {
    console.log('rollout');
    $('#homeRollOver, #homeRollOver2').css('display', 'none');
    $('#home' + this.id).stop().animate({ opacity: 0.125 }, 1000 );
}
});

window.HomeView = Backbone.View.extend({

model: new PreloadHomeImages,

template: _.template([
            '<div id="homeIconWrapper"></div>',
            '<div id="homeRollOver"></div>',
            '<div id="homeRollOver2"></div>'
            ].join('')),

initialize: function() {
    _PAGE_H = $(document).height();
    _PAGE_W = $(document).width();
    this.preload();
    this.render();
},

preload: function() {
    var i = 0;
    _.each(this.model.get('icons'), function(icon) {
        var tmpimg = $('<img/>');
        tmpimg.src = icon.image;
        i++;
    });
    this.$el.css('paddingTop', (_PAGE_H - 180) / 2) ;
    $('#wrapper').css('height', _PAGE_H - 50);
},

render: function() {
    this.$el.html(this.template);
    var i = 0;
    _.each(this.model.get('icons'), function(icon) {
        var iconView = new HomeIconView({
                                model: new HomeIconModel, 
                                c: { 'id': i, 'homeIconSrc': icon.image }
                            });
        $('#homeIconWrapper').append(iconView.render);
        i++;
    });
    return this;
}
}); 
...

Solution

  • The HomeIconView required a valid ID when being instantiated.

    Later on when trying to implement the rollover I experienced the problem mu_is_too_short described, in that the z-index of the elements were causing the mouseenter/leave to also continually trigger. Both answers are right. Thanks again @mu_is_too_short.

    Example;

    http://3d.rededitor.net/site2/