简体   繁体   English

使用jQuery .empty()删除动态元素

[英]Using jQuery .empty() to remove dynamic elements

I'm using the jQuery SimplyScroll plugin to create a circular image carousel on my page. 我正在使用jQuery SimplyScroll插件在页面上创建圆形图像轮播。 I start off with a simple empty <div> : 我从一个简单的空<div>

<div id="scroller-wrapper">

</div>

I then append an unordered list... 然后,我追加一个无序列表...

$("#scroller-wrapper").append("<ul id='scroller' />");

...to which I dynamically add the images and then initiate the SimplyScroll plugin. ...我向其中动态添加图像,然后启动SimplyScroll插件。 That results in this: 结果是:

<div id="scroller-wrapper">
    <div class="simply-scroll simply-scroll-container">
        <div class="simply-scroll-clip">
            <ul id="scroller" class="simply-scroll-list" style="width: 2808px;">
                <li><img src="image1.png" alt="Image 1" /></li>
                <!-- more images -->
            </ul>
        </div>
    </div>
</div>

So far so good. 到现在为止还挺好。 The problem is that periodically, I need to completely empty the scroller and reinitialize it with all new images. 问题在于,我需要定期完全清空滚动条,并使用所有新图像重新初始化它。 So at the time the unordered list is appended, I tried emptying the wrapping <div> first, like this: 因此,在追加无序列表时,我尝试先清空包装的<div> ,如下所示:

$("#scroller-wrapper").empty().append("<ul id='scroller' />");

But as you can see, SimplyScroll has dynamically inserted a few of its own <div> s, and those don't seem to be affected by .empty() . 但是如您所见,SimplyScroll已经动态插入了一些自己的<div> ,而这些似乎不受.empty()影响。 So when I reinitialize the scroller, I get this: 因此,当我重新初始化滚动器时,得到以下信息:

<div id="scroller-wrapper">
    <div class="simply-scroll simply-scroll-container">
        <div class="simply-scroll-clip">
            <div class="simply-scroll simply-scroll-container">
                <div class="simply-scroll-clip">
                    <ul id="scroller" class="simply-scroll-list" style="width: 2808px;">
                        <li><img src="image1.png" alt="Image 1" /></li>
                        <!-- more images -->
                    </ul>
                </div>
            </div>
        </div>
    </div>
</div>

Since the <div> s that were generated by SimplyScroll weren't removed, the new scroller is appended inside of them and it doesn't work. 由于没有删除SimplyScroll生成的<div> ,因此新的滚动条将附加在其内部,并且不起作用。

How do I completely empty out the contents of #scroller , including the dynamically added elements, so that I can start over "from scratch" each time I initialize the scroller? 如何完全清空#scroller的内容(包括动态添加的元素),以便每次初始化滚动器时都可以从头开始?

I have ported some standard code I use from TypeScript to Javascript and enhanced SimplyScroll to support instance data and method calls. 我已经将我使用的一些标准代码从TypeScript移植到Javascript,并增强了SimplyScroll以支持实例数据和方法调用。

I also added stop and start methods for you to allow you to kill the timers and reinitialise the layout after items change. 我还为您添加了stopstart方法,以允许您杀死计时器并在项目更改后重新初始化布局。

I don't have time to complete this, but it should give you the hooks you need now. 我没有时间来完成此操作,但是它应该为您提供了现在需要的功能。

Use it like this: 像这样使用它:

$("#images").simplyScroll({...options...});

Then when you want to change content: 然后,当您想更改内容时:

$('#images').simplyScroll('stop');
$('#images').empty().append('...new content...')
$('#images').simplyScroll('start');

Full modified code below: 完整的修改代码如下:

/*
 * simplyScroll 2 - a scroll-tastic jQuery plugin
 *
 * http://logicbox.net/jquery/simplyscroll/
 *
 * Copyright (c) 2009-2012 Will Kelly - http://logicbox.net
 *
 * Dual licensed under the MIT and GPL licenses.
 *
 * Version: 2.0.5 Last revised: 10/05/2012
 *
 */

