BOM常用对象
定时器,客户端储存技术,event
location对象:保存了当前窗口的正在打开的url
由5部分组成:协议、主机号|域名|IP地址、端口号、文件的相对路径|路由、查询字符串|请求信息
属性:
- 协议:location.protocol
- 域名:location.hostname
- 端口号:location.port;
- 路由:ocation.pathname;
- 请求消息:location.search;
方法
- 跳转:location="新url";
- 跳转后,禁止后退:location.replace("新url");
- 刷新:location.reload();
DOM
- 核心DOM:既可以操作HTML又可以操作XML,但是语法相对比较复杂
- HTML DOM:只能操作HTML,不能访问一些自定义的东西,但是语法比较简单
- XML DOM:只能操作XML,被淘汰了,被JSON数据格式代替了
1、查找元素:
- 通过关系网查找元素
- 通过HTML的特性去查找元素
- var elems=document.getElementsByXXXXX();//返回的是一个动态集合HTMLCollection
- var elem=document.querySelector("任意css选择器");找到的是单个元素
- *var elems=document.querySelectorAll("任意css选择器");找到的是一个集合
2、操作样式:
- 内联样式:
- 获取:elem.style.css属性名; - 只能获取内联样式
- 设置:elem.style.css属性名="css属性值";
3、操作属性:
-
获取属性值:
核心DOM:elem.getAttribute("属性名");
HTML DOM:elem.属性名; -
设置属性值
核心DOM:elem.setAttribute("属性名","属性值");
HTML DOM:elem.属性名="属性值"; -
删除属性
核心DOM:elem.removeAttribute("属性名");
HTML DOM:elem.属性名=""; -
判断有没有属性
核心DOM:elem.hasAttribute("属性名");
HTML DOM:elem.属性名!="";
4、操作内容
innerHTML/innerText/value
5、如何创建元素以及上树:3步
- 创建空标签:var elem=document.createElement("标签名");
- 为其设置必要的属性和事件
- elem.属性名="属性值";
- elem.on事件名=function(){}
- 上树:三种
- 父元素.appendChild(elem);//在父元素末尾追加一个子元素elem
- 父元素.insertBefore(elem,已有子元素);//在父元素里面追加一个子元素elem,但是会放到已有子元素的前面
- 父元素.replaceChild(elem,已有子元素);//在父元素里面追加一个子元素elem,但是会替换掉已有子元素
6、删除元素:
elem.remove();
扩展:
- input/textarea的两个专属事件:onfocus(获取焦点)和 onblur(失去焦点)
- let 变量名=值;
- 解决了声明提前,一定先创建,后使用
- 带来了块级作用域,一个{}就是一个块
- 如果你用let当作下标去绑定事件,那么他会记录着你当前元素的下标,不需要再自定义下标了
- 类数组对象变为普通数组: let 变量名=Array.from(类数组);
递归
就是在函数中再一次调用了函数自己,专门用于【遍历层级不明确】的情况
使用方法:
function 函数名(root){
1 、rootroot第一层要做什么直接做
2、 判断有没有下一层,如果有下一层再次调用此方法,但是传入的实参是自己的下一层
}
函数名(实际的根元素)
- 算法:深度优先算法!优先遍历当前节点的子节点,子节点遍历完毕才会跳到兄弟节点
- 缺陷:不要过多使用,性能相对较差,同时开启大量的函数调用,浪费内存,我们只在一个情况使用它:【遍历层级不明确】
递归与死循环
- 递归:优点:简单易用,缺点是性能较低
- 纯循环:优点:性能高,缺点是比较复杂
绑定事件:3种方式
- 在HTML页面上书写事件属性:<elem on事件名="函数名()">
- 在JS中使用是件处理函数属性:elem.on事件名=function(){操作}
- 在JS中使用事件API:
- 主流:elem.addEventListener("事件名",callback)
- 老IE:elem.attachEvent("on事件名",callback)
扩展:
select&option 只有这俩可以简化创建和上树
select.add(new Option("innerHTML","value"));
获取事件对象event
事件周期:从事件发生,到所有是件处理函数执行完毕的全过程
- 捕获阶段:由外向内,记录着要发生的事件有哪些
- 目标优先触发:目标元素->当前点击的实际发生事件的元素
- 冒泡触发:由内向外,依次执行我们之前记录着的要发生的事件
主流:会自动作为事件处理函数的第一个形参传入e
老IE:event;
兼容:event;
获取事件对象event的作用:
-
获取鼠标的坐标/位置:3种
- 获取鼠标相对于屏幕的坐标:e.screenX/Y;
- 获取鼠标相对于浏览器窗口/客户端/文档显示区域的坐标:e.clientX/Y
- 获取鼠标相对于网页的坐标:e.pageX/Y;
-
阻止冒泡:
- 主流:e.stopPropagation();
- 老IE:e.cancelBubble=true;
- 兼容:e.cancelBubble=true;
-
事件委托/利用冒泡: 优化:如果多个子元素定义了 相同 或 相似的事件操作,那么最好只给【父元素】绑定一次
使用【目标元素】,可以减少绑定事件函数的次数,优化了网页的性能
主流:e.target;
老IE:e.srcElement;
兼容:e.srcElement;
-
阻止浏览器的默认行为
- 主流:e.preventDefault();
- 老IE:e.returnValue=false;
- 兼容:e.returnValue=false;
-
新的事件:
- 右键事件:window.oncontextmenu;
- 键盘事件 一般用于游戏开发比较多 + 都要搭配上键盘的键码
- window.onkeydown - 按下和按住都会触发,而且任何按键都会触发
- window.onkeypress - 按下和按住都会触发,但是只有数字、字母、回车、空格可以触发
- window.onkeyup - 松开的时候才会触发,而且任何按键都会触发
-
获取键盘的键码 e.keyCode - 可以获取到按了哪个键了直接控制台输出查看。
事件的取消绑定
- 如果你用的elem.on事件名=()=>{},那么你想要取消绑定:elem.on事件名=nul
- 如果用的elem.addEventListener("事件名",f1),那么想要取消绑定:
elem.removeEventListener("事件名",f1),事件名和回调函数,【必须和添加时一模一样,是同一个】
this的指向
- 单个元素绑定事件,this->这个元素
- 多个元素绑定事件,this->当前触发事件的元素
- 箭头函数中的this->外部对象
- 函数中的this->当前正在调用函数的这个人
- 定时器的this->window
ES5强制改变this的指向
- call/apply:临时的替换了函数之中的this - 借用
- 语法:
- 函数名.call(借用的对象,实参,...) - 单独传入每个实参
- 函数名.apply(借用的对象,arr) - 只能传入一个实参,要求必须是一个数组:apply其实会将数组打散
- 强调:call/apply,相当于立刻调用函数,是会立刻执行的
- 语法:
- bind:永久的替换了函数中的this
- 语法:var 新函数=函数名.bind(指定对象,永久的固定的实参);
- 创建了一个和原函数功能完全相同的新函数
- 将新函数中的this永久绑定了为指定对象,别人都借不走
- 将新函数的部分参数永久固定的
- 强调
- bind绑定的新函数没办法被call/apply再次借走
- bind是不会立刻调用的,需要自己手动调用一下
- 语法:var 新函数=函数名.bind(指定对象,永久的固定的实参);
- 三个固定套路:
- Math.max/min.apply(Math,arr);
- 类数组转为普通数组
- 老方法:接住=Array.prototype.slice.call/apply(类数组)
- 新方法:接住=Array.from(类数组)
ES5严格模式
很严格 - 可以在任意作用域的顶部写上一句话:"use strict";
效果:
- 全局污染会报错
- 将静默失败升级为报错!
正则表达式:
-
定义字符串中字符出现规则的表达式
何时使用:切割、替换、【验证】
如何使用:语法:/正则表达式/;- 最简单的正则就是关键字原文:"no" -> /no/后缀
后缀:g:找全部 i:忽略大小写
- 最简单的正则就是关键字原文:"no" -> /no/后缀
-
备选字符集:/[备选字符集]/
- 强调:
- 一个中括号,只管一位字符 2、问题:正则表达式默认只要满足了就不管后续了,而我们做验证的人,希望的是用户从头到尾完全按照我们的要求来,希望完全匹配 解决:前加^后$加两者同时使用,代表要求从头到尾【完全匹配】 - /^[备选字符集]$/; 3. 特殊:如果备选字符集中ASCII码是连续的,那么可用-省略掉中间部分
- 强调:
-
预定义字符集
- 一位数字:\d
- 一位数字、字母、下划线:\w
- 一位空白字符:\s - 什么叫空白字符:空格、制表符、换行
- 一位除了换行外的任意字符
-
量词:规定一个字符集出现的次数
-
有明确数量
- 符集{n,m}:前边相邻的字符集最少出现n个,最多出现m个
- 字符集{n,}:前边相邻的字符集最少出现n个,多了不限
- 字符集{n}:前边相邻的字符集必须出现n个
-
无明确数量
- 字符集?:前边相邻的字符集,可有可无,最多1个
- 字符集*:前边相邻的字符集,可有可无,多了不限
- 字符集+:前边相邻的字符集,至少一个,多了不限
-
-
选择和分组:
- 选择:在多个规则中选一个,选择往往都要和分组进行搭配
规则1|规则2 - 分组:将多个字符集临时组成一组子规则
(规则1|规则2)
- 选择:在多个规则中选一个,选择往往都要和分组进行搭配
-
指定匹配的位置
- 开头:^
- 结尾:$
- 特殊:两者如果同时使用,前加^后加$,表示从头到尾要求完全匹配 - 只要你做【验证】
-
预判公式
- (?![0-9]+$) -> 不能全由数字组成,可能有大写、小写、汉字、日文、韩文、特殊符号...
- (?![0-9a-z]+$) -> 不能全由数字组成,也不能全由小写组成,也不能全由数字和小写的组合组成,可能有大写、汉字、日文、韩文、特殊符号...
- (?![0-9A-Za-z]+$) -> 不能全由数字组成,也不能全由小写组成,也不能全由数字和小写的组合组成,也不能全由数字和大写的组合组成,也不能全由大字和小写的组合组成,也不能全由数字和大写和小写的组合组成
- 例子:长度为2-4,可以输入数字、字母、但是必须出现一位大写和一位数字的组合?
var reg=/^(?![0-9a-z]+)[0-9A-Za-z]{2,4}$/;
支持正则的字符串API
-
切割:var arr=str.split("固定切割符"/RegExp);
-
替换:
- 基础替换法:var newStr=str.replace(RegExp,"新内容");
- 高级替换法:
var newStr=str.replace(/[替换的内容][第二个替换的内容]+/g,function(key,i,str){
console.log(key);//关键字
console.log(i);//关键字的下标
console.log(str);//原文本身
return a.length==2?"":"*";
-
格式化:
- var idCard="52222720231204091X";
- var reg=/(\d{6})(\d{4})(\d{2})(\d{2})(\d{4})/;将原字符串分为5个分组
- var newStr=idCard.replace(reg,function(a,b,c,d,e,f,g,h){
- 在replace的时候,如果正则中出现了分组,那我们会得到更多的形参,在形参key的后面就会出现n个形参,具体有多少个,看你有多少个分组
- 第1个分组获得的内容会保存到第2个形参之中,依次排列
- return
${c}年${d}月${e}日;
-
正则对象:
-
创建:
- 直接量:var reg=/正则表达式/后缀;
- 构造函数:var reg=new RegExp("正则表达式","后缀");
-
API
- 验证:var bool=reg.test(str);
-