鱼C论坛

 找回密码
 立即注册
查看: 4569|回复: 4

[已解决]关于js 匀速运动

[复制链接]
发表于 2020-9-18 15:20:53 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <style type="text/css">
      * {
        margin: 0;
        padding: 0;
      }
      div {
        width: 100px;
        height: 100px;
        background: black;
        position: absolute;
      }
      /* div:nth-of-type(2) {
        width: 150px;
        height: 150px;
        background: black;
        position: absolute;
        right: 0;
      } */
    </style>
    <script type="text/javascript">
      // 匀速运动
      window.onload = function () {
        var odiv = document.getElementsByTagName("div");
        var speedX = 3;
        var speedY = 3;
        function move() {
          var currentleft = parseInt(window.getComputedStyle(odiv).left);
          var currenttop = parseInt(window.getComputedStyle(odiv).top);
          odiv.style.left = currentleft + speedX + "px";
        }
        setInterval(function () {
          move();
        }, 20);
      };
    </script>
  </head>
  <body>
    <div></div>
    <!-- <div></div> -->
  </body>
</html>
代码如上 为什么用谷歌浏览器function move() {
          var currentleft = parseInt(window.getComputedStyle(odiv).left);
          var currenttop = parseInt(window.getComputedStyle(odiv).top);
          odiv.style.left = currentleft + speedX + "px";
        }会报错
Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.
    at move (匀速加碰撞检测.html:41)
    at 匀速加碰撞检测.html:46
最佳答案
2023-7-21 08:33:29
原因是 getComputedStyle() 方法需要传入一个 DOM 元素作为参数,你传入的 odiv 是 DOM 元素集合,不是单个元素。

可以这样修改:

  1. var odiv = document.getElementsByTagName("div")[0];
  2. // 传入具体的 DIV 元素

  3. function move() {
  4.   var currentleft = parseInt(window.getComputedStyle(odiv).left);
  5.   var currenttop = parseInt(window.getComputedStyle(odiv).top);
  6.   odiv.style.left = currentleft + speedX + "px";
  7. }
复制代码

getComputedStyle() 需要一个具体的 DOM 元素作为参数,你传入的 odiv 通过 getElementsByTagName 获取的是一组 DOM 元素,不是单个元素,所以会报错。

指定获取第一个 DIV 元素传递给 getComputedStyle() 就可以了。
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2020-9-18 16:15:48 | 显示全部楼层

回帖奖励 +1 鱼币

var odiv = document.getElementsByTagName("div")
odiv的类型是HTMLCollection类数组

Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'.

说的是参数1必须是一个Element类型

所以你应该传 如 odiv[0] 进去


小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-9-18 17:03:53 | 显示全部楼层
kogawananari 发表于 2020-9-18 16:15
var odiv = document.getElementsByTagName("div")
odiv的类型是HTMLCollection类数组

那该怎么改呢? 我要让currentleft = div的left值
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-18 17:50:04 | 显示全部楼层
良木 发表于 2020-9-18 17:03
那该怎么改呢? 我要让currentleft = div的left值

emmm 这个写起来蛮费脑子的 我复制一段我以前写过的吧
  1. <style>
  2.     .box {
  3.         width: 100px;
  4.         height: 200px;
  5.         background-color: red;
  6.         position: absolute;
  7.     }
  8. </style>
  9. <script>
  10.     function getStyle(ele) {
  11.         return ele.currentStyle || getComputedStyle(ele)
  12.     }

  13.     //简单的解决兼容问题
  14.     window.requestAnimationFrame = window.requestAnimationFrame || function (cb) { return setTimeout(cb, 1000 / 60) }
  15.     window.cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout

  16.     function animation(ele, data = {}, time = 500, cb) {
  17.         /*
  18.          * ele => 已获取的HTML标签对象
  19.          * data => 需要改变的样式:目标数值 可以带单位
  20.          * time => 改变样式所需要的总时间 单位是毫秒
  21.          * 例如 : animation(box,{width:'1000px',height:'1000px'},5000)
  22.          */
  23.         var startValue = {}
  24.         var changeValue = {}
  25.         var startTime = new Date()
  26.         var eleStart = getStyle(ele)
  27.         for (var key in data) {
  28.             startValue[key] = isNaN(Number.parseFloat(eleStart[key])) ? 0 : Number.parseFloat(eleStart[key])
  29.             changeValue[key] = Number.parseFloat(data[key]) - startValue[key]
  30.         }
  31.         run()
  32.         function run() {
  33.             var nowTime = new Date() - startTime
  34.             var t1 = nowTime / time
  35.             for (var key in changeValue) {
  36.                 var val = t1 * changeValue[key] + startValue[key]
  37.                 ele.style[key] = val + 'px'
  38.             }
  39.             if (t1 >= 1) {
  40.                 cancelAnimationFrame(run)
  41.                 cb && cb()
  42.             } else {
  43.                 requestAnimationFrame(run)
  44.             }
  45.         }
  46.     }
  47. </script>
  48. <div id="box1" class="box"></div>
  49. <script>
  50.     function run1() {
  51.         animation(box1, { marginLeft: '300px' }, 2000, run2)
  52.     }
  53.     function run2() {
  54.         animation(box1, { marginLeft: '0px' }, 2000, run1)
  55.     }
  56.     run1()
  57. </script>
复制代码
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-7-21 08:33:29 | 显示全部楼层    本楼为最佳答案   
原因是 getComputedStyle() 方法需要传入一个 DOM 元素作为参数,你传入的 odiv 是 DOM 元素集合,不是单个元素。

可以这样修改:

  1. var odiv = document.getElementsByTagName("div")[0];
  2. // 传入具体的 DIV 元素

  3. function move() {
  4.   var currentleft = parseInt(window.getComputedStyle(odiv).left);
  5.   var currenttop = parseInt(window.getComputedStyle(odiv).top);
  6.   odiv.style.left = currentleft + speedX + "px";
  7. }
复制代码

getComputedStyle() 需要一个具体的 DOM 元素作为参数,你传入的 odiv 通过 getElementsByTagName 获取的是一组 DOM 元素,不是单个元素,所以会报错。

指定获取第一个 DIV 元素传递给 getComputedStyle() 就可以了。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-8 18:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表