Saber 酱的抱枕

Fly me to the moon

08/20
2015
学习

解决火狐不支持jq动画的backgroundPosition属性的方法

现在排版的网站中有一个地方,指示器的位置需要变化,我用jQuery做了动画,把这个指示器设置为背景图,然后使用backgroundPosition属性来使其移动。

可是今天测试兼容性的时候发现在火狐下这个动画无效。百度一番,找到了解决办法。参见此处

解决这个问题之前(火狐中无效)的动画代码如下:

$("#anlilist").animate({
	backgroundPositionX:bgLeft+"px",
	backgroundPositionY:"0px"
},100);

这时候X和Y值要分别定义,否则chrome中是无效的。

要解决火狐中无效的问题,先在动画的代码之前加入以下代码:

/**
 * 自定义backgroundPosition的animate,支持火狐,jQuery1.8以上版本
 * @author Meleong
 * v1.00
 */
(function($) {
    $.fx.step["backgroundPosition"] = function(fx) {
        if (typeof fx.end == 'string') {
            fx.start = getBgPos(fx.elem);
            //fx.end原本是一个string,这里将它转换成数组,就不会再进入这个if,也方便我们下面的计算
            //例 "0px -21px"
            fx.end = [parseFloat(fx.end.split(" ")[0]), parseFloat(fx.end.split(" ")[1])];
        }
        //这里fx.pos是根据传入的时间参数,从0到1变化的浮点数
        var nowPosX = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit;
        var nowPosY = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit;
        fx.elem.style.backgroundPosition = nowPosX + ' ' + nowPosY;
        
        /**
         * 获取backgroundPosition数组[top, left],没有单位
         */
        function getBgPos(elem) {
            var top  = 0.0;
            var left = 0.0;
            if ($(elem).css("backgroundPosition")) {
                //例 "0px -21px"
                top  = parseFloat($(elem).css("backgroundPosition").split(" ")[0]);
                left = parseFloat($(elem).css("backgroundPosition").split(" ")[1]);
            }else{
                top  = parseFloat($(elem).css("backgroundPositionX"));
                left = parseFloat($(elem).css("backgroundPositionY"));
            }
            return [top, left];
        }
    }
})(jQuery);

然后改一下动画的代码,把X和Y的值写在一起就行了。

$("#anlilist").animate({
		backgroundPosition: bgLeft.toString()+"px 0px"
},100);

这样写一起chrome里也是能用的,分开写chrome里反而无效了。此时,IE、chrome、firefox三大浏览器里都可以正常实现动画效果了。

合起来的代码如下:

<script src="http://apps.bdimg.com/libs/jquery/1.9.0/jquery.js"></script>
<ul id="anlilist" class="clearfix">
	<li><img src="/f/head2.png" alt=""></li>
	<li><img src="/f/head2.png" alt=""></li>
	<li><img src="/f/head2.png" alt=""></li>
	<li><img src="/f/head2.png" alt=""></li>
</ul>
<style>
	*{margin: 0;padding: 0;}
	li{list-style: none;}
	.clearfix:after{content:".";display:block;height:0; clear:both; visibility:hidden;}
	#anlilist{clear: both;padding-bottom: 17px;margin: 12px 0 0 15px; background: url(http://www.saber.love/demo/jQuery-animate-backgroundPosition/cgal_bg.png) 0 0 no-repeat;}
	#anlilist li{float: left;width: 137px;padding: 13px 3px 3px;margin-right: 7px;height: 129px;cursor: pointer;text-align: center;}
</style>
<script>
	(function($) {
	    $.fx.step["backgroundPosition"] = function(fx) {
	        if (typeof fx.end == 'string') {
	            fx.start = getBgPos(fx.elem);
	            //fx.end原本是一个string,这里将它转换成数组,就不会再进入这个if,也方便我们下面的计算
	            //例 "0px -21px"
	            fx.end = [parseFloat(fx.end.split(" ")[0]), parseFloat(fx.end.split(" ")[1])];
	        }
	        //这里fx.pos是根据传入的时间参数,从0到1变化的浮点数
	        var nowPosX = ((fx.end[0] - fx.start[0]) * fx.pos) + fx.start[0] + fx.unit;
	        var nowPosY = ((fx.end[1] - fx.start[1]) * fx.pos) + fx.start[1] + fx.unit;
	        fx.elem.style.backgroundPosition = nowPosX + ' ' + nowPosY;
	        /**
	         * 获取backgroundPosition数组[top, left],没有单位
	         */
	        function getBgPos(elem) {
	            var top  = 0.0;
	            var left = 0.0;
	            if ($(elem).css("backgroundPosition")) {
	                //例 "0px -21px"
	                top  = parseFloat($(elem).css("backgroundPosition").split(" ")[0]);
	                left = parseFloat($(elem).css("backgroundPosition").split(" ")[1]);
	            }else{
	                top  = parseFloat($(elem).css("backgroundPositionX"));
	                left = parseFloat($(elem).css("backgroundPositionY"));
	            }
	            return [top, left];
	        }
	    }
	})(jQuery);
	//下面做动画时就不能把backgroundPosition的X和Y分开写了,否则无效。
	$(document).ready(function () {
		$("#anlilist li").click(
			function  () {
				var bgLeft=$(this).index()*$(this).outerWidth(true);;
				$("#anlilist").animate({
		 			backgroundPosition: bgLeft.toString()+"px 0px"
				},100);
			}
		);
	})
</script>

关键词:背景偏移 背景定位 backgroundPosition jquery

另外一个低版本ie中jquery做backgroundPosition 动画的代码如下:

<!--兼容ie8以下用jquery来控制动画-->
<!--[if lt IE 9]>
<script type="text/javascript">
$(function(){
$('input[type="text"]').focus(function(){
$(this).removeClass('hover').stop().animate({backgroundPositionY:"-44px"},300);
}).blur(function(){
$(this).stop().animate({backgroundPositionY:"-3px"},300);
});
});

单用了X Y属性,参考一下

解决火狐不支持jq动画的backgroundPosition属性的方法