我處於一種困境,因爲我需要以某種方式更新事件監聽器,當頁面更改使用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進行了測試,每當我切換頁面時,它會記錄兩次,然後三次,等等。
我該如何避免這種情況?
可以解除綁定正確 –
你爲什麼不委派事件,這樣你就不需要每次重新綁定他們不需要的事件? https://davidwalsh.name/event-delegate –
您的意思是在您的第一個代碼示例中定義的事件?如果是,則將它們附加到文檔根目錄,即使在通過AJAX進行頁面更改時也會保持連接。所以你已經在init上設置了事件的布爾值就足夠了。 – jerone