jquery 动画背景位置 firefox

Posted

技术标签:

【中文标题】jquery 动画背景位置 firefox【英文标题】:jquery animate background-position firefox 【发布时间】:2011-07-27 23:47:41 【问题描述】:

我在 chrome 和 safari 中得到了这个背景图像滑块的东西,但它在 Firefox 中没有任何作用。有什么帮助吗?

$(function()
    var image= ".main-content";
    var button_left= "#button_left";
    var button_right= "#button_right";
    var animation= "easeOutQuint";
    var time= 800;
    var jump= 800;
    var action= 0;

    $(button_left).click(function()
        right();
    );
    $(button_right).click(function()
        left();
    );
    $(document).keydown(function(event)
        if(event.keyCode == '37')
            right();
        
    );
    $(document).keydown(function(event)
        if(event.keyCode == '39')
            left();
        
    );
    function left()
        if(action == 0)
            action= 1;
            $(image).animate(backgroundPositionX: '-='+jump+'px', duration: time, easing: animation);
            setTimeout(anim, time);
        

    
    function right()
        if(action == 0)
            action= 1;
            $(image).animate(backgroundPositionX: '+='+jump+'px', duration: time, easing: animation);
            setTimeout(anim, time);
        
    
    function anim()
        action= 0;
    
); 

我也试过了,但它什么也没做

$(image).animate(backgroundPosition: '500px 0px', 800);

【问题讨论】:

如果有人可以帮助解决我的问题,我会的 【参考方案1】:

以上版本不适用于 jQuery 1.6.1。这个可以。

(function($) 
if(!document.defaultView || !document.defaultView.getComputedStyle)
    var oldCurCSS = jQuery.curCSS;
    jQuery.curCSS = function(elem, name, force)
        if(name === 'background-position')
            name = 'backgroundPosition';
        
        if(name !== 'backgroundPosition' || !elem.currentStyle || elem.currentStyle[ name ])
            return oldCurCSS.apply(this, arguments);
        
        var style = elem.style;
        if ( !force && style && style[ name ] )
            return style[ name ];
        
        return oldCurCSS(elem, 'backgroundPositionX', force) +' '+ oldCurCSS(elem, 'backgroundPositionY', force);
    ;


var oldAnim = $.fn.animate;
$.fn.animate = function(prop)
    if('background-position' in prop)
        prop.backgroundPosition = prop['background-position'];
        delete prop['background-position'];
    
    if('backgroundPosition' in prop)
        prop.backgroundPosition = '('+ prop.backgroundPosition + ')';
    
    return oldAnim.apply(this, arguments);
;

function toArray(strg)
    strg = strg.replace(/left|top/g,'0px');
    strg = strg.replace(/center/g,'50%');
    strg = strg.replace(/right|bottom/g,'100%');
    strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
    var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
    return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];


$.fx.step.backgroundPosition = function(fx) 
    if (!fx.bgPosReady) 
        var start = $.curCSS(fx.elem,'backgroundPosition');

        if(!start)//FF2 no inline-style fallback
            start = '0px 0px';
        

        start = toArray(start);

        fx.start = [start[0],start[2]];

        var end = toArray(fx.end);
        fx.end = [end[0],end[2]];

        fx.unit = [end[1],end[3]];
        fx.bgPosReady = true;
    

    var nowPosX = [];
    nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
    nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
    fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];
;
)(jQuery);

【讨论】:

对于那些想了解更多关于curCSS的人:struckthrough.krystophv.org/tag/curcss $.curCSS() was deprecated in jQuery 1.3 and removed in jQuery 1.8【参考方案2】:

code posted by magiconair 不再适用于 jQuery 1.8。这是一个不使用depreciated $.curCSS() method的补丁版本。

