在resize上重置我的jQuery插件

时间:2014-04-01 16:40:20

标签: javascript jquery jquery-plugins

这与我previous post关于我写的jQuery插件有关。我自己试图提出答案,但我又被卡住了!

基本上,我试图在调整大小时重置我的插件。我有一个等待用户停止调整浏览器大小然后再调用resize函数的函数,但我正在努力解决如何销毁然后重新包装元素的问题。我需要这样做的唯一原因是因为链接周围的动画线条的宽度和高度是固定在' wrap'功能,我需要重置它们。如果有更好的方法可以做到这一点,我很乐意学习它。

我的代码如下:

;

// Avoid `console` errors in browsers that lack a console.
(function () {
    var method;
    var noop = function () {};
    var methods = [
            'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
            'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
            'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
            'timeStamp', 'trace', 'warn'
        ];
    var length = methods.length;
    var console = (window.console = window.console || {});

    while (length--) {
        method = methods[length];

        // Only stub undefined methods.
        if (!console[method]) {
            console[method] = noop;
        }
    }
}());



(function ($, window, document, undefined) {
    // **********************************
    // ***** Start: Private Members *****
    var pluginName = 'onFancyLinks',
        version = '1.0';
    // ***** Fin: Private Members *****
    // ********************************

    // *********************************
    // ***** Start: Public Methods *****
    var methods = {
        init: function (options) {
            //"this" is a jquery object on which this plugin has been invoked.
            return this.each(function (index) {
                var $this = $(this);
                var data = $this.data(pluginName);
                // If the plugin hasn't been initialized yet
                if (!data) {
                    var settings = {
                        lineColor: '#fff',
                        lineWidth: 1,
                        wrapperClass: 'fancy-link',
                        linesClass: 'line',
                        transDuration: '.5',
                        transEase: 'ease-in-out'
                    };
                    if (options) {
                        $.extend(true, settings, options);
                    }

                    $this.data(pluginName, {
                        target: $this,
                        settings: settings
                    });
                }
            });
        },
        wrap: function () {
            return this.each(function () {
                var $this = $(this),
                    data = $this.data(pluginName),
                    opts = data.settings,
                    //wrapping div
                    wrapper = '<div class="' + opts.wrapperClass + '"></div>',
                    lines = {
                        top: '<div class="' + opts.linesClass + ' line-top">&nbsp;</div>',
                        right: '<div class="' + opts.linesClass + ' line-right">&nbsp;</div>',
                        bottom: '<div class="' + opts.linesClass + ' line-bottom">&nbsp;</div>',
                        left: '<div class="' + opts.linesClass + ' line-left">&nbsp;</div>'
                    };

                var $wrapper = $this.wrap(wrapper).parent();
                $wrapper.append(lines.top, lines.right, lines.bottom, lines.left);

                //setup transition duration of lines animation
                $wrapper.find('.' + opts.linesClass).css({
                    /*transition: 'all ' + opts.transDuration + ' ' + opts.transEase,*/
                    backgroundColor: opts.lineColor,
                    borderWidth: opts.lineWidth
                });

                var topBottom = $wrapper.find('.line-top, .line-bottom'),
                    leftRight = $wrapper.find('.line-left, .line-right'),
                    elemWidth = $wrapper.outerWidth(),
                    elemHeight = $wrapper.outerHeight();


                var tl = new TimelineMax({
                    paused: true
                });

                tl.to(topBottom, opts.transDuration, {
                    width: elemWidth - 1
                }).to(leftRight, opts.transDuration, {
                    height: elemHeight - 1
                }, '-=' + opts.transDuration); //at the same time as the one above

                $this.off('hover').hover(function () {
                    tl.play();
                }, function () {
                    tl.reverse();
                });


                return methods.resize.apply($this);

            });
        },
        resize: function () {
            //check when resize has stopped
            var $this = $(this),
                rtime = new Date(1, 1, 2000, 12),
                timeout = false,
                delta = 200;


            $(window).resize(function () {
                rtime = new Date();
                if (timeout === false) {
                    timeout = true;
                    setTimeout(resizeend, delta);
                }
            });

            function resizeend() {
                if (new Date() - rtime < delta) {
                    setTimeout(resizeend, delta);
                } else {
                    timeout = false;
                    //resize has stopped - do something
                    return methods.destroy.apply($this);
                }
            }

        },
        destroy: function() {
            var $this = $(this);
            pluginName.prototype.destroy.call($this);
            return methods.wrap.apply($this);
        }
    };
    // ***** Fin: Public Methods *****
    // *******************************

    // *****************************
    // ***** Start: Supervisor *****
    $.fn[pluginName] = function (method) {
        if (methods[method]) {
            return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
        } else if (typeof method === 'object' || !method) {
            return methods.init.apply(this, arguments);
        } else {
            $.error('Method ' + method + ' does not exist in jQuery.' + pluginName);
        }
    };
    // ***** Fin: Supervisor *****
    // ***************************
})(jQuery, window, document);

$(function() {

        var v1 = $('.flink2').onFancyLinks({
            lineColor: '#f00',
            lineWidth: 1,
            transDuration: '.3'
        });

        var v2 = $('#flink').onFancyLinks({
            lineColor: '#ff0',
            lineWidth: 1,
            transDuration: '0.3'
        });


        v1.onFancyLinks('wrap');
        v2.onFancyLinks('wrap');

    });

HTML:

<a class="flink2" href="http://www.google.co.uk">View Google</a>
<a class="flink2" href="http://www.google.co.uk">View Bubbon</a>
<a id="flink" href="http://www.visarc.co.uk">View Visarc Site</a>

1 个答案:

答案 0 :(得分:1)

听起来这就是你要找的东西:

Updated Fiddle

methods.destroy()修改:

destroy: function() {
    var $this = $(this),
        $thisWrapper = $(this).parent(),
        $origParent = $(this).parent().parent();
    $this.appendTo($origParent);
    $thisWrapper.remove();
    return methods.wrap.apply($this);
}

增加setTimeout的delta以避免过多的DOM操作:

    delta = 1000;

理想情况下,您可以修改插件,以便它可以更新现有元素,而无需删除然后重新添加元素到DOM。但是,在这种情况下,只有重新调整才会发生重新调整并且只影响一些元素,这似乎很好。

如果你想分享这个插件,你应该重新考虑并查看你的wrap()方法中的一些代码。