想为拷贝的对象绑定事件,但事件跑到了被拷贝的对象上

问题描述:生成了一个人物对象person,拥有left,right等方法,并拷贝了一个person对象命名为person_new。然后分别为两个对象绑定事件,但是为拷贝对象的绑定的事件总是跑到了被拷贝的对象上,(如下图,点击person_new绑定的事件却是person在动)不知道到底是哪里的问题;以及我知道我在代码书写规则方面做得不怎么好,请为我指正,谢谢
问题图片:图片描述
关键代码:

     * 人物对象模板
     */
    let person = (function Person(){
        let obj = {};
        obj =  {
            deg: 0,
            direction: 0,
            head : {},
            step: {
                x: 0,
                y: 0,
            },
            trun: (deg) =>{
                obj.head.style.transform = "rotate(" + deg + "deg)";
            },
            right: () => {
                obj.deg += 90;
                obj.trun(obj.deg)
            },
            left: () => {
                obj.deg -= 90;
                obj.trun(obj.deg)
            },
            trunBack: () => {
                obj.deg += 180;
                obj.trun(obj.deg)
            },
            go: ()=>{
                let direction = obj.deg%360;
                let isCross = obj.step.x >=0 && obj.step.x <= croTotal-distance;
                let isVertical = obj.step.y <=0 && obj.step.y >= -verTotal+distance;
                if(isVertical){
                    switch (direction) {
                        case 0:
                            obj.step.y >= -verTotal+distance*2 ? obj.step.y -= 50 :obj.step.y;
                            break;
                        case -0:
                            obj.step.y >= -verTotal+distance*2 ? obj.step.y -= 50 :obj.step.y;
                            break;
                        case 180:
                            obj.step.y < 0 ? obj.step.y += 50 : obj.step.y;
                            break;
                        case -180:
                            obj.step.y < 0 ? obj.step.y += 50 : obj.step.y;
                            break;
                    }
                }
                if(isCross){
                    switch (direction) {
                        case 270:
                            obj.step.x < croTotal-distance ? obj.step.x += 50 : obj.step.x;
                            break;
                        case -90:
                            obj.step.x < croTotal-distance ? obj.step.x += 50 : obj.step.x;
                            break;
                        case -270:
                            obj.step.x > 0 ? obj.step.x -= 50 : obj.step.x;
                            break;
                        case 90:
                            obj.step.x > 0 ? obj.step.x -= 50 : obj.step.x;
                            break;
                    }
                }
                obj.head.style.left = obj.step.x + 'px';
                obj.head.style.top = -obj.step.y + 'px';
                console.log(obj.step,'step')
            }
        }
       return obj;
    })()
    /**
     * 绑定人物对象
     */
    function setPosition(className,obj,leftID,rightID,backID,goID){
        obj.head = document.getElementsByClassName(className)[0];
        var colorStr=null;
        obj.head.currentStyle ? colorStr=obj.head.currentStyle : colorStr=window.getComputedStyle(obj.head,null);
        obj.step.x=Number(colorStr.left.replace('px','')) || 0;
        obj.step.y=Number(colorStr.top.replace('px','')) || 0;
        document.getElementById(leftID).addEventListener('click',obj.left);
        document.getElementById(rightID).addEventListener('click',obj.right);
        document.getElementById(backID).addEventListener('click',obj.trunBack);
        document.getElementById(goID).addEventListener('click',obj.go);
    }
    /**
     * 拷贝人物对象
     */
    var personCopy = function (source) {
        var result = {};
        for(var key in source) {
            if(typeof source[key] === 'object') {
                result[key] = personCopy(source[key])
            } else {
                result[key] = source[key]
            }
        }
        return result;
    }
    /**
     * 初始化人物对象
     */
    var person_new = personCopy(person);
    setPosition('robot-box',person,'turn_left','turn_right','turn_back','comand_button');
    setPosition('robot-box1',person_new,'turn_left1','turn_right1','turn_back1','comand_button1');
    

