Java Script第三周

82 阅读9分钟

BOM常用对象

定时器,客户端储存技术,event

location对象:保存了当前窗口的正在打开的url

由5部分组成:协议、主机号|域名|IP地址、端口号、文件的相对路径|路由、查询字符串|请求信息

属性:
  1. 协议:location.protocol
  2. 域名:location.hostname
  3. 端口号:location.port;
  4. 路由:ocation.pathname;
  5. 请求消息:location.search;
方法
  1. 跳转:location="新url";
  2. 跳转后,禁止后退:location.replace("新url");
  3. 刷新:location.reload();

DOM

  1. 核心DOM:既可以操作HTML又可以操作XML,但是语法相对比较复杂
  2. HTML DOM:只能操作HTML,不能访问一些自定义的东西,但是语法比较简单
  3. XML DOM:只能操作XML,被淘汰了,被JSON数据格式代替了
1、查找元素:
  1. 通过关系网查找元素
  2. 通过HTML的特性去查找元素
    1. var elems=document.getElementsByXXXXX();//返回的是一个动态集合HTMLCollection
    2. var elem=document.querySelector("任意css选择器");找到的是单个元素
    3. *var elems=document.querySelectorAll("任意css选择器");找到的是一个集合
2、操作样式:
  1. 内联样式:
    1. 获取:elem.style.css属性名; - 只能获取内联样式
    2. 设置:elem.style.css属性名="css属性值";
3、操作属性:
  1. 获取属性值:
    核心DOM:elem.getAttribute("属性名");
    HTML DOM:elem.属性名;

  2. 设置属性值
    核心DOM:elem.setAttribute("属性名","属性值");
    HTML DOM:elem.属性名="属性值";

  3. 删除属性
    核心DOM:elem.removeAttribute("属性名");
    HTML DOM:elem.属性名="";

  4. 判断有没有属性
    核心DOM:elem.hasAttribute("属性名");
    HTML DOM:elem.属性名!="";

4、操作内容

innerHTML/innerText/value

5、如何创建元素以及上树:3步
  1. 创建空标签:var elem=document.createElement("标签名");
  2. 为其设置必要的属性和事件
    1. elem.属性名="属性值";
    2. elem.on事件名=function(){}
  3. 上树:三种
    1. 父元素.appendChild(elem);//在父元素末尾追加一个子元素elem
    2. 父元素.insertBefore(elem,已有子元素);//在父元素里面追加一个子元素elem,但是会放到已有子元素的前面
    3. 父元素.replaceChild(elem,已有子元素);//在父元素里面追加一个子元素elem,但是会替换掉已有子元素
6、删除元素:

elem.remove();

扩展:
  1. input/textarea的两个专属事件:onfocus(获取焦点)和 onblur(失去焦点)
  2. let 变量名=值;
    1. 解决了声明提前,一定先创建,后使用
    2. 带来了块级作用域,一个{}就是一个块
    3. 如果你用let当作下标去绑定事件,那么他会记录着你当前元素的下标,不需要再自定义下标了
  3. 类数组对象变为普通数组: let 变量名=Array.from(类数组);

递归

就是在函数中再一次调用了函数自己,专门用于【遍历层级不明确】的情况 使用方法:
function 函数名(root){
1 、rootroot第一层要做什么直接做
2、 判断有没有下一层,如果有下一层再次调用此方法,但是传入的实参是自己的下一层
}
函数名(实际的根元素)

  1. 算法:深度优先算法!优先遍历当前节点的子节点,子节点遍历完毕才会跳到兄弟节点
  2. 缺陷:不要过多使用,性能相对较差,同时开启大量的函数调用,浪费内存,我们只在一个情况使用它:【遍历层级不明确】
递归与死循环
  1. 递归:优点:简单易用,缺点是性能较低
  2. 纯循环:优点:性能高,缺点是比较复杂
绑定事件:3种方式
  1. 在HTML页面上书写事件属性:<elem on事件名="函数名()">
  2. 在JS中使用是件处理函数属性:elem.on事件名=function(){操作}
  3. 在JS中使用事件API:
    1. 主流:elem.addEventListener("事件名",callback)
    2. 老IE:elem.attachEvent("on事件名",callback)
