jQuery.animate期间的视觉故障

时间:2013-08-15 21:17:46

标签: javascript jquery jquery-animate

我差不多在jQuery中实现了一个向下滑动的抽屉。当您单击标记为show的句柄时,它应向下展开抽屉,公开内容。单击手柄应将抽屉向上滑动。除了一些视觉故障之外,它的效果很好,我不知道它们为什么会发生。请参阅下面的工作示例。

http://jsfiddle.net/fKUy9/1/

当您单击手柄时,抽屉会按预期滑下,但手柄会停止。此外,当向上和向下滑动时,抽屉作为整体在页面上向上然后向下跳跃,就像上边距被修改一样。任何人都可以帮我解决这个问题吗?

代码:

(function($){
    $.cabinet = function(options) {
        plugin = this;

        plugin.ui = {};
        plugin.settings = $.extend({}, $.cabinet.prototype.defaultOptions, (typeof options === 'object') ? options : {});

        plugin.content = function(contentCallback){
            contentCallback(plugin.ui.content);
        }

        var init = function() {
            createHTMLElements();
            bindUIEvents();
            attachToDOM();
            mockCSS();
        }

        var createHTMLElements = function() {
            plugin.ui.body = $('body');
            plugin.ui.drawer = $('<div id="drawer" data-expanded="false"></div>');
            plugin.ui.content = $('<div id="drawer-content"></div>');
            plugin.ui.handle = $('<div id="drawer-handle">Show</div>');
        };

        var mockCSS = function() {
            plugin.ui.drawer.css({
                'height': plugin.settings.collapsed_height,
                'width': plugin.settings.drawer_width,
                'margin': '0 auto',
                'position': 'relative',
                'font-family': 'Helvetica, Verdana, Arial, sans-serif'
            });

            plugin.ui.content.css({
                'background': '#cccccc',
                'height': plugin.settings.collapsed_height,
                'font-size': '.75em'
            });

            plugin.ui.handle.css({
                'height': plugin.settings.collapsed_height,
                'width': plugin.settings.drawer_width,
                'position': 'absolute',
                'bottom': '-1px',
                'left': (plugin.ui.drawer.width()/2) - (plugin.ui.handle.width()/2),
                'text-align': 'center',
                'background': '#333',
                'color': '#fff',
                'cursor': 'pointer',
                'font-size': '.7em',
                'padding-top': '5px',
                'padding-bottom': '5px'
            });
        };

        var bindUIEvents = function() {
            plugin.ui.handle.on('click', function(e){
                plugin.ui.drawer.data('expanded', plugin.ui.drawer.data('expanded') === true ? false : true);
                plugin.ui.handle.data('label', plugin.ui.drawer.data('expanded') === true ? 'Hide' : 'Show');

                if(plugin.ui.drawer.data('expanded') === true) {
                    expandDrawer();
                } else {
                    collapseDrawer();
                }
            });
        };

        var attachToDOM = function() {
            var fragment = document.createDocumentFragment();

            plugin.ui.drawer.appendTo(fragment);
            plugin.ui.content.appendTo(plugin.ui.drawer);
            plugin.ui.handle.appendTo(plugin.ui.drawer);

            plugin.ui.body.prepend(fragment);
        };

        var collapseDrawer = function() {
            var shared_animiations = {
                'height': '-='+plugin.settings.content_height
            }

            plugin.ui.drawer.animate($.extend({}, shared_animiations));

            plugin.ui.content.animate($.extend({
                'padding': 0,
                'overflow': 'hidden'
            }, shared_animiations));

            plugin.ui.handle.text(plugin.ui.handle.data('label'));
        };

        var expandDrawer = function() {
            var shared_animiations = {
                'height': '+='+plugin.settings.content_height
            }

            plugin.ui.drawer.animate($.extend({}, shared_animiations));

            plugin.ui.content.animate($.extend({
                'padding': 25,
            }, shared_animiations));

            plugin.ui.handle.text(plugin.ui.handle.data('label'));
        };

        init();

        return plugin;
    }

    $.cabinet.prototype.defaultOptions = {
        drawer_width: 750,
        content_height: 200,
        handle_height: 15,
        drawer_height: 30
    }
})(jQuery);

2 个答案:

答案 0 :(得分:0)

当jQuery为plugin.ui.content设置动画时,它会更改heightpadding。当动画停止时,由于我仍然需要理解的原因,重新应用正确的填充,突然你可以看到故障。

我不知道为什么会这样,但我想我知道你怎么能解决它。不要为padding中的plugin.ui.content设置动画,但要创建一个内部div并在那里应用填充。应该这样做。

答案 1 :(得分:0)

@danielepolencic基本上是正确的。原因是填充,您为抽屉和内容共享相同的动画值。这就是在高度动画结束后应用填充的原因。 如果将这些值分开并从抽屉的动画高度中减去顶部和底部填充,则应该是所需的效果。 我对您的fiddle进行了更新。

这有帮助吗?

var content_animiations = {
        'height':  plugin.settings.content_height
    },
    drawer_animiations = {
        'height':  plugin.settings.content_height + 50
    };


    plugin.ui.content.animate($.extend({
        'padding': 25,
    }, content_animiations))


    plugin.ui.drawer.animate($.extend({}, drawer_animiations));