2016-03-02 37 views
0

我處於一種困境,因爲我需要以某種方式更新事件監聽器,當頁面更改使用ajax時。我有一個特定的元素,我需要根據ajax調用注入的頁面進行更新。這裏是我的問題:當頁面切換時更新事件監聽器

我有這個滑塊控件的構造:

UI.CONTROLS.SLIDER = function (select, action, actionWhenActive, actionWhenSet) { 
    'use strict'; 
    var self = this; 
    this.action = action; 
    this.select = select; 
    this.area = select.find($('area-')); 
    this.fill = select.find($('fill-')); 
    this.value = 0; 
    this.active = false; 
    this.actionWhenActive = actionWhenActive; 
    this.actionWhenSet = actionWhenSet; 

    function eventlisteners(self) { 
     $(document).on('mousemove', function (event) { 
      self.move(event, self); 
     }); 
     $(document).on('mouseup', function (event) { 
      self.drop(event, self); 
     }); 
     self.area.on('mousedown', function (event) { 
      self.grab(event, self); 
     }); 
    } 
    eventlisteners(self); 

    this.reselect = function (element) { 
     self.area = element.find($('area-')); 
     self.fill = element.find($('fill-')); 
     eventlisteners(self); 
    }; 
}; 

UI.CONTROLS.SLIDER.prototype = { 
    action: this.action, 
    width: function() { 
     'use strict'; 
     var calcWidth = ((this.value * 100) + '%'); 
     this.fill.width(calcWidth); 
    }, 
    update: function (event, self) { 
     'use strict'; 
     if (this.actionWhenActive === true) { 
      this.action(); 
     } 
     var direction, percent, container, area; 
     direction = event.pageX - this.area.offset().left; 
     percent = Math.min(Math.max(direction/this.area.width(), 0), 1.0); 
     this.value = percent; 
     this.width(); 
    }, 
    move: function (event, self) { 
     'use strict'; 
     if (this.active === true) { 
      this.update(event); 
     } 
    }, 
    grab: function (event, self) { 
     'use strict'; 
     this.active = true; 
     self.update(event); 
     event.preventDefault(); 
    }, 
    drop: function (event, self) { 
     'use strict'; 
     if (this.active === true) { 
      this.active = false; 
      this.action(); 
     } 
    }, 
    setValue: function (value) { 
     'use strict'; 
     if (this.active === false) { 
      this.value = value; 
      this.width(); 
      if (this.actionWhenSet === true) { 
       this.action(); 
      } 
     } 
    } 
}; 

這可以創建基於指定的容器(select)新的滑塊。在我的網站上,我有一個音頻播放器。所以使用ajax你可以在這個音頻播放器播放時導航。我有兩個狀態,觀看曲目,而不是觀看曲目。當您沒有查看正在播放的曲目時,將從包含滑塊控件的標題中彈出一個傳送欄,此滑塊也位於曲目視圖(查看曲目)頁面內。

此代碼檢查您是否正在查看正在播放的曲目。 audioFromView在ajax調用中得到更新,它基本上用你正在查看的軌道替換它。它然後將它與audioCurrent這是當前播放的曲目相比,UI.PAGE.TYPE是您正在查看的頁面類型,在這種情況下軌道:

var audioViewIsCurrent = function() { 
    'use strict'; 
    if (audioCurrent.src === audioFromView.src && UI.PAGE.TYPE === 'track') { 
     return true; 
    } else { 
     return false; 
    } 
}; 

所以這個代碼,然後更新基於上述代碼的輸出洗滌器(audioElementTrackView是軌道頁面內洗滌,並audioElementTransport是運輸板內部的洗滌器):

var audioScrubber = { 
    element: {}, 
    active: false, 
    action: function() { 
     'use strict'; 
     audioScrubber.active = this.active; 
     var time = audioSource.duration * this.value; 
     if (this.active === false) { 
      audioCurrent.time(this.value * duration); 
     } 
    }, 
    set: function() { 
     'use strict'; 
     var container, slider; 
     if (audioElementTrackView.length === 1) { 
      container = audioElementTrackView.find(audioElementScrubber); 
     } else { 
      container = audioElementTransport.find(audioElementScrubber); 
     } 
     this.element = new UI.CONTROLS.SLIDER(container, this.action, true); 
    }, 
    reselect: function() { 
     if (audioElementTrackView.length === 1) { 
      container = audioElementTrackView.find(audioElementScrubber); 
     } else { 
      container = audioElementTransport.find(audioElementScrubber); 
     } 
     this.element.reselect(container) 
    } 
}; 

audioScrubber.reselect() 

因此,這正常工作與我當前如何做它,但是因爲我每次添加新的事件監聽器我更新我的洗滌器對象(在ajax調用中)以保持洗滌器正在工作也使他們堆積起來,使舊的事件聽衆佔用空間和內存最終使網站變慢(如果你足夠導航)

我在mouseup上使用console.log進行了測試,每當我切換頁面時,它會記錄兩次,然後三次,等等。

我該如何避免這種情況?

+0

可以解除綁定正確 –

+1

你爲什麼不委派事件,這樣你就不需要每次重新綁定他們不需要的事件? https://davidwalsh.name/event-delegate –

+0

您的意思是在您的第一個代碼示例中定義的事件?如果是,則將它們附加到文檔根目錄,即使在通過AJAX進行頁面更改時也會保持連接。所以你已經在init上設置了事件的布爾值就足夠了。 – jerone

回答