(function ($, window, undefined) {
    $.fn.simplyScroll = function (options, args) {
        var THIS = this;
        // If a string is supplied, assume we are calling a method on the add-in
        if (typeof options === 'string') {
            this.each(function () {
                var instance = $(this).data('simplyscroll');
                if (!instance) {
                    alert("Attempted to call method '" + options + "' prior to initialization.");
                    return;
                }
                if (!$.isFunction(instance[options])) {
                    alert("Method '" + options + "' does not exist");
                    return;
                }
                instance[options].apply(instance, args);
            });

        }
        else {
            THIS.each(function () {
                var instance = $(this).data('simplyscroll');
                if (instance) {
                    // Reinit the add-in options
                    instance._changeOptions(options);
                } else {
                    $(this).data('simplyscroll', new $.simplyScroll(this, options));
                }
            });
        }
        return THIS;
        //return this.each(function () {
        //    new $.simplyScroll(this, options);
        //});
    };

    var defaults = {
        customClass: 'simply-scroll',
        frameRate: 24, //No of movements per second
        speed: 1, //No of pixels per frame
        orientation: 'horizontal', //'horizontal or 'vertical' - not to be confused with device orientation
        auto: true,
        autoMode: 'loop', //auto = true, 'loop' or 'bounce',
        manualMode: 'end', //auto = false, 'loop' or 'end'
        direction: 'forwards', //'forwards' or 'backwards'.
        pauseOnHover: true, //autoMode = loop|bounce only
        pauseOnTouch: true, //" touch device only
        pauseButton: false, //" generates an extra element to allow manual pausing 
        startOnLoad: false //use this to delay starting of plugin until all page assets have loaded
    };

    $.simplyScroll = function (el, options) {

        var self = this;

        this.o = $.extend({}, defaults, options || {});
        this.isAuto = this.o.auto !== false && this.o.autoMode.match(/^loop|bounce$/) !== null;
        this.isHorizontal = this.o.orientation.match(/^horizontal|vertical$/) !== null && this.o.orientation == defaults.orientation;
        this.isRTL = this.isHorizontal && $("html").attr('dir') == 'rtl';
        this.isForwards = !this.isAuto || (this.isAuto && this.o.direction.match(/^forwards|backwards$/) !== null && this.o.direction == defaults.direction) && !this.isRTL;
        this.isLoop = this.isAuto && this.o.autoMode == 'loop' || !this.isAuto && this.o.manualMode == 'loop';

        this.supportsTouch = ('createTouch' in document);

        this.events = this.supportsTouch ?
        { start: 'touchstart MozTouchDown', move: 'touchmove MozTouchMove', end: 'touchend touchcancel MozTouchRelease' } :
        { start: 'mouseenter', end: 'mouseleave' };

        this.$list = $(el); //called on ul/ol/div etc
        var $items = this.$list.children();

        //generate extra markup
        this.$list.addClass('simply-scroll-list')
            .wrap('<div class="simply-scroll-clip"></div>')
            .parent().wrap('<div class="' + this.o.customClass + ' simply-scroll-container"></div>');

        if (!this.isAuto) { //button placeholders
            this.$list.parent().parent()
            .prepend('<div class="simply-scroll-forward"></div>')
            .prepend('<div class="simply-scroll-back"></div>');
        } else {
            if (this.o.pauseButton) {
                this.$list.parent().parent()
                .prepend('<div class="simply-scroll-btn simply-scroll-btn-pause"></div>');
                this.o.pauseOnHover = false;
            }
        }

        //wrap an extra div around the whole lot if elements scrolled aren't equal
        if ($items.length > 1) {

            var extra_wrap = false,
                total = 0;

            if (this.isHorizontal) {
                $items.each(function () { total += $(this).outerWidth(true); });
                extra_wrap = $items.eq(0).outerWidth(true) * $items.length !== total;
            } else {
                $items.each(function () { total += $(this).outerHeight(true); });
                extra_wrap = $items.eq(0).outerHeight(true) * $items.length !== total;
            }

            if (extra_wrap) {
                this.$list = this.$list.wrap('<div></div>').parent().addClass('simply-scroll-list');
                if (this.isHorizontal) {
                    this.$list.children().css({ "float": 'left', width: total + 'px' });
                } else {
                    this.$list.children().css({ height: total + 'px' });
                }
            }
        }

        if (!this.o.startOnLoad) {
            this.init();
        } else {
            //wait for load before completing setup
            $(window).load(function () { self.init(); });
        }

    };

    $.simplyScroll.fn = $.simplyScroll.prototype = {};

    $.simplyScroll.fn.extend = $.simplyScroll.extend = $.extend;

    $.simplyScroll.fn.extend({
        _changeOptions: function (options) {
            // Options have changed - reinit
        },
        stop: function () {
            this.isAuto = false;
            this.moveStop(this.movement);
        },
        start: function () {
            this.init();
            this.isAuto = true;
        },
        init: function () {

            this.$items = this.$list.children();
            this.$clip = this.$list.parent(); //this is the element that scrolls
            this.$container = this.$clip.parent();
            this.$btnBack = $('.simply-scroll-back', this.$container);
            this.$btnForward = $('.simply-scroll-forward', this.$container);


            if (!this.isHorizontal) {
                this.itemMax = this.$items.eq(0).outerHeight(true);
                this.clipMax = this.$clip.height();
                this.dimension = 'height';
                this.moveBackClass = 'simply-scroll-btn-up';
                this.moveForwardClass = 'simply-scroll-btn-down';
                this.scrollPos = 'Top';
            } else {
                this.itemMax = this.$items.eq(0).outerWidth(true);
                this.clipMax = this.$clip.width();
                this.dimension = 'width';
                this.moveBackClass = 'simply-scroll-btn-left';
                this.moveForwardClass = 'simply-scroll-btn-right';
                this.scrollPos = 'Left';
            }

            this.posMin = 0;

            this.posMax = this.$items.length * this.itemMax;

            var addItems = Math.ceil(this.clipMax / this.itemMax);

            //auto scroll loop & manual scroll bounce or end(to-end)
            if (this.isAuto && this.o.autoMode == 'loop') {

                this.$list.css(this.dimension, this.posMax + (this.itemMax * addItems) + 'px');

                this.posMax += (this.clipMax - this.o.speed);

                if (this.isForwards) {
                    this.$items.slice(0, addItems).clone(true).appendTo(this.$list);
                    this.resetPosition = 0;

                } else {
                    this.$items.slice(-addItems).clone(true).prependTo(this.$list);
                    this.resetPosition = this.$items.length * this.itemMax;
                    //due to inconsistent RTL implementation force back to LTR then fake
                    if (this.isRTL) {
                        this.$clip[0].dir = 'ltr';
                        //based on feedback seems a good idea to force float right
                        this.$items.css('float', 'right');
                    }
                }

                //manual and loop
            } else if (!this.isAuto && this.o.manualMode == 'loop') {

                this.posMax += this.itemMax * addItems;

                this.$list.css(this.dimension, this.posMax + (this.itemMax * addItems) + 'px');

                this.posMax += (this.clipMax - this.o.speed);

                var items_append = this.$items.slice(0, addItems).clone(true).appendTo(this.$list);
                var items_prepend = this.$items.slice(-addItems).clone(true).prependTo(this.$list);

                this.resetPositionForwards = this.resetPosition = addItems * this.itemMax;
                this.resetPositionBackwards = this.$items.length * this.itemMax;

                //extra events to force scroll direction change
                var self = this;

                this.$btnBack.bind(this.events.start, function () {
                    self.isForwards = false;
                    self.resetPosition = self.resetPositionBackwards;
                });

                this.$btnForward.bind(this.events.start, function () {
                    self.isForwards = true;
                    self.resetPosition = self.resetPositionForwards;
                });

            } else { //(!this.isAuto && this.o.manualMode=='end') 

                this.$list.css(this.dimension, this.posMax + 'px');

                if (this.isForwards) {
                    this.resetPosition = 0;

                } else {
                    this.resetPosition = this.$items.length * this.itemMax;
                    //due to inconsistent RTL implementation force back to LTR then fake
                    if (this.isRTL) {
                        this.$clip[0].dir = 'ltr';
                        //based on feedback seems a good idea to force float right
                        this.$items.css('float', 'right');
                    }
                }
            }

            this.resetPos() //ensure scroll position is reset

            this.interval = null;
            this.intervalDelay = Math.floor(1000 / this.o.frameRate);

            if (!(!this.isAuto && this.o.manualMode == 'end')) { //loop mode
                //ensure that speed is divisible by item width. Helps to always make images even not odd widths!
                while (this.itemMax % this.o.speed !== 0) {
                    this.o.speed--;
                    if (this.o.speed === 0) {
                        this.o.speed = 1;
                        break;
                    }
                }
            }

            var self = this;
            this.trigger = null;
            this.funcMoveBack = function (e) {
                if (e !== undefined) {
                    e.preventDefault();
                }
                self.trigger = !self.isAuto && self.o.manualMode == 'end' ? this : null;
                if (self.isAuto) {
                    self.isForwards ? self.moveBack() : self.moveForward();
                } else {
                    self.moveBack();
                }
            };
            this.funcMoveForward = function (e) {
                if (e !== undefined) {
                    e.preventDefault();
                }
                self.trigger = !self.isAuto && self.o.manualMode == 'end' ? this : null;
                if (self.isAuto) {
                    self.isForwards ? self.moveForward() : self.moveBack();
                } else {
                    self.moveForward();
                }
            };
            this.funcMovePause = function () { self.movePause(); };
            this.funcMoveStop = function () { self.moveStop(); };
            this.funcMoveResume = function () { self.moveResume(); };

            if (this.isAuto) {

                this.paused = false;

                function togglePause() {
                    if (self.paused === false) {
                        self.paused = true;
                        self.funcMovePause();
                    } else {
                        self.paused = false;
                        self.funcMoveResume();
                    }
                    return self.paused;
                };

                //disable pauseTouch when links are present
                if (this.supportsTouch && this.$items.find('a').length) {
                    this.supportsTouch = false;
                }

                if (this.isAuto && this.o.pauseOnHover && !this.supportsTouch) {
                    this.$clip.bind(this.events.start, this.funcMovePause).bind(this.events.end, this.funcMoveResume);
                } else if (this.isAuto && this.o.pauseOnTouch && !this.o.pauseButton && this.supportsTouch) {

                    var touchStartPos, scrollStartPos;

                    this.$clip.bind(this.events.start, function (e) {
                        togglePause();
                        var touch = e.originalEvent.touches[0];
                        touchStartPos = self.isHorizontal ? touch.pageX : touch.pageY;
                        scrollStartPos = self.$clip[0]['scroll' + self.scrollPos];
                        e.stopPropagation();
                        e.preventDefault();

                    }).bind(this.events.move, function (e) {

                        e.stopPropagation();
                        e.preventDefault();

                        var touch = e.originalEvent.touches[0],
                            endTouchPos = self.isHorizontal ? touch.pageX : touch.pageY,
                            pos = (touchStartPos - endTouchPos) + scrollStartPos;

                        if (pos < 0) pos = 0;
                        else if (pos > self.posMax) pos = self.posMax;

                        self.$clip[0]['scroll' + self.scrollPos] = pos;

                        //force pause
                        self.funcMovePause();
                        self.paused = true;
                    });
                } else {
                    if (this.o.pauseButton) {

                        this.$btnPause = $(".simply-scroll-btn-pause", this.$container)
                            .bind('click', function (e) {
                                e.preventDefault();
                                togglePause() ? $(this).addClass('active') : $(this).removeClass('active');
                            });
                    }
                }
                this.funcMoveForward();
            } else {

                this.$btnBack
                    .addClass('simply-scroll-btn' + ' ' + this.moveBackClass)
                    .bind(this.events.start, this.funcMoveBack).bind(this.events.end, this.funcMoveStop);
                this.$btnForward
                    .addClass('simply-scroll-btn' + ' ' + this.moveForwardClass)
                    .bind(this.events.start, this.funcMoveForward).bind(this.events.end, this.funcMoveStop);

                if (this.o.manualMode == 'end') {
                    !this.isRTL ? this.$btnBack.addClass('disabled') : this.$btnForward.addClass('disabled');
                }
            }
        },
        moveForward: function () {
            var self = this;
            this.movement = 'forward';
            if (this.trigger !== null) {
                this.$btnBack.removeClass('disabled');
            }
            self.interval = setInterval(function () {
                if (self.$clip[0]['scroll' + self.scrollPos] < (self.posMax - self.clipMax)) {
                    self.$clip[0]['scroll' + self.scrollPos] += self.o.speed;
                } else if (self.isLoop) {
                    self.resetPos();
                } else {
                    self.moveStop(self.movement);
                }
            }, self.intervalDelay);
        },
        moveBack: function () {
            var self = this;
            this.movement = 'back';
            if (this.trigger !== null) {
                this.$btnForward.removeClass('disabled');
            }
            self.interval = setInterval(function () {
                if (self.$clip[0]['scroll' + self.scrollPos] > self.posMin) {
                    self.$clip[0]['scroll' + self.scrollPos] -= self.o.speed;
                } else if (self.isLoop) {
                    self.resetPos();
                } else {
                    self.moveStop(self.movement);
                }
            }, self.intervalDelay);
        },
        movePause: function () {
            clearInterval(this.interval);
        },
        moveStop: function (moveDir) {
            this.movePause();
            if (this.trigger !== null) {
                if (typeof moveDir !== 'undefined') {
                    $(this.trigger).addClass('disabled');
                }
                this.trigger = null;
            }
            if (this.isAuto) {
                if (this.o.autoMode == 'bounce') {
                    moveDir == 'forward' ? this.moveBack() : this.moveForward();
                }
            }
        },
        moveResume: function () {
            this.movement == 'forward' ? this.moveForward() : this.moveBack();
        },
        resetPos: function () {
            this.$clip[0]['scroll' + this.scrollPos] = this.resetPosition;
        }
    });

})(jQuery, window);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM