页面切换时更新事件侦听器

时间:2016-03-02 10:44:26

标签: javascript jquery ajax

我有点陷入困境,因为当页面使用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;
    }
};

因此,此代码会根据上面的代码输出更新scrubber(audioElementTrackView是track页面内的scrubber,audioElementTransport是传输面板内的scrubber):

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()

所以这适用于我目前正在做的事情,但是因为我每次更新我的scrubber对象(在ajax调用中)时都要添加新的事件监听器以保持洗涤器工作我也在堆积它们up,使旧的事件监听器占用空间和RAM最终使网站减速停止(如果你足够导航)

我在mouseup上使用console.log进行了测试,每次切换页面时,都会记录两次,然后三次等等。

我该如何避免这种情况?

1 个答案:

答案 0 :(得分:2)

您可以将事件委托给最近的静态祖先,这样您就不需要每次重新绑定它们。

阅读这篇文章

https://davidwalsh.name/event-delegate