例如需求为一张竖直方向的精灵图,给你10个li,需要给每个li展示精灵图中10个不同的图案
首先思路就是通过js的选择器取到所有li的DOM结点并存进一个数组里
let arr = document.querySelectorAll('li')
接着就是通过设置backgroundPosition样式来取精灵图中的不同图案,假设每个图案的大小都是10px,我们就用for循环实现
for(let i = 0; i < arr.length ; i++){
arr[i].style.backgroundPosition = '0 -' + i * 10 + 'px';
}
代码的意思就是第1个li取精灵图中第1个图案,第2个li的图案就往下偏移1 * 10px以此类推
简简单单的几行代码中其实有不少坑
‘0 -’ + i + 'px’是啥意思呢?
首先因为i是一个变量,所以这是拼接字符串的操作
然后’0 -'是啥意思呢?
说到这里,需要检查一下自己是否了解backgroundPosition这个样式属性,如果不了解的话去查查文档
backgroundPosition需要传两个值,分别控制x轴方向和y轴方向
所以我们通过js修改样式的时候需要传的是’10px 10px’这样一个字符串
而里面的数值i是动态的变量,所以需要拼接字符串,i不能包进分号里
然而’0 -’ + i + 'px’看起来好像只有一个值,而backgroundPosition只传一个值的话那么就默认y轴是center,这好像不符合我们的需求(y轴方向取不同图案)
这时候一个非常非常容易被坑的点来了
请注意,'0 -‘之中,0和-中间有一个空格!
这意味着什么呢?意味着最后拼接出的字符串中,其实0就作为了x轴的值,代表x轴方向上不变,y轴方向则是空格后面的-i px
所以最后拼接的结果其实是’0 -ipx’
那么又有一个疑问带出来,这个-号不能写外面吗?
也就是不能写成’0 ’ - i + 'px’吗?
答案当然是不能的,别忘了我们是在拼接字符串,而拼接字符串是需要+号来进行的,如果非要把-号写在外面,那么就要写成以下形式:
'0 ’ + -i + ‘px’
然而这样很难看,所以还是乖乖把-号写在分号里面把
最后的疑问就是为什么我们非要取一个负值?精灵图中需要往下取图案,难道i不是应该越来越大吗?
这就需要借助图形来理解了
如果实在理解不了的可以在csdn搜backgroundPosition,有很多文章用的图片会比我专业易懂很多

首先backgroundPosition的初始值是0,0,此时图片在容器的左上角
一般情况下是盒子比图片大很多,我们需要让图片移动到盒子中指定位置
然而,我们现在的精灵图是盒子比图片小,也就是下图这样:

其中黑圈代表我们的容器,而黄色长条就是整个精灵图,红框则是每个图案
所以也就意味着如果y值取正数,那么图片就往下跑了,我们的容器就啥也看不见了,所以需要取负值,让图片向上移动,这样容器就能取到第2个,第3个图案了
注意这里的原理跟商城项目中的放大镜效果是一样的,其中放大后的图片为什么要取负值,跟这个原理是一样的,好好理解就能一次学会两个效果的实现,建议自己写个demo调调看backgroundPosition方便理解