2016-03-02 4 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), чтобы сохранить работу скруббера. Я также накапливая их, заставляя слушателей старого события занимать место и оперативную память, в результате чего сайт замедляется до остановки (если вы достаточно перемещаетесь)

Я тестировал это с помощью console.log на мыши, каждый раз, когда я переключал страницу, он будет регистрировать его дважды, а затем трижды и так далее.

Как я могу избежать этого?

+0

вы можете отвязать нежелательные события прямо –

+1

Почему вы не делегируют события, так что вам не нужно пересвязать их каждый раз? https://davidwalsh.name/event-delegate –

+0

Вы имеете в виду события, определенные в вашем первом примере кода? Если да, вы прикрепляете их к корню документа, которые сохраняются в приложении даже при изменении страницы через AJAX. Таким образом, должно быть достаточно булево, чтобы вы уже установили события в init. – jerone

ответ

2

Вы можете делегировать события ближайшему статическому предку, поэтому вам не нужно их повторно переписывать.

Читать эту статью

https://davidwalsh.name/event-delegate

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