(function($) 
if(!document.defaultView || !document.defaultView.getComputedStyle)
    var oldCSS = jQuery.css;
    jQuery.css = function(elem, name, force)
        if(name === 'background-position')
            name = 'backgroundPosition';
        
        if(name !== 'backgroundPosition' || !elem.currentStyle || elem.currentStyle[ name ])
            return oldCSS.apply(this, arguments);
        
        var style = elem.style;
        if ( !force && style && style[ name ] )
            return style[ name ];
        
        return oldCSS(elem, 'backgroundPositionX', force) +' '+ oldCSS(elem, 'backgroundPositionY', force);
    ;


var oldAnim = $.fn.animate;
$.fn.animate = function(prop)
    if('background-position' in prop)
        prop.backgroundPosition = prop['background-position'];
        delete prop['background-position'];
    
    if('backgroundPosition' in prop)
        prop.backgroundPosition = '('+ prop.backgroundPosition + ')';
    
    return oldAnim.apply(this, arguments);
;

function toArray(strg)
    strg = strg.replace(/left|top/g,'0px');
    strg = strg.replace(/right|bottom/g,'100%');
    strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
    var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
    return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];


$.fx.step.backgroundPosition = function(fx) 
    if (!fx.bgPosReady) 
        var start = $.css(fx.elem,'backgroundPosition');

        if(!start)//FF2 no inline-style fallback
            start = '0px 0px';
        

        start = toArray(start);

        fx.start = [start[0],start[2]];

        var end = toArray(fx.end);
        fx.end = [end[0],end[2]];

        fx.unit = [end[1],end[3]];
        fx.bgPosReady = true;
    

    var nowPosX = [];
    nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
    nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
    fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];
;
)(jQuery);

【讨论】:

【参考方案3】:

这段代码在 jQuery 1.8.1 和 Firefox 上运行良好,我在让 Prydie 的示例工作时遇到了一些问题:

http://nelsonwells.net/2012/08/using-bgpos-js-with-jquery-18/

/**
 * @author Alexander Farkas
 * v. 1.02
 *
 * Edited by Nelson Wells for jQuery 1.8 compatibility
 */
(function($) 
    $.extend($.fx.step,
        backgroundPosition: function(fx) 
            if (fx.pos === 0 && typeof fx.end == 'string') 
                var start = $.css(fx.elem,'backgroundPosition');
                start = toArray(start);
                fx.start = [start[0],start[2]];
                var end = toArray(fx.end);
                fx.end = [end[0],end[2]];
                fx.unit = [end[1],end[3]];
            
            var nowPosX = [];
            nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
            nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
            fx.elem.style.backgroundPosition = nowPosX[0]+' '+nowPosX[1];

            function toArray(strg)
                strg = strg.replace(/left|top/g,'0px');
                strg = strg.replace(/right|bottom/g,'100%');
                strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g,"$1px$2");
                var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
                return [parseFloat(res[1],10),res[2],parseFloat(res[3],10),res[4]];
            
        
    );
)(jQuery);

【讨论】:

【参考方案4】:

这里试试这个背景动画

