2016-04-19 2 views
0

Ничего себе. Наконец я понял, что вызывает ошибку, но я не могу понять, почему. У меня есть объект со свойством (простите массивный код дамп)Почему здесь вызывается только функция последнего объекта?

// relatives second indices in the video to events 
    // that are called when the video reaches that second 
    this.PausePoints = [ 
     { 
      sec: 10, 
      name: "Point number 1", 
      passed: false, 
      func: (function(that) { 

       this.$layer = that.GetLayerElement(10); 
       this.$layer.hide(); 

       this.to = function() { 
        that.videlem.pause(); // pause video 
        $(window).resize(); // re-proportion stuff 
        // point the 3 mouse pointers 
        var $mptrs = this.$layer.find('.filmstrip-pointer'); 
        for (var i = 0; i < $mptrs.length; ++i) { 
         (function (j) { 
          setTimeout(function() { 
           Point($mptrs.eq(j)); 
          }, j * 1000); 
         })(i); 
        } 
       }; 



       // attach click event to 3 sections 
       $clickRegions = $layer.find('div.click-region'); 
       $clickRegions.click(function(){ 
        $clickRegions.removeClass('clicked'); 
        $(this).addClass('clicked'); 
       }); 

       this.away = function() { 
        this.$layer.hide(); 
       } 

       // attach event to next button 
       $layer.find('.next-btn').click(function(){ 
        this.away(); 
        that.videlem.play(); 
       }.bind(this)); 

       return this; 

      })(this) 
     }, 
     { 
      sec: 26, 
      name: "Point number 2", 
      passed: false, 
      func: (function(that) { 

       this.$layer = that.GetLayerElement(26); 
       this.$layer.hide(); 

       this.to = function() { 

        // loop video between 0:26-0:31 
        this.loop = setInterval(function() { 
         that.videlem.currentTime = 26; 
         that.videlem.play(); 
        }, 5000); 

        // point the 3 mouse pointers 
        var $mptrs = this.$layer.find('.filmstrip-pointer'); 
        for (var i = 0; i < $mptrs.length; ++i) { 
         (function (j) { 
          setTimeout(function() { 
           Point($mptrs.eq(j)); 
          }, j * 1000); 
         })(i); 
        } 

        this.$layer.show(); 

       } 


       // separate pargraph words by spans 
       this.$layer.find('p').each(function() { 
        var spanned = $(this).text().split(" ").map(function (w) { return '<span class="word">' + w + '</span>'; }).join(" "); 
        $(this).html(spanned); 
       }); 

       // add event click event on headlines 
       var timeouts = []; 
       this.$layer.find('h3').click(function() { 
        // clear any current 'showing' animations 
        timeouts.forEach(function(t){ clearTimeout(t); }); 
        timeouts = []; 
        // unshow all words on the slide 
        this.$layer.find('span.word').removeClass('shown'); 
        // show all words associated with the headline that was clicked 
        var $wspans = $(this).closest('.tower-layer').find('span.word'); 
        for (var i = 0; i < $wspans.length; ++i) 
        { 
         (function(j){ 
          timeouts.push(setTimeout(function(){ 
           $wspans.eq(j).addClass('shown'); 
          },j*100)); 
         })(i); 
        } 
       }.bind(this)); 

       this.away = function() { 
        clearInterval(this.loop); 
        this.$layer.find('span.word').removeClass('shown'); 
        $layer.hide(); 
        that.videlem.currentTime = 31;//go to end of loop 
       }; 

       // set action of "Next" button 
       this.$layer.find('.next-btn').click(function() { 
        this.away(); 
        that.videlem.play(); 
       }.bind(this)); 

       return this; 

      })(this) 
     }, 
     { 
      sec: 38, 
      name: "Point number 3", 
      passed: false, 
      func: (function(that) { 

       this.$layer = that.GetLayerElement(38); 
       this.$layer.hide(); 

       this.to = function () { 
        // loop video between 0:38-0:43 
        this.loop = setInterval(function() { 
         that.videlem.currentTime = 38; 
         that.videlem.play(); 
        }, 5000); 

        this.$layer.show(); 
       } 

       this.away = function(){ 
        clearInterval(this.loop); 
        this.$layer.hide(); 
       }; 

       this.$layer.find('.next-btn').click(function(){ 
        that.videlem.currentTime = 43; 
        this.away(); 
        that.videlem.play(); 
       }.bind(this)); 

       return this; 

      })(this) 
     }, 
     { 
      sec: 47, 
      name: "Point number 4", 
      passed: false, 
      func: (function(that){ 

       this.$layer = that.GetLayerElement(47); 
       this.$layer.hide(); 

       this.to = function() 
       { 
        // loop video between 0:47-0:52 
        this.loop = setInterval(function() { 
         that.videlem.currentTime = 47; 
         that.videlem.play(); 
        }, 5000); 
        // show layer 
        this.$layer.show(); 
       } 

       this.away = function() { 
        clearInterval(this.loop); 
        this.$layer.hide(); 
       }; 

       this.$layer.find('.next-btn').click(function() { 
        that.videlem.currentTime = 52; 
        this.away(); 
        that.videlem.play(); 
       }.bind(this)); 

       return this; 

      })(this) 
     }, 
     { 
      sec: 57, 
      name: "Point number 5", 
      passed: false, 
      func: (function(that){ 

       this.$layer = that.GetLayerElement(57); 
       // hide initially 
       this.$layer.hide(); 

       this.to = function() 
       { 
        // loop video between 0:57-1:02 
        this.loop = setInterval(function() { 
         that.videlem.currentTime = 57; 
         that.videlem.play(); 
        }, 5000); 

        this.$layer.show(); 
       } 

       this.away = function(){ 
        clearInterval(this.loop); 
        $layer.hide(); 
       }; 

       this.$layer.find('.next-btn').click(function() { 
        that.videlem.currentTime = 62; 
        this.away(); 
        that.videlem.play(); 
       }.bind(this)); 

       return this; 

      })(this) 
     } 
    ]; 