所有代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>task33</title>
    <style type="text/css">
        * {
            padding: 0;
            margin: 0;
        }
        .clear_border {
            border: none;
        }
        table {
            border-spacing: 0;
            border-collapse: collapse;
        }
        td {
            font-family: Microsoft Yahei;
            text-align: center;
            font-weight: bold;
            border: 1px solid #eee;
            width: 50px;
            height: 50px;
            box-sizing: border-box;
        }
        .blank {
            border: none;
        }
        .robot-box {
            transition: all .8s;
            height: 50px;
            width: 50px;
            position: absolute;
            top: 0px;
            left: 0px;
            transform: rotate(0deg);
            background: url('https://github.com/pkjy/ife-task/blob/gh-pages/2016_spring/part2/task33/box.jpg?raw=true') no-repeat 100% 100%;
        }
        .robot-box1 {
            transition: all .8s;
            height: 50px;
            width: 50px;
            position: absolute;
            top: 50px;
            left: 50px;
            transform: rotate(0deg);
            background: url('https://github.com/pkjy/ife-task/blob/gh-pages/2016_spring/part2/task33/box.jpg?raw=true') no-repeat 40% 40%;
        }
        #table{
            position: relative;
        }
    </style>
</head>

<body>
<div class="wrap">
    <table id="table"></table>
    <div class="robot-box" id="robot_box"></div>
    <div class="robot-box1" id="robot_box1"></div>
    <div class="btn">
        <p>person的控制按钮</p>
        <input type="button" id="comand_button" value="GO">
        <input type="button" id="turn_left" value="TUN LEF">
        <input type="button" id="turn_right" value="TUN RIG">
        <input type="button" id="turn_back" value="TUN BAC">
    </div>
    <div class="btn">
        <p>person_new的控制按钮</p>
        <input type="button" id="comand_button1" value="GO">
        <input type="button" id="turn_left1" value="TUN LEF">
        <input type="button" id="turn_right1" value="TUN RIG">
        <input type="button" id="turn_back1" value="TUN BAC">
    </div>
</div>

<script>
  let distance = 50;//每个格子的距离
  let tableNum = 10;//游戏格子数
  let cross = 0;//横向位置
  let vertical = 0;//竖向位置
  let croTotal = tableNum*distance;//横向距离
  let verTotal = tableNum*distance;//竖向距离
    /**
     * 生成table
     */
    (function table() {
        let trArr = [];
        for(let i = 0; i<tableNum; i++){
            trArr[i] = document.createElement('tr');
            document.getElementById('table').appendChild(trArr[i]);
            let tdArr = [];
            for(let m = 0; m <tableNum; m++){
                tdArr[m] = document.createElement('td');
                trArr[i].appendChild(tdArr[m]);
            }
        }
    })()
    /**
     * 人物对象模板
     */
    let person = (function Person(){
        let obj = {};
        obj =  {
            deg: 0,
            direction: 0,
            head : {},
            step: {
                x: 0,
                y: 0,
            },
            trun: (deg) =>{
                obj.head.style.transform = "rotate(" + deg + "deg)";
            },
            right: () => {
                obj.deg += 90;
                obj.trun(obj.deg)
            },
            left: () => {
                obj.deg -= 90;
                obj.trun(obj.deg)
            },
            trunBack: () => {
                obj.deg += 180;
                obj.trun(obj.deg)
            },
            go: ()=>{
                let direction = obj.deg%360;
                let isCross = obj.step.x >=0 && obj.step.x <= croTotal-distance;
                let isVertical = obj.step.y <=0 && obj.step.y >= -verTotal+distance;
                if(isVertical){
                    switch (direction) {
                        case 0:
                            obj.step.y >= -verTotal+distance*2 ? obj.step.y -= 50 :obj.step.y;
                            break;
                        case -0:
                            obj.step.y >= -verTotal+distance*2 ? obj.step.y -= 50 :obj.step.y;
                            break;
                        case 180:
                            obj.step.y < 0 ? obj.step.y += 50 : obj.step.y;
                            break;
                        case -180:
                            obj.step.y < 0 ? obj.step.y += 50 : obj.step.y;
                            break;
                    }
                }
                if(isCross){
                    switch (direction) {
                        case 270:
                            obj.step.x < croTotal-distance ? obj.step.x += 50 : obj.step.x;
                            break;
                        case -90:
                            obj.step.x < croTotal-distance ? obj.step.x += 50 : obj.step.x;
                            break;
                        case -270:
                            obj.step.x > 0 ? obj.step.x -= 50 : obj.step.x;
                            break;
                        case 90:
                            obj.step.x > 0 ? obj.step.x -= 50 : obj.step.x;
                            break;
                    }
                }
                obj.head.style.left = obj.step.x + 'px';
                obj.head.style.top = -obj.step.y + 'px';
                console.log(obj.step,'step')
            }
        }
       return obj;
    })()
    /**
     * 绑定人物对象
     */
    function setPosition(className,obj,leftID,rightID,backID,goID){
        obj.head = document.getElementsByClassName(className)[0];
        var colorStr=null;
        obj.head.currentStyle ? colorStr=obj.head.currentStyle : colorStr=window.getComputedStyle(obj.head,null);
        obj.step.x=Number(colorStr.left.replace('px','')) || 0;
        obj.step.y=Number(colorStr.top.replace('px','')) || 0;
        document.getElementById(leftID).addEventListener('click',obj.left);
        document.getElementById(rightID).addEventListener('click',obj.right);
        document.getElementById(backID).addEventListener('click',obj.trunBack);
        document.getElementById(goID).addEventListener('click',obj.go);
    }
    /**
     * 拷贝人物对象
     */
    var personCopy = function (source) {
        var result = {};
        for(var key in source) {
            if(typeof source[key] === 'object') {
                result[key] = personCopy(source[key])
            } else {
                result[key] = source[key]
            }
        }
        return result;
    }
    /**
     * 初始化人物对象
     */
    var person_new = personCopy(person);
    setPosition('robot-box',person,'turn_left','turn_right','turn_back','comand_button');
    setPosition('robot-box1',person_new,'turn_left1','turn_right1','turn_back1','comand_button1');