扩展:

select&option 只有这俩可以简化创建和上树
select.add(new Option("innerHTML","value"));

获取事件对象event

事件周期:从事件发生,到所有是件处理函数执行完毕的全过程

  1. 捕获阶段:由外向内,记录着要发生的事件有哪些
  2. 目标优先触发:目标元素->当前点击的实际发生事件的元素
  3. 冒泡触发:由内向外,依次执行我们之前记录着的要发生的事件

主流:会自动作为事件处理函数的第一个形参传入e
老IE:event;
兼容:event;

获取事件对象event的作用:

  1. 获取鼠标的坐标/位置:3种

    1. 获取鼠标相对于屏幕的坐标:e.screenX/Y;
    2. 获取鼠标相对于浏览器窗口/客户端/文档显示区域的坐标:e.clientX/Y
    3. 获取鼠标相对于网页的坐标:e.pageX/Y;
  2. 阻止冒泡:

    1. 主流:e.stopPropagation();
    2. 老IE:e.cancelBubble=true;
    3. 兼容:e.cancelBubble=true;
  3. 事件委托/利用冒泡: 优化:如果多个子元素定义了 相同 或 相似的事件操作,那么最好只给【父元素】绑定一次

使用【目标元素】,可以减少绑定事件函数的次数,优化了网页的性能
主流:e.target;
老IE:e.srcElement;
兼容:e.srcElement;

  1. 阻止浏览器的默认行为

    1. 主流:e.preventDefault();
    2. 老IE:e.returnValue=false;
    3. 兼容:e.returnValue=false;
  2. 新的事件:

    1. 右键事件:window.oncontextmenu;
    2. 键盘事件 一般用于游戏开发比较多 + 都要搭配上键盘的键码
      1. window.onkeydown - 按下和按住都会触发,而且任何按键都会触发
      2. window.onkeypress - 按下和按住都会触发,但是只有数字、字母、回车、空格可以触发
      3. window.onkeyup - 松开的时候才会触发,而且任何按键都会触发
  3. 获取键盘的键码 e.keyCode - 可以获取到按了哪个键了直接控制台输出查看。

事件的取消绑定

  1. 如果你用的elem.on事件名=()=>{},那么你想要取消绑定:elem.on事件名=nul
  2. 如果用的elem.addEventListener("事件名",f1),那么想要取消绑定:
    elem.removeEventListener("事件名",f1),事件名和回调函数,【必须和添加时一模一样,是同一个】
this的指向
  1. 单个元素绑定事件,this->这个元素
  2. 多个元素绑定事件,this->当前触发事件的元素
  3. 箭头函数中的this->外部对象
  4. 函数中的this->当前正在调用函数的这个人
  5. 定时器的this->window
ES5强制改变this的指向
  1. call/apply:临时的替换了函数之中的this - 借用
    1. 语法:
      1. 函数名.call(借用的对象,实参,...) - 单独传入每个实参
      2. 函数名.apply(借用的对象,arr) - 只能传入一个实参,要求必须是一个数组:apply其实会将数组打散
    2. 强调:call/apply,相当于立刻调用函数,是会立刻执行的
  2. bind:永久的替换了函数中的this
    1. 语法:var 新函数=函数名.bind(指定对象,永久的固定的实参);
      1. 创建了一个和原函数功能完全相同的新函数
      2. 将新函数中的this永久绑定了为指定对象,别人都借不走
      3. 将新函数的部分参数永久固定的
    2. 强调
      1. bind绑定的新函数没办法被call/apply再次借走
      2. bind是不会立刻调用的,需要自己手动调用一下
  3. 三个固定套路:
    1. Math.max/min.apply(Math,arr);
    2. 类数组转为普通数组
      1. 老方法:接住=Array.prototype.slice.call/apply(类数组)
      2. 新方法:接住=Array.from(类数组)
ES5严格模式

很严格 - 可以在任意作用域的顶部写上一句话:"use strict";

效果:

  1. 全局污染会报错
  2. 将静默失败升级为报错!