(function($) 
    if (!document.defaultView || !document.defaultView.getComputedStyle) 
        var oldCurCSS = jQuery.curCSS;
        jQuery.curCSS = function(elem, name, force) 
            if (name === 'background-position') 
                name = 'backgroundPosition';
            
            if (name !== 'backgroundPosition' || !elem.currentStyle || elem.currentStyle[name]) 
                return oldCurCSS.apply(this, arguments);
            
            var style = elem.style;
            if (!force && style && style[name]) 
                return style[name];
            
            return oldCurCSS(elem, 'backgroundPositionX', force) + ' ' + oldCurCSS(elem, 'backgroundPositionY', force);
        ;
    
    var oldAnim = $.fn.animate;
    $.fn.animate = function(prop) 
        if ('background-position' in prop) 
            prop.backgroundPosition = prop['background-position'];
            delete prop['background-position'];
        
        if ('backgroundPosition' in prop) 
            prop.backgroundPosition = '(' + prop.backgroundPosition;
        
        return oldAnim.apply(this, arguments);
    ;

    function toArray(strg) 
        strg = strg.replace(/left|top/g, '0px');
        strg = strg.replace(/right|bottom/g, '100%');
        strg = strg.replace(/([0-9\.]+)(\s|\)|$)/g, "$1px$2");
        var res = strg.match(/(-?[0-9\.]+)(px|\%|em|pt)\s(-?[0-9\.]+)(px|\%|em|pt)/);
        return [parseFloat(res[1], 10), res[2], parseFloat(res[3], 10), res[4]];
    
    $.fx.step.backgroundPosition = function(fx) 
        if (!fx.bgPosReady) 
            var start = $.curCSS(fx.elem, 'backgroundPosition');

            if (!start)  //FF2 no inline-style fallback
                start = '0px 0px';
            
            start = toArray(start);
            fx.start = [start[0], start[2]];
            var end = toArray(fx.options.curAnim.backgroundPosition);
            fx.end = [end[0], end[2]];
            fx.unit = [end[1], end[3]];
            fx.bgPosReady = true;
        
        //return;
        var nowPosX = [];
        nowPosX[0] = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0];
        nowPosX[1] = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1];
        fx.elem.style.backgroundPosition = nowPosX[0] + ' ' + nowPosX[1];
    ;
)(jQuery);

这样调用它,

$(this).animate(
    backgroundPosition: '0 0'
)

【讨论】:

你是否添加了最后几位代码 )(jQuery);到插件的末尾?还要确保你想要动画的是背景图像。 我忘记了额外的位,它起作用了 :) 我必须在左右函数中添加一点来检索新的当前位置,但它可以工作。它仍然不如 webkit 动画那么流畅,但它完成了工作。非常感谢! 不用担心,很高兴为您提供帮助。 请在以后发布时检查您的代码格式。只是粘贴它会破坏缩进,特别是当源代码文件使用制表符时。这次我已经为你修好了:-)(还有语法错误)。 这是插件的链接(在答案中引用):protofunc.com/scripts/jquery/backgroundPosition【参考方案5】:

这里是 Prydie 解决方案的更新(适用于 jQuery 1.80 及更高版本)。

它处理“+=”和“-=”值的情况:

$.fx.step.backgroundPosition = function(fx) 
if (!fx.bgPosReady) 
    var start = toArray($.css(fx.elem,'backgroundPosition') || '0px 0px');
    fx.start = [start[0],start[2]];
    var add = [
        (ret = /([+-])=/.exec( fx.end.split(' ')[0] )) && ret[1],
        (ret = /([+-])=/.exec( fx.end.split(' ')[1] )) && ret[1]
    ];
    var end = toArray(fx.end.replace(/([+-])=/g,''));
    fx.end = [
        add[0]?eval(start[0]+add[0]+end[0]):end[0],
        add[1]?eval(start[1]+add[1]+end[2]):end[2]
    ];
    fx.unit = [end[1],end[3]];
    fx.bgPosReady = true;

fx.now = [
    ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit[0],
    ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit[1]
];
fx.elem.style.backgroundPosition = fx.now[0]+' '+fx.now[1];
;

注意:您必须使用 Prydie 解决方案中的其他方法才能使其工作。

使用示例:

$(this).animate(backgroundPosition:'bottom -=100',5000,'linear',function());

【讨论】:

以上是关于jquery 动画背景位置 firefox的主要内容,如果未能解决你的问题,请参考以下文章

使用 Jquery 在 Firefox 中为背景位置 y 设置动画

jQuery背景按钮动画适用于Chrome和IE8,但不适用于Firefox或IE9 [重复]

jQuery用x和y位置动画背景位置[重复]

jQuery动画背景位置,不适用于ie

同步 jQuery 背景和元素动画

通过关键帧动画背景位置在 Webkit 上不起作用