и то, что я заметил, что когда я пытаюсь вызвать любого из to функций, которые он всегда вызывает один в последнем элементе массив.

Например,

VidHandler.PausePoints[0].func.to() 

звонки

   this.to = function() 
       { 
        // loop video between 0:57-1:02 
        this.loop = setInterval(function() { 
         that.videlem.currentTime = 57; 
         that.videlem.play(); 
        }, 5000); 

        this.$layer.show(); 
       } 

вместо ожидаемого

   this.to = function() { 
        that.videlem.pause(); // pause video 
        $(window).resize(); // re-proportion stuff 
        // point the 3 mouse pointers 
        var $mptrs = this.$layer.find('.filmstrip-pointer'); 
        for (var i = 0; i < $mptrs.length; ++i) { 
         (function (j) { 
          setTimeout(function() { 
           Point($mptrs.eq(j)); 
          }, j * 1000); 
         })(i); 
        } 
       }; 

Почему это происходит и как я могу это исправить?

+0

Becasue 'this' является объектом' window', и каждый вызов перезаписывает предыдущие. Почему вы используете 'this' вообще? Просто используйте IIFE, который возвращает литерал объекта. – Bergi

+0

Вау, да, массивный свалка кода. Вы действительно должны сделать это более сухим. Создайте функцию конструктора и вызовите это несколько раз. – Bergi

+1

Используйте строгий режим. Всегда используйте строгий режим. Если вы используете строгий режим, эта ошибка всплыла бы как исключение. – Bergi

ответ

1

Проблема заключается в том, что вы пытаетесь присвоить что-то func, используя выражение, вызванное немедленно вызываемой функцией (IIFE). Те IIFE выполняются до объект построен, то есть this относится к чему-то еще. Ваш код может быть в основном разбиты, как это:

this.to = function() { 
    // version for "Point number 1" 
}; 
this.to = function() { 
    // version for "Point number 2" 
    // notice that you're overwriting the previous one 
}; 

// repeat for all points 

var self = this; 
this.PausePoints = [ 
    { 
    name: "Point number 1", 
    func: self 
    }, 
    // repeat for all points 
];  

Так что вы на самом деле делаете, назначая to значение на тот же объект, который имеет свойство PausePoints.

Смежные вопросы