</script>
</body>
</html>
阅读 1.5k
2 个回答
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>task33</title>
  <style type="text/css">
    * {
      padding: 0;
      margin: 0;
    }

    .clear_border {
      border: none;
    }

    table {
      border-spacing: 0;
      border-collapse: collapse;
    }

    td {
      font-family: Microsoft Yahei;
      text-align: center;
      font-weight: bold;
      border: 1px solid #eee;
      width: 50px;
      height: 50px;
      box-sizing: border-box;
    }

    .blank {
      border: none;
    }

    .robot-box {
      transition: all .8s;
      height: 50px;
      width: 50px;
      position: absolute;
      top: 0px;
      left: 0px;
      transform: rotate(0deg);
      background: url('https://github.com/pkjy/ife-task/blob/gh-pages/2016_spring/part2/task33/box.jpg?raw=true') no-repeat 100% 100%;
    }

    .robot-box1 {
      transition: all .8s;
      height: 50px;
      width: 50px;
      position: absolute;
      top: 50px;
      left: 50px;
      transform: rotate(0deg);
      background: url('https://github.com/pkjy/ife-task/blob/gh-pages/2016_spring/part2/task33/box.jpg?raw=true') no-repeat 40% 40%;
    }

    #table {
      position: relative;
    }
  </style>
</head>

