分类: 笔记

  • 事件对象

    • 在事件绑定的回调函数的第一个参数就是事件对象
    • 一般命名为event、ev、e

    获取事件对象

    btn.addEventListener('click',funtcion(e){
      console.log(e)
    })
    

    常用属性

    type

    获取当前的事件类型

    clientX / clientY

    获取光标相对于浏览器可见窗口距离左上角的位置

    offsetX / offsetY

    获取光标相对于当前DOM元素距离左上角的位置

    pageX / pageY

    获取光标相对于文档距离左上角的位置

    key

    用户按下的键盘键的值

    target

    触发事件的对象(可用于事件委托)

    Event.target | MDN

    // Make a list
    var ul = document.createElement('ul');
    document.body.appendChild(ul);
    
    var li1 = document.createElement('li');
    var li2 = document.createElement('li');
    ul.appendChild(li1);
    ul.appendChild(li2);
    
    function hide(e){
      // e.target 引用着 <li> 元素
      // 不像 e.currentTarget 引用着其父级的 <ul> 元素.
      e.target.style.visibility = 'hidden';
    }
    
    // 添加监听事件到列表,当每个 <li> 被点击的时候都会触发。
    ul.addEventListener('click', hide, false);
    

    Event | MDN

  • DOM节点

    DOM树里每一个内容都称之为节点

    节点类型

    元素节点

    所有的标签

    比如bodydivhtml是根节点

    属性节点

    所有的属性 比如hrefsrc

    文本节点

    所有的文本

    其他

    查找节点

    父节点查找

    • parentNode 属性
    • 返回最近一级的父节点找不到返回为null
    子元素.parentNode //是属性 不需要加括号
    

    子节点查找

    children (重点)

    • 仅获得所有元素节点
    • 返回的还是一个伪数组
    父元素.children
    

    childNodes

    获得所有子节点、包括文本节点(空格、换行)、注释节点等

    兄弟关系查找

    下一个兄弟节点

    nextElementSibling属性

    上一个兄弟节点

    previousElementSibling属性

    增加节点

    创建节点

    创造出一个新的网页元素,再添加到网页内,一般先创建节点,然后插入节点

    document.createElement('标签名')  //必须是字符串
    

    追加节点

    插入到父元素的最后一个子元素

    父元素.appendChild(要插入的元素)
    

    插入到父元素中某个子元素的前面

    父元素.insertBefore(要插入的元素,在哪个元素前面)
    

    克隆节点

    cloneNode会克隆出一个跟原标签一样的元素,括号内传入布尔值

    元素.cloneNode(true or false)
    • 默认为false
    • 若为false,则代表克隆时不包含后代节点
    • 若为true,则代表克隆时会包含后代节点一起克隆

    注意:为了防止一个文档中出现两个ID重复的元素,使用cloneNode()方法克隆的节点在需要时应该指定另外一个与原ID值不同的ID

    删除节点

    JavaScript原生DOM操作中,要删除元素必须通过父元素删除

    Node.removeChild() 方法从DOM中删除一个子节点。返回删除的节点。

    let oldChild = node.removeChild(child)
    
    //OR
    
    element.removeChild(child)
    
    • child 是要移除的那个子节点
    • node 是child的父节点
    • oldChild保存对删除的子节点的引用. oldChild === child

    被移除的这个子节点仍然存在于内存中,只是没有添加到当前文档的DOM树中,因此,你还可以把这个节点重新添加回文档中,当然,实现要用另外一个变量比如上例中的oldChild来保存这个节点的引用. 如果使用上述语法中的第二种方法, 即没有使用 oldChild 来保存对这个节点的引用, 则认为被移除的节点已经是无用的, 在短时间内将会被内存管理回收.

    Node.removeChild | MDN

    如果上例中的child节点不是node节点的子节点,则该方法会抛出异常

  • 时间对象

    实例化

    在代码中出现了new关键字时,一般将这个操作称为实例化

    创建一个时间对象并获取时间

    //获得当前时间
    let date = new Date()
    
    //获得指定时间
    let date = new Date('1999-3-14')
    

    因为时间对象返回的数据我们不能直接使用,所以需要转换为实际开发中常用的格式

    方法作用说明
    getFullYear()获得年份获取四位年份
    getMonth()获得月份取值为 0 ~ 11
    getDate()获取月份中的每一天不同月份取值也不相同
    getDay()获取星期取值为 0 ~ 6
    getHours()获取小时取值为 0 ~ 23
    getMinutes()获取分钟取值为 0 ~ 59
    getSeconds()获取秒取值为 0 ~ 59
    ·········

    时间戳

    指1970年01月01日00时00分00秒起至现在的毫秒数,它是一种特殊的计量时间的方式。

    //得到指定的时间戳 括号里是字符串!
    //1.
    +new Date('2022-3-1 18:00:00')
    
    //2.
    let date = new Date('2022-3-1 18:00:00')
    console.log(date.getTime())
    

    三种获取方式

    //1.简写(推荐)
    //直接获取
    +new Date()
    
    //2.
    //实例化
    let date = new Date()
    //获取时间戳
    date.getTime()
    
    //3.
    //无需实例化
    //只能获取当前的时间戳,前两种可以获取指定时间的时间戳
    Date.now()
    

    Date – JavaScript | MDN

  • 重排和重绘

    浏览器是如何进行界面渲染的

    回流 / 重排(reflow)

    当 Render Tree 中部分或者全部元素的尺寸结构布局等发生改变时,浏览器就会重新渲染部分全部文档的过程称为回流。

    会导致回流(重排)的操作:

    • 页面的首次刷新
    • 浏览器的窗口大小发生改变
    • 元素的大小或位置发生改变
    • 改变字体的大小
    • 内容的变化(如:input框的输入,图片的大小)
    • 激活css伪类 (如::hover)
    • 脚本操作DOM(添加或者删除可见的DOM元素)

    简单理解影响到布局了,就会有回流

    重绘(Repaints)

    由于节点(元素)的样式的改变并不影响它在文档流中的位置和文档布局时(比如:colorbackground-coloroutline等), 称为重绘。

    重绘不一定引起回流,而回流一定会引起重绘。

    let s = document.body.style
    s.padding = '2px'              // 重排 + 重绘
    s.border = '1px solid red'    // 再次重排 + 重绘
    s.color = 'blue'             // 再次重绘
    s.backgroundColor = '#ccc'  // 再次重绘
    s.fontSize = '14px'        // 再次重排 + 重绘
  • 排他思想

    let btns = document.querySelectorAll('button')
    for (let i = 0; i < btns.length; i++) {
      
     //方法1
    btns[i].addEventListener('click', function () {
            // 干掉所有人 把所有按钮中的这个类都删除
            for (let j = 0; j < btns.length; j++) {
                btns[j].classList.remove('pink')
            }
            // 复活我自己 只给自己添加
            this.classList.add('pink')
        })
      
    //方法2
    btns[i].addEventListener('click', function () {
    		// 我只需要找出那个唯一的 pink类,删除
    		document.querySelector('.pink').classList.remove('pink')
    		// 我的
    		this.classList.add('pink')
        })
      
    }
  • 随机点名案例

    功能:

    • 点击开始按钮开始随机点名
    • 点击结束按钮抽取一个名字,并把抽到的名字删除
    • 直到抽到最后一个人,弹出重新开始按钮和“抽完了”提示文字

    HTML部分

    <div class="box">
    <h3>随机点名</h3>
    <p>幸运儿:<span class="luckyman"></span></p>
    <p class="alert">抽完啦</p>
    <div class="btn">
    <button class="start">开始</button>
    <button class="end" disabled>结束</button>
    <button class="reopen">重新开始</button>
    </div>
    </div>

    CSS部分

    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }
    body {
      color: #333;
    }
    .box {
      user-select: none;
      display: flex;
      flex-direction: column;
      align-items: center;
      justify-content: space-around;
      margin: 3vw auto 0;
      height: 40vw;
      border-top: 0.6667vw solid #333;
      border-bottom: 0.6667vw solid #333;
    }
    .box h3 {
      font-size: 4vw;
    }
    .box p {
      font-size: 2.9333vw;
    }
    .box p span {
      display: inline-block;
      min-width: 6.6667vw;
      max-width: 20vw;
      border-bottom: 0.4vw solid #333;
      overflow: hidden;
      white-space: nowrap;
      text-overflow: ellipsis;
    }
    .btn button {
      width: 13.3333vw ;
      height: 5.3333vw;
      font-size: 2.4vw;
      border: 0.2667vw solid #333;
      margin: 0 1.3333vw;
      background: none;
      cursor: pointer;
    }
    button:disabled {
      color: #999;
      border: 0.2667vw solid #999;
      cursor: default;
    }
    .reopen {
      display: none;
    }
    .alert {
      display: none;
    }

    JS部分

    // 获取M-N之间的随机数
    let random = function (m, n) {
      let rNum = 0
      rNum = Math.floor(Math.random() * (m - n + 1) + n) //m - n + 1 向下取整,所以
      return rNum
    }
    // 随机名字函数
    let i = 0
    let nameArr = ["rose", "cool", "tony", "Liao", "Q"]
    let text = document.querySelector(".luckyman")
    let rName = function () {
      i = random(nameArr.length - 1, 0)
      let name = nameArr[i]
      text.innerHTML = name
    }
    //按钮事件绑定
    let start = document.querySelector(".start")
    let end = document.querySelector(".end")
    let reopen = document.querySelector(".reopen")
    let alert1 = document.querySelector(".alert")
    start.addEventListener("click", function () {
      //开启定时器
      t = setInterval(rName, 50)
      start.disabled = true
      end.disabled = false
      if (nameArr.length === 1) {
        start.disabled = true
        end.disabled = true
        alert1.style.display = "block"
        reopen.style.display = "inline-block"
        clearInterval(t)
      }
    })
    end.addEventListener("click", function () {
      //结束定时器
      clearInterval(t)
      start.disabled = false
      end.disabled = true
      //在数组删除被选中的名字
      nameArr.splice(i, 1)
    })
    //重新开始
    reopen.addEventListener("click", function () {
      nameArr = ["rose", "cool", "tony", "Liao", "Q"]
      start.disabled = false
      alert1.style.display = "none"
      text.innerHTML = ""
      reopen.style.display = ""
      
    })
  • 变量命名规则与规范

    1. 规则:

    • 不能用关键字
    • 关键字:有特殊含义的字符,JavaScript 内置的一些英语词汇。例如:letvariffor
    • 只能用下划线、字母、数字、$组成,且数字不能开头
    • 字母严格区分大小写,如 Age 和 age 是不同的变量

    2. 规范:

    • 起名要有意义
    • 遵守小驼峰命名法
    • 第一个单词首字母小写,后面每个单词首字母大写。例:userName
  • js术语、数据类型

    术语

    术语解释举例
    关键字在JavaScript中有特殊意义的词汇let、var、function、if、else、 switch、case、break
    保留字在目前的JavaScript中没意义,但未来可能会具有特殊意义的词汇int、short、long、char
    标识(标识符)变量名、函数名的另一种叫法
    表达式能产生值的代码,一般配合运算符出现10 + 3、age >= 18
    语句一句代码也称之为一条语句,一般按 用途还会分类:输出语句、声明语句、 分支语句

    基本数据类型和引用数据类型的存储方式

    简单类型又叫做基本数据类型或者值类型复杂类型又叫做引用类型

    值类型:

    简单数据类型/基本数据类型,在存储时变量中存储的是值本身,因此叫做值类型 string number boolean undefined null

    引用类型:

    复杂数据类型,在存储时变量中存储的仅仅是地址(引用),因此叫做引用数据类型。通过 new 关键字创建的对象(系统对象、自定义对象),如 Object、Array、Date等

    堆栈空间分配区别:

    1.栈(操作系统):由操作系统自动分配释放存放函数的参数值、局部变量的值等。其操作方式类似于数据结构中的栈;

    简单数据类型存放到里面

    简单数据类型存储方式

    简单数据类型直接存值

    引用数据类型存的是地址

    2.堆(操作系统):存储复杂类型(对象),一般由程序员分配释放,若程序员不释放,由垃圾回收机制回收。

    引用数据类型里存的是地址

    引用数据类型存放到里面

    引用数据类型存储方式
    // 简单数据类型存储的是值
    let num1 = 10
    let num2 = num1
    num2 = 20
    console.log(num1)


    // 对象 引用数据类型 栈里面存储的是地址
    let obj1 = {
       age: 18
    }
    let obj2 = obj1  //将obj1在堆中的地址给obj2
    obj2.age = 20
    //obj1和obj2地址相同,在堆里找的是同一个东西
    console.log(obj1)   // 20
  • 高阶函数

    高阶函数可以被简单理解为函数的高级应用,JavaScript函数可以被当来对待,基于这个特性实现函数的高级应用。

    是 JavaScript 中的数据,如数值字符串布尔对象等。

    函数表达式

    • 函数也是数据
    • 把函数赋值给变量
    let abc = function(){}
    
    • 普通函数的声明与调用无顺序限制,推荐做法先声明再调用
    • 函数表达式必须要先声明再调用

    回调函数

    如果将函数 A 做为参数传递给函数 B 时,我们称函数 A 为回调函数 简单理解: 当一个函数当做参数来传递给另外一个函数的时候,这个函数就是回调函数

    常见的使用场景

    //1.间歇函数
    function fn(){
    		console.log('我是谁')
    }
    //fn传递给了setIterval,fn就是回掉函数
    setInterval(fn,1000)
    
    //2.事件监听
    //这里匿名函数为回掉函数
    box.addEventListener('click',function(){
      console.log('123')
    })
    
    • 把函数当做另外一个函数的参数传递,这个函数就叫回调函数
    • 回调函数本质还是函数,只不过把它当成参数使用
    • 使用匿名函数做为回调函数比较常见
  • 对象

    • 一种数据类型
    • 可以理解为一堆数据的集合
    • 用来表示某个事物

    属性方法组成

    语法

    属性

    let 对象名 = {
      属性名:值,
      属性名:值,
      属性名:值
    }
    
    //例
    let person = {
      uname:'andy',
      age:18,
      sex:'男'
    }
    

    对象的属性没有顺序,属性和值之间用冒号: 属性之间用,

    方法

    本质是函数

    let person = {
      name: "andy",
      sayHi: function () {
        document.write("hi~~")
      },    //注意加逗号
    }
    
    • 方法是由方法名函数两部分构成,它们之间使用 : 分隔
    • 多个属性之间使用英文,分隔
    • 方法是依附在对象中的函数
    • 方法名可以使用 “” 或 ”,一般情况下省略,除非名称遇到特殊符号如空格、中横线等

    对象使用

    属性访问

    //两种方式(根据场景使用)
    let person = {
    		name:'andy',
    		age:18,
    		sex:'男'
    }
    
    // 对象名.属性名
    console.log(person.name)
    console.log(person.age)
    
    // 对象名['属性名']
    console.log(person['name'])
    console.log(person['age'])
    

    方法访问

    let person = {
      name: "andy",
      sayHi: function () {
        document.write("hi~~")
      },    //注意加逗号
    }
    
    //调用 注意需要加小括号
    person.sayHi()
    

    操作对象

    增加/修改

    如果对象没有该属性,则增加该属性,如果有,则修改属性值

    动态添加与直接定义是一样的,只是语法上更灵活

    let obj = {
      name: 'andy'
    }
    
    //增加属性
    //对象名.新增属性名 = 属性值
     obj.hobby = '拍照'
     obj['sex'] = '男'
    
    //新增对象中的方法
    //对象名.新增方法名 = 方法
    obj.move = function(){
    		document.write('12')
    }
    

    注:无论是属性或是方法,同一个对象中出现名称一样的,后面的会覆盖前面的

    删除对象中的属性(了解)

    //delete 对象名.属性名
      delete obj.age
    

    遍历对象

    • 对象没有像数组一样的length属性,所以无法确定长度
    • 对象里面是无序的键值对, 没有规律. 不像数组里面有规律的下标
    //for(let k 对象名){}
    for(let k in obj){
      console.log(k)   //属性名
    }
    
    //得到属性值 k是变量不要加引号!
    console.log(obj[k])
    // k存的是字符串 === '属性名'
    //——————————————————
    
    //console.log(obj.k) 错误!! 找的是obj里面的k属性
    

    内置对象

    例如:

    document.write()
    console.log()	
    

    Math

    方法Math.*() 
    random生成0-1之间的随机数(包含0不包括1)
    ceil向上取整
    floor向下取整
    round就近取整
    max找最大数
    min找最小数
    pow幂运算
    abs绝对值
    console.log(Math.PI)  //  圆周率    π  
    console.log(Math.random())  //  随机数  随机抽奖  随机点名
    // 返回的是小数  但是能得到 0  得不到 1
    // 向上取整  返回的整数
    console.log(Math.ceil(1.1))  // ceil  2
    console.log(Math.ceil(1.5))  // ceil  2
    console.log(Math.ceil(1.9))  // ceil  2
    // 向下取整  返回的整数  floor  
    console.log(Math.floor(1.1))  // floor  1
    console.log(Math.floor(1.5))  // floor  1
    console.log(Math.floor(1.9))  // floor  1
    console.log('-------------------------------')
    // round 就近取整( .5往大取整)  返回的整数   
    console.log(Math.round(1.1))  // round  1
    console.log(Math.round(1.5))  // round  2
    console.log(Math.round(1.9))  // round  2
    console.log('-------------------------------')
    console.log(Math.round(-1.1))  // round  -1
    console.log(Math.round(-1.5))  // round  -1
    console.log(Math.round(-1.9))  // round  -2
    // 最大值和最小值
    console.log(Math.max(1, 5, 9, 45))
    console.log(Math.min(1, 5, 9, 45))
    

    生成任意范围的随机数

    //生成N-M之间的随机数
    Math.floor(Math.random() * (M - N + 1)) + N