鱼C论坛

 找回密码
 立即注册
查看: 3973|回复: 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 元素集合,不是单个元素。

可以这样修改:
var odiv = document.getElementsByTagName("div")[0];
// 传入具体的 DIV 元素

function move() {
  var currentleft = parseInt(window.getComputedStyle(odiv).left);
  var currenttop = parseInt(window.getComputedStyle(odiv).top);
  odiv.style.left = currentleft + speedX + "px"; 
}
getComputedStyle() 需要一个具体的 DOM 元素作为参数,你传入的 odiv 通过 getElementsByTagName 获取的是一组 DOM 元素,不是单个元素,所以会报错。

指定获取第一个 DIV 元素传递给 getComputedStyle() 就可以了。
想知道小甲鱼最近在做啥?请访问 -> 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] 进去


想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

那该怎么改呢? 我要让currentleft = div的left值
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

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

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

    function animation(ele, data = {}, time = 500, cb) {
        /*
         * ele => 已获取的HTML标签对象
         * data => 需要改变的样式:目标数值 可以带单位
         * time => 改变样式所需要的总时间 单位是毫秒
         * 例如 : animation(box,{width:'1000px',height:'1000px'},5000)
         */
        var startValue = {}
        var changeValue = {}
        var startTime = new Date()
        var eleStart = getStyle(ele)
        for (var key in data) {
            startValue[key] = isNaN(Number.parseFloat(eleStart[key])) ? 0 : Number.parseFloat(eleStart[key])
            changeValue[key] = Number.parseFloat(data[key]) - startValue[key]
        }
        run()
        function run() {
            var nowTime = new Date() - startTime
            var t1 = nowTime / time
            for (var key in changeValue) {
                var val = t1 * changeValue[key] + startValue[key]
                ele.style[key] = val + 'px'
            }
            if (t1 >= 1) {
                cancelAnimationFrame(run)
                cb && cb()
            } else {
                requestAnimationFrame(run)
            }
        }
    }
</script>
<div id="box1" class="box"></div>
<script>
    function run1() {
        animation(box1, { marginLeft: '300px' }, 2000, run2)
    }
    function run2() {
        animation(box1, { marginLeft: '0px' }, 2000, run1)
    }
    run1()
</script>
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

可以这样修改:
var odiv = document.getElementsByTagName("div")[0];
// 传入具体的 DIV 元素

function move() {
  var currentleft = parseInt(window.getComputedStyle(odiv).left);
  var currenttop = parseInt(window.getComputedStyle(odiv).top);
  odiv.style.left = currentleft + speedX + "px"; 
}
getComputedStyle() 需要一个具体的 DOM 元素作为参数,你传入的 odiv 通过 getElementsByTagName 获取的是一组 DOM 元素,不是单个元素,所以会报错。

指定获取第一个 DIV 元素传递给 getComputedStyle() 就可以了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-12-23 10:27

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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