Search code examples
javascriptjquerybackbone.jsbackbone-eventsevent-bubbling

Backbone events firing multiple times


I'm using Backbone together with require.js and jQuery. What I'm trying to do is to simply bind an event to a container which should show (mouseover) or hide (mouseout) a video. The event fires but unfortunately too many times (I've several children inside .intro-content). I tried using ev.stopPropagation() (as seen in the code) and ev.stopImmediatePropagation but this doesn't prevent the bubbling. What am I doing wrong?

View:

define([
  'jquery',
  'underscore',
  'backbone',
  'global'
], function($, _, Backbone, Global){

    var VideoView = Backbone.View.extend({

        el: $('#splitlayout'),

        events: {
            'mouseover .side-left .intro-content': 'checkVideoState',
            'mouseout .side-left .intro-content': 'checkVideoState'
        },        

        render: function(){

            this.playVideo('video', '0GsrOOV0gQM');
            this.delegateEvents();

        },

        initialize: function() {

            _.bindAll(this);
            this.render();

        },

        checkVideoState: function(ev) {

            ev.stopPropagation();

            if(!$('#video').hasClass('active') && ev.type == 'mouseover') {

                this.showVideo();

            } else if($('#video').hasClass('active') && ev.type == 'mouseout') {

                this.hideVideo();

            }

        },

        showVideo: function() {
            console.log('test');
            $('#video').addClass('active');
            player.playVideo();
        },

        hideVideo: function() {
            console.log('test');
            $('#video').removeClass('active');
            player.pauseVideo();
        },

        playVideo: function(container, videoId) {

            var self = this;

            if (typeof(YT) == 'undefined' || typeof(YT.Player) == 'undefined') {
                window.onYouTubeIframeAPIReady = function() {
                    self.loadPlayer(container, videoId);
                };

                $.getScript('//www.youtube.com/iframe_api');
            } else {
                self.loadPlayer(container, videoId);
            }

        },

        loadPlayer: function(container, videoId) {

            player = new YT.Player(container, {
                videoId: videoId,
                playerVars: {
                    controls: 0,
                    loop: 1,
                    modestbranding: 0,
                    rel: 0,
                    showinfo: 0
                },
                events: {
                    'onReady': this.onPlayerReady
                }
            });

        },

        onPlayerReady: function() {

            player.setPlaybackQuality('hd720');
            player.seekTo(8,false);
            player.pauseVideo();

        }

    });

    return VideoView;

});

Solution

  • You probably initialized your view twice.

    Here is an example of double events http://jsfiddle.net/rph4R which you can fix with removing last line new VideoView();.

    To check this you may add

    console.log('initialize');
    

    to the VideoView.initialize() method and check on console or use debugger or console.trace() to see full call stack.

    You can also check search for this code in your files and count it

    new VideoView();