自动移动的元素

背景:

  今天,突然想到之前碰到过的一个场景:QQ空间中有着一些漂浮的装饰挂件,能够规律性在页面中移动(因为本人之前浏览别人空间时,确实遇到过装饰的非常好看的界面,因此印象比较深刻)。于是非常想知道这个功能是怎么实现的,于是就有了这一篇博客。

 

原理:

  其实,实现原理很简单,就是在页面中添加一些好看的元素,然后使用定时器周期性改变这些元素的位置,这实现了该功能。这个可以在你自己的QQ空间中去验证,如下图片所示:

 

 

 

技术图片

 移动元素的原理

 

代码:

 1 <!DOCTYPE html>
 2 <html>
 3 <head>
 4     <meta charset="UTF-8">
 5     <title>移动标签实践</title>
 6     <style>
 7  body {
 8  width: 1000px;
 9  height: 600px;
 10  margin: 0 auto;
 11  position: relative;
 12  border: black solid 1px;
 13         }
 14  #moveTag {
 15  width: 30px;
 16  height: 30px;
 17  margin: 0;
 18  position: absolute;
 19  box-sizing: border-box;
 20  border: black solid 1px;
 21         }
 22     </style>
 23 </head>
 24 <body>
 25     <div id="moveTag"></div>
 26     <script defer>
 27         // 将传入的属性(string型,单位为 px)转换为 Number
 28  const returnNumber = (num) => {  29  let x = num.indexOf(p)  30             return Number(num.slice(0, x))  31  }  32 
 33         // x 为计算过后的 margin 值,limit 表示移动的范围限制(分为横纵两轴),adjustment 表示的是移动元素的属性(分为width 和height)
 34  const dealLimit = (x, limit, adjustment) => {  35             // console.log(x + ‘ ‘ + limit)
 36             if (x >= limit) {  37                 // 之所以要是使用 limit - adjustment,是因为移动的元素不要移动到当前元素的外面(此时为最大值限制)
 38                 return limit - adjustment + px
 39  } else if (x <= 0) {  40                 // 此时为最小值限制
 41                 return 0 + px
 42  } else {  43                 // 如果移动的值在范围之内,则直接返回
 44                 return x + px
 45  }  46  }  47 
 48         // 该函数是主要的变换函数
 49  const moveTagElement = () => {  50             // 这里使用了闭包,保存了需要大量使用过的变量
 51 
 52  let ele = document.querySelector(#moveTag)  53             // 获取<style>标签中的CSS值
 54             // 注意:ele.style.property 这种语法只能获取内联CSS的属性
 55             // 移动元素的width
 56  let moveTagwidth = returnNumber(window.getComputedStyle(ele).getPropertyValue(width))  57             // 移动元素的heigth
 58  let moveTagheight = returnNumber(window.getComputedStyle(ele).getPropertyValue(height))  59             // 由于 ele 不再使用,故释放 ele 的内存占用
 60  ele = null
 61 
 62  let box = document.querySelector(body)  63             // 参照元素的width
 64  let boxWidth = returnNumber(window.getComputedStyle(box).getPropertyValue(width))  65             // 参照元素的height
 66  let boxHeight = returnNumber(window.getComputedStyle(box).getPropertyValue(height))  67             // 由于 box 不再使用,故释放 box 的内存占用
 68  box = null
 69 
 70             // 用来判断 marginTop 是 + 还是 - ,即移动元素在 x 方向上是右移还是左移
 71  let judgeTop = true
 72             // 用来判断 marginLeft 是 + 还是 -,即移动元素在 y 方向上是是下移还是上移
 73  let judgeLeft = true
 74 
 75             return function () {  76  let ele = document.querySelector(#moveTag)  77  let top = returnNumber(ele.style.marginTop)  78  let left = returnNumber(ele.style.marginLeft)  79 
 80                 // 表示移动的量
 81  let topChange = 10
 82  let leftChange = 10
 83 
 84                 // 这里和前面需要保持一致
 85                 // 如果超过 box 的限制,则改变移动元素移动的方向(上下)
 86                 if (top <= 0 || top >= boxHeight - moveTagheight) {  87  judgeTop = !judgeTop  88  }  89                 // 计算移动的值,并赋值
 90  ele.style.marginTop = judgeTop ? dealLimit(top + topChange, boxHeight, moveTagheight) : dealLimit(top - topChange, boxHeight, moveTagheight)  91 
 92                 // 如果超过 box 的限制,则改变移动元素移动的方向(左右)
 93                 if (left <= 0 || left >= boxWidth - moveTagwidth) {  94  judgeLeft = !judgeLeft  95  }  96                 // 计算移动的值,并赋值
 97  ele.style.marginLeft = judgeLeft ? dealLimit(left + leftChange, boxWidth, moveTagwidth) : dealLimit(left - leftChange, boxWidth, moveTagwidth)  98  }  99  } 100 
101  let func = moveTagElement() 102         // 使用定时器进行周期性控制
103  let timer = setInterval(func, 50) 104     </script>
105 </body>
106 </html>

 

运行结果:

技术图片

运行结果

 

代码说明:

  代码在注释中说的非常明白了,同时原理也并非很复杂,所以这里并不打算在继续使用文字进行相关的原理的介绍,有兴趣的小伙伴可以直接复制代码进行查看。

 

个人吐槽:

  ①. 虽然运行的结果简陋了点,但是原理确实实现了,( 0.0 )如果想更加美观一点,只需要更改界面以及移动元素的背景图片即可。

  ②. 做完这个内容我发现了一个问题:那就是打砖块这个游戏其实原理就是这个(这里自己先挖一个坑)

  ③. over