<body>
  <div class="wrap">
    <table id="table"></table>
    <div class="robot-box" id="robot_box"></div>
    <div class="robot-box1" id="robot_box1"></div>
    <div class="btn">
      <p>person的控制按钮</p>
      <input type="button" id="comand_button" value="GO">
      <input type="button" id="turn_left" value="TUN LEF">
      <input type="button" id="turn_right" value="TUN RIG">
      <input type="button" id="turn_back" value="TUN BAC">
    </div>
    <div class="btn">
      <p>person_new的控制按钮</p>
      <input type="button" id="comand_button1" value="GO">
      <input type="button" id="turn_left1" value="TUN LEF">
      <input type="button" id="turn_right1" value="TUN RIG">
      <input type="button" id="turn_back1" value="TUN BAC">
    </div>
  </div>

  <script>
    let distance = 50;//每个格子的距离
    let tableNum = 10;//游戏格子数
    let cross = 0;//横向位置
    let vertical = 0;//竖向位置
    let croTotal = tableNum * distance;//横向距离
    let verTotal = tableNum * distance;//竖向距离
    /**
     * 生成table
     */
    (function table() {
      let trArr = [];
      for (let i = 0; i < tableNum; i++) {
        trArr[i] = document.createElement('tr');
        document.getElementById('table').appendChild(trArr[i]);
        let tdArr = [];
        for (let m = 0; m < tableNum; m++) {
          tdArr[m] = document.createElement('td');
          trArr[i].appendChild(tdArr[m]);
        }
      }
    })()
    /**
     * 人物对象模板
     */
    function Person() {
      this.deg = 0;
      this.direction = 0;
      this.head = {};
      this.step = {
        x: 0,
        y: 0,
      };

    };
    Person.prototype = {
      constructor: Person,
      trun: function(deg) {
        this.head.style.transform = "rotate(" + deg + "deg)";
      },
      right: function () {
        this.deg += 90;
        this.trun(this.deg)
      },
      left: function () {
        this.deg -= 90;
        this.trun(this.deg)
      },
      trunBack: function () {
        this.deg += 180;
        this.trun(this.deg)
      },
      go: function () {
        let direction = this.deg % 360;
        let isCross = this.step.x >= 0 && this.step.x <= croTotal - distance;
        let isVertical = this.step.y <= 0 && this.step.y >= -verTotal + distance;
        if (isVertical) {
          switch (direction) {
            case 0:
              this.step.y >= -verTotal + distance * 2 ? this.step.y -= 50 : this.step.y;
              break;
            case -0:
              this.step.y >= -verTotal + distance * 2 ? this.step.y -= 50 : this.step.y;
              break;
            case 180:
              this.step.y < 0 ? this.step.y += 50 : this.step.y;
              break;
            case -180:
              this.step.y < 0 ? this.step.y += 50 : this.step.y;
              break;
          }
        }
        if (isCross) {
          switch (direction) {
            case 270:
              this.step.x < croTotal - distance ? this.step.x += 50 : this.step.x;
              break;
            case -90:
              this.step.x < croTotal - distance ? this.step.x += 50 : this.step.x;
              break;
            case -270:
              this.step.x > 0 ? this.step.x -= 50 : this.step.x;
              break;
            case 90:
              this.step.x > 0 ? this.step.x -= 50 : this.step.x;
              break;
          }
        }
        this.head.style.left = this.step.x + 'px';
        this.head.style.top = -this.step.y + 'px';
        console.log(this.step, 'step')
      }
    };
    /**
     * 绑定人物对象
     */
    function setPosition(className, obj, leftID, rightID, backID, goID){
      obj.head = document.getElementsByClassName(className)[0];
      var colorStr = null;
      obj.head.currentStyle ? colorStr = obj.head.currentStyle : colorStr = window.getComputedStyle(obj.head, null);
      obj.step.x = Number(colorStr.left.replace('px', '')) || 0;
      obj.step.y = Number(colorStr.top.replace('px', '')) || 0;
      document.getElementById(leftID).addEventListener('click', function(){
        obj.left();
      });
      document.getElementById(rightID).addEventListener('click', function(){
        obj.right();
      });
      document.getElementById(backID).addEventListener('click', function(){
        obj.trunBack()
      });
      document.getElementById(goID).addEventListener('click', function(){
        obj.go();
      });
    }
    /**
     * 拷贝人物对象
     */
    var personCopy = function (source) {
      var result = {};
      for (var key in source) {
        if (typeof source[key] === 'object') {
          result[key] = personCopy(source[key])
        } else {
          result[key] = source[key]
        }
      }
      return result;
    }
    /**
     * 初始化人物对象
     */
    let person = new Person();

    let person_new = new Person();
    setPosition('robot-box', person, 'turn_left', 'turn_right', 'turn_back', 'comand_button');
    setPosition('robot-box1', person_new, 'turn_left1', 'turn_right1', 'turn_back1', 'comand_button1');
  </script>
</body>

</html>

1、通过构造函数+原型模式创建对象,不用拷贝
2、将obj换成this
3、事件绑定外层加一个function(){},否则this会指向addEventListener的元素
4、go方法里面应该逻辑错误,person_new会有问题,没做修改

复制的时候 函数直接复制过来了 函数里的obj指的一直是第一个

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题