正则表达式:

  1. 定义字符串中字符出现规则的表达式
    何时使用:切割、替换、【验证】
    如何使用:语法:/正则表达式/;

    1. 最简单的正则就是关键字原文:"no" -> /no/后缀
      后缀:g:找全部 i:忽略大小写
  2. 备选字符集:/[备选字符集]/

    1. 强调:
      1. 一个中括号,只管一位字符 2、问题:正则表达式默认只要满足了就不管后续了,而我们做验证的人,希望的是用户从头到尾完全按照我们的要求来,希望完全匹配 解决:前加^后$加两者同时使用,代表要求从头到尾【完全匹配】 - /^[备选字符集]$/; 3. 特殊:如果备选字符集中ASCII码是连续的,那么可用-省略掉中间部分
  3. 预定义字符集

    1. 一位数字:\d
    2. 一位数字、字母、下划线:\w
    3. 一位空白字符:\s - 什么叫空白字符:空格、制表符、换行
    4. 一位除了换行外的任意字符
  4. 量词:规定一个字符集出现的次数

    1. 有明确数量

      1. 符集{n,m}:前边相邻的字符集最少出现n个,最多出现m个
      2. 字符集{n,}:前边相邻的字符集最少出现n个,多了不限
      3. 字符集{n}:前边相邻的字符集必须出现n个
    2. 无明确数量

      1. 字符集?:前边相邻的字符集,可有可无,最多1个
      2. 字符集*:前边相邻的字符集,可有可无,多了不限
      3. 字符集+:前边相邻的字符集,至少一个,多了不限
  5. 选择和分组:

    1. 选择:在多个规则中选一个,选择往往都要和分组进行搭配
      规则1|规则2
    2. 分组:将多个字符集临时组成一组子规则
      (规则1|规则2)
  6. 指定匹配的位置

    1. 开头:^
    2. 结尾:$
    3. 特殊:两者如果同时使用,前加^后加$,表示从头到尾要求完全匹配 - 只要你做【验证】
  7. 预判公式

    1. (?![0-9]+$) -> 不能全由数字组成,可能有大写、小写、汉字、日文、韩文、特殊符号...
    2. (?![0-9a-z]+$) -> 不能全由数字组成,也不能全由小写组成,也不能全由数字和小写的组合组成,可能有大写、汉字、日文、韩文、特殊符号...
    3. (?![0-9A-Za-z]+$) -> 不能全由数字组成,也不能全由小写组成,也不能全由数字和小写的组合组成,也不能全由数字和大写的组合组成,也不能全由大字和小写的组合组成,也不能全由数字和大写和小写的组合组成
    4. 例子:长度为2-4,可以输入数字、字母、但是必须出现一位大写和一位数字的组合?
      var reg=/^(?![0-9a-z]+)(?![AZaz]+)(?![A-Za-z]+)[0-9A-Za-z]{2,4}$/;
支持正则的字符串API
  1. 切割:var arr=str.split("固定切割符"/RegExp);

  2. 替换:

    1. 基础替换法:var newStr=str.replace(RegExp,"新内容");
    2. 高级替换法: var newStr=str.replace(/[替换的内容][第二个替换的内容]+/g,function(key,i,str){
      console.log(key);//关键字
      console.log(i);//关键字的下标
      console.log(str);//原文本身
      return a.length==2?"":"*";
  3. 格式化:

    1. var idCard="52222720231204091X";
    2. var reg=/(\d{6})(\d{4})(\d{2})(\d{2})(\d{4})/;将原字符串分为5个分组
    3. var newStr=idCard.replace(reg,function(a,b,c,d,e,f,g,h){
    4. 在replace的时候,如果正则中出现了分组,那我们会得到更多的形参,在形参key的后面就会出现n个形参,具体有多少个,看你有多少个分组
    5. 第1个分组获得的内容会保存到第2个形参之中,依次排列
    6. return ${c}年${d}月${e}日;
  4. 正则对象:

    1. 创建:

      1. 直接量:var reg=/正则表达式/后缀;
      2. 构造函数:var reg=new RegExp("正则表达式","后缀");
    2. API

      1. 验证:var bool=reg.test(str);