1.30-web

迷惑的this

目标

完善 js/index.js 中的 handle 函数中的 TODO 部分,实现以下功能:

- 为输入框即 this.inputEl)绑定 input 事件,当输入框的值发生变化时,调用已经提供的 handleInput 方法进行搜索处理,注意 handleInput 方法调用时的 this 指向应为 search 对象本身。

const data = [
    { id: 1, content: "明日方舟" },
    { id: 2, content: "明朝" },
    { id: 3, content: "明天会更好" },
    { id: 4, content: "明星" },
    { id: 4, content: "m" },
    { id: 5, content: "mi" },
    { id: 6, content: "min" },
    { id: 7, content: "ming" },
  ];
  const search = {
    inputEl: null,
    listEl: null,
    data: [],
    init(options) {
      this.initData(options.el);
      this.handle();
    },
    initData(el) {
      //获取页面上的输入框
      this.inputEl = el.querySelector("input");
      //获取页面上的显示项的ul标签
      this.listEl = el.querySelector(".search-list");
    },
    //事件处理函数
    handle() {
      // TODO:待补充代码  
      this.inputEl.addEventListener('input', this.handleInput.bind(this));
      
    },
    // 搜索处理函数
    handleInput(e) {
      const value = e.target.value;
      // 使用定时器模拟 ajax 发送请求,data 接收数据
      setTimeout(() => {
        this.data = !!value
          ? data.filter((val) => val.content.indexOf(value) !== -1)
          : [];
        // 渲染搜索结果到页面上的列表
        this.render();
      });
    },
    render() {
      // 根据得到的数组转化为 li 标签,并插入到 .search-list 元素(ul标签)内
      const template = this.data.reduce(
        (prev, next) => prev + `<li>${next.content}</li>`,
        ""
      );
      this.listEl.innerHTML = template;
    },
  };
  
  
  search.init({
    el: document.getElementById("app"),
  });

1.this

handleInput函数会被调用,并且它的上下文(即this的值会被绑定到当前的search对象实例上。

this指向的是search对象,而不是输入框元素。这样做的目的是为了方便在事件处理函数中访问和操作对象的属性和方法,而无需每次都使用对象名来调用它们。

因为事件监听器默认情况下this 是触发事件的DOM元素(在这里是inputEl),而不是包含这个函数的对象。通过使用bind(this),我们确保了在handleInput函数内部,this指向的是search对象,而不是输入框元素。

2. .bind(this):

bind是一个JavaScript函数的方法,用于改变函数的上下文(即this的值)。在这里,它确保handleInput方法在执行时,其上下文是当前的类实例。这意味着thishandleInput方法中指的是当前的类实例search,而不是而不是输入框元素。

贪吃蛇

找到 index.js 文件中的 nextStep 函数,完成函数中的 TODO 部分:

  1. 根据当前蛇的移动方向(this.direction)以及蛇身块的大小(this.size),计算新的蛇头位置,更新蛇身坐标数组 (this.snakeBody),即可实现蛇的正确移动。蛇的移动和增加蛇的长度代码已提供。

蛇身坐标示例如下:

 [{ left: 2, top: 0 }, { left: 1, top: 0 }, { left: 0, top: 0 }]` 

蛇的身体是由多个坐标点组成的,每个坐标点包含了 left 和 top 属性,分别表示在游戏界面中的水平和垂直位置,第一个坐标表示当前蛇头的位置。

思路:

1. 首先通过snakeHead变量,拿到蛇头的位置

2. 接着定义了一个新的蛇头

3.利用switch、case,形参是蛇的移动方向this.direction,分别是上下左右

4.由题目中给出的蛇的坐标表达,我们将新的坐标赋值给蛇头

5. 然后利用unshift和pop的配合,模拟蛇的移动(前多一个后少一个)

// 移动蛇的头部
       nextStep() {
        // TODO:待补充代码
        //this指向Snake
        const snakeHead = this.snakeBody[0]; //拿到蛇头的位置
      
        let newHead;
        switch (this.direction) {
            case 'right':
                newHead = { left: snakeHead.left + this.size, top: snakeHead.top };
                break;
            case 'down':
                newHead = { left: snakeHead.left, top: snakeHead.top + this.size };
                break;
            case 'left':
                newHead = { left: snakeHead.left - this.size, top: snakeHead.top };
                break;
            case 'up':
                newHead = { left: snakeHead.left, top: snakeHead.top - this.size };
                break;
        }
        //更新蛇头的位置
        //使用 `unshift` 方法,我们将新的蛇头位置添加到 `this.snakeBody` 数组的开始位置。
        this.snakeBody.unshift(newHead);
        //* 使用 `pop` 方法,我们从 `this.snakeBody` 数组的末尾删除一个元素。这两个操作结合起来,实际上是在移动蛇的位置,而不是增加其长度。蛇的头部移动到新的位置,而尾部则被删除,从而模拟了蛇的移动效果。
        this.snakeBody.pop();
      }

6. 更新蛇的位置除了上面的方法,还可以利用for循环

for (let i = 1; i < this.snakeBody.length; i++) {
      this.snakeBody[i].top = tempList[i - 1].top;
      this.snakeBody[i].left = tempList[i - 1].left;
    }

这个循环从蛇身的第二个部分(索引为1)开始,并遍历到蛇身的最后一个部分。对于每个部分,它都会设置新的 top 和 left 属性值,这些值来自 tempList 中对应部分的位置。

简单来说,这个循环确保蛇身的每一部分都跟随其前一部分的位置移动。这样,当蛇头移动时,整个蛇都会跟随它移动

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值