jQuery.animate期间出现视觉故障

Visual glitches during jQuery.animate

本文关键字:视觉 故障 animate jQuery      更新时间:2023-09-26

我几乎完成了在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);

@daniepolencic基本上是对的。原因是填充,并且抽屉和内容共享相同的动画值。这就是为什么在高度动画完成后应用填充的原因。如果将这些值分开,并从抽屉的动画高度中减去顶部和底部填充,则应该是所需的效果。我更新了你的小提琴。

这有帮助吗?

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

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

我不知道为什么会发生这种情况,但我想我知道如何解决它。不要在plugin.ui.content中设置padding的动画,而是创建一个内部div并在那里应用填充。它应该起作用。