目录
DOM
DOM – Document Object Model文档对象模型
DOM定义了表示和修改文档所需要的方法,是一系列方法的统称
DOM对象即为宿主对象,由浏览器厂商定义,用来操作HTML和XML功能的一类对象的集合,也可以称之为DOM是对HTML以及XML的标准编程接口
任何东西都操作不了css
简单来说,XML是HTML的前身
DOM操作不了css样式表,但是可以通过间接的方式改变css,就是操作HTML直接往上面加属性
基本操作
在页面中选择除了按照id选择,其余的选出来基本都是类数组,所以此时此刻,哪怕符合选名规则的元素只有一个,返回出来的任然是一个类数组,所以无论被选中的有几个,都要使用数组的方式精确选中,即在后面加上下标
-
document代表整个文档,包含HTML
-
document.getElementById(),表示按照id名来选中元素
在IE8以下的浏览器,ID不区分大小写,而且返回匹配name属性的元素,在返回的时候,可能会改变你的id,所以不建议使用 -
document.getElementsByTagName(),表示根据标签名来选中元素,会选中的所有带这个标签名的元素,然后返回一个类数组
不存在兼容性问题,所以是最提倡的使用方法
如果里面填‘*’就表示选中所有标签 -
document.getElementsByClassName(),根据类名来选中元素,存在兼容性问题,在IE8及IE8以下没有这个方法
-
document.getElementsByName(),要注意的是,name属性是可以提交数据的组件的数据名,所以只有在表单,表单元素,iframe,img这些里面,name才是有意义的,所以要注意兼容性问题
-
document.querySelector(),是可以通过使用css选择器来选中想要元素
-
document.querySelectorAll(),和上面差不多,区别是使用这个是选中一组选择器
缺点:在IE6及以下是无法识别的,不是实时的,只有最开始对元素做的行为,在后面对所选中的元素做出一系列操作在6,7两种方法里面不会实现,除非通过自己命名的数组选中才会进行更改
节点的类型
—元素类型------节点类型—
- 元素节点-------1
- 属性节点-------2
- 文本节点-------3
- 注释节点-------8
- document-------9
- DocumentFragment----11
节点的属性
- nodeName,以字符串的形式返回元素的标签,以大写形式表示,只读
- nodeValue,只有Text节点或者Comment节点的文本内容才有这个属性,可以读写
- nodeType,节点的类型,只读
- attribute,Element节点的属性集合
可以在获得属性节点的类数组之后,对数组的每一个元素进行name或者value的操作,name不可改,value可以改
// 实现在不用children的情况下返回元素子节点
var test = document.getElementsByTagName('div')[0];
function ElementChild(node){
var temp = {
length : 0,
push : Array.prototype.push,
splice : Array.prototype.splice
},
child = node.childNodes,
len = child.length;
for( var i = 0; i < len ; i ++){
if(child[i].nodeType === 1){
temp.push(child[i]);
}
}
return temp;
}
console.log(ElementChild(test));
遍历节点树
一个元素在dom里面称之为一个节点,元素也可以称之为dom元素
- parentNode—表示父节点,最顶端的parentNode为#document
- childNodes—子节点们
- firstChild—第一个子节点
- lastChild—最后一个子节点
- nextSibling—下一个兄弟节点
- previousSibling—前一个兄弟节点
==节点的一个方法:hasChildNodes()==就是判断是否存在子节点,返回布尔值
遍历元素节点数
除children以外,IE9及以下都不兼容
- .parentElement,返回当前元素的父元素节点(IE不兼容)
- .children,返回当前元素的元素子节点
- .childElementCount === .children.length,就是求当前子元素节点的个数(IE不兼容)
- firstElementChild,返回第一个元素子节点(IE不兼容)
- lastElementChild,返回最后一个元素子节点(IE不兼容)
- nextElementSibling—下一个兄弟元素节点(IE不兼容)
- previousElementSibling—前一个兄弟元素节点(IE不兼容)
节点的一个方法:hasChildren()就是判断是否存在元素子节点,返回布尔值
DOM继承树
document后面的分支还有XMLDocument
函数的位置
- document.getElementById(),定义在Document.prototype上,HTML和XML都可以调用,其他节点不能调用
- document.getElementsByName()定义在了HTMLDocument.prototype上,非HTML不可以使用
- document.getElementsByTagName()定义在了Document和Element的prototype上
- HTMLDocument.prototype定义了一些常用的属性,body,head属性分别指代HTML文档中的body,head标签
- Document.prototype上定义了DocumentElement属性,代指文档的根元素,在HTML文档中,代指html标签
- document.getElementsByClassName(),querySelector(),querySelectorAll()在Document.prototype,Element.prototype均有定义
增
括号里面都填字符串
- document.createElement();增加或创建一个元素节点,但此时创建的元素节点是存放在js的变量里面的,要让这个元素出现在body里面,需要使用document.body.appendChild(),将创建出来的元素节点添加在body里面
- document.createTextNode();创建文本节点
- document.createComment();创建注释节点
- document.createDocumentFragment();创建文档事件节点
插
填变量名
-
appendChild();所有的元素节点都会有appendChild方法,作用类似于push,但实际上是剪切作用,可以对文本节点进行操作,也可以对元素节点进行操作
-
insertBefore(a, b);把a插在b前面
删除
- parent.removeChild();通过父级剪切子元素节点
- child.remove();通过自己直接删除自己
替换
- parent.replaceChild(new, origin);表示拿新的元素替换老的元素,然后老的元素是被剪切出来,并不是直接被删除
想修改也可以直接这样修改
- element.id可以直接修改id
- element.className可以直接修改classname
element节点的属性和方法
属性
-
innerHTML,对使用这个属性的元素里面的全部内容进行提取和赋值
-
innerText,直接对使用这个属性的元素里面的文本内容进行提取和赋值
注意这个属性火狐不兼容,在火狐里面可以使用textContent(老版本的IE不管用),作用都一样
方法
-
element.setAttribute(‘a’,‘b’);给元素设置行间属性,a是属性名,b是属性值
-
element.getAttribute(‘a’);取出该元素里面属性名为a的属性值
日期对象 Date()
封装函数,打印当前是何年何月何日,几分几秒
是系统自带的对象,由构造函数去建立,例如var date = new Date();
- getTime(),计算从1970年1月1日到现在一共过去了多少毫秒------最常用的方法
可以求时间戳
建议直接看w3c里面的,链接在这里:https://www.w3school.com.cn/jsref/jsref_obj_date.asp
js定时器
setInterval(function (){
},1000)//每隔一千毫秒执行一次函数
循环执行
在数值那里也可以填一个自己定义的变量,不过如果在后期变量发生改变,但是该函数执行频率不会发生改变,因为在setInterval执行的时候,time只会被读取一次,所以就不会发生改变
每一个setInterval()都会返回一个唯一标识,是数字,从1开始排列
其实是不准的
clearInterval();里面传入的数据就是setInterval返回的数值,用于清除setInterval
setTimeout(function (){
},1000);
表示在1000毫秒之后执行一次函数体
相对应的,clearTimeout();就是清除setTimeout的函数,传入内容也是setTimeout返回的唯一标识
以上这些方法都是全局对象window上的方法,内部函数this指向window
两种计时器的函数部分也可以用字符串形式表示js代码
DOM基本操作,一些边角知识
- 查看滚动条滚动距离
- window.pageXOffset/pageYOffset(X求x轴,Y求y轴,返回像素值)
- IE8及以下不支持
- document.body.scrollLeft,document.body.scrollTop,前者求x轴,后者求y轴
- document.documentElement.scrollLeft,document.documentElement.scrollTop和上面一样
这两个存在兼容性问题,在IE8即以下,只有一个会生效,且不一定哪个会生效,但这两个存在的情况是互斥的
- window.pageXOffset/pageYOffset(X求x轴,Y求y轴,返回像素值)
实现效果的函数封装
function getScrollOffset() {
if ( window.pageXOffset) {
return {
x : window.pageXOffset,
y : window.pageYOffset
}
}else{
return {
x : document.documentElement.scrollLeft + document.body.scrollLeft,
y : document.documentElement.scrollTop + document.body.scrollTop
}
}
}
浏览器的怪异模式也可以称为混杂模式,一旦启动就会不再使用最新的css标准,而是会兼容之前版本的浏览器删掉这行代码就会启动怪异模式
- 查看视口尺寸(就是html占据屏幕的大小)
- window.innerWidth/innerHeight
- IE8及以下不支持
- document.documentElement.clientWidth,document.documentElement.clientHeight
- 标准模式下,任意浏览器都兼容
- document.body.clientWidth,document.body.clientHeight
- 适用于怪异模式下的浏览器
- window.innerWidth/innerHeight
如何判断浏览器处于什么模式?
document.compatMode , 返回"CSS1Compat",表示是标准模式,返回"BackCompat"表示怪异模式
实现效果的函数封装
function getViewportOffset() {
if (window.innerWidth) {
return {
w : window.innerWidth,
h : window.innerHeight
}
}else{
if (document.compatMode === "BackCompat") {
return {
w : document.body.clientWidth,
h : document.body.clientHeight
}
}else{
return {
w : document.documentElement.clientWidth,
h : document.documentElement.clientHeight
}
}
}
}
- 查看元素的几何尺寸
- div.getBoundingClientRect();
- 兼容性很好
- 返回一个对象,对象里面有left,top,right,bottom等属性。left,top代表该元素左上角的x,y坐标,right,bottom代表右下角的x,y坐标,x,y表示盒子左边界和上边界和左边上边的距离
- height和width属性老版本的IE没有实现
- 返回的结果不是实时的
html代码如下
<div style="width: 100px;height: 100px;position: absolute;top: 250px;left: 250px;background-color: rosybrown;">
-
查看元素尺寸
- div.offsetWidth,div.offsetHeight查看宽高
-
查看元素的位置
- div.offsetLeft,div.offsetTop
- 对于无定位的父级元素,返回相对文档的坐标,对于有定位父级返回相对于有定位的父级的坐标
- div.offsetParent返回最近的有定位的父级,如果没有,返回body,body.offsetParent返回NULL
都是求视觉上的尺寸(就是border及以内的)
- 让滚动条滚动
- window上面有三个方法,scroll(),scrollTo(),scrollBy()
都是传入两个参数,第一个是x轴方向想让滚动条滚动的距离,第二个是纵轴方向上让滚动条滚动的距离,但是前两个是直接到那个想要到的位置不会累加,第三个是会累加的
- window上面有三个方法,scroll(),scrollTo(),scrollBy()
脚本化CSS
间接控制css,读写css属性
-
dom.style.prop(只有这种方法可以写入值)
- 对行间样式进行读写,没有兼容性问题,碰到float这种保留字属性应该加css
- 复合属性必须拆解,组合单词变成小驼峰式写法
- 写入的必须是字符串格式
-
查询计算样式
- window.getComputedStyle(element, null);
- 这个计算样式只读
- 返回值都是绝对值,没有相对单位,例如rem返回px,色值返回rgb等等
- IE8及以下不兼容
- 想要获取伪元素的size可以把第二个参数换成’before’或者’after’
-
查询计算样式(兼容ie浏览器)
- ele.currentStyle
- IE独有的属性,返回值和window.getComputedStyle(element, null);一样,elem.currentStyle.prop
函数封装
var div = document.getElementsByTagName('div')[0];
var width = 'width';
function getStyle(element, prop) {
if(window.getComputedStyle){
return window.getComputedStyle(element, null)[prop];
}else{
return element.correntStyle[prop];
}
}
事件
交互体验的核心功能
绑定事件
给特定元素的特殊事件绑定特定的处理函数
-
ele.onxxx = function(event) {}
- 兼容性好,但是一个元素的同一件事件上面只能绑定一个函数
- 基本等同于写在HTML行间上
- 句柄的方式
-
dom.addEventListener(type,function,false)
- IE9及以下不兼容,可以为一个事件绑定多个处理函数
- 第一个参数是事件类型,第二个是处理函数,第三个暂且不管,可深入
- 如果绑定多个处理函数,若处理函数的地址不一样,那就按照书写顺序依次执行函数,如果地址一样,就只执行一次
-
dom.attachEvent( ‘on’ + 事件类型, 处理函数);
- IE独有的,一件事情可以绑定多个函数
var li = document.getElementsByTagName('li');
// for (var i = 0; i < li.length; i++ ){
// li[i].onclick = function () {
// console.log(i);
// }
// }
// 错误示范,存在闭包
// 正确答案
for (var i = 0; i < li.length; i++ ){
(function (i) {
li[i].onclick = function () {
console.log(i);
}
}(i))
}
事件处理程序的运行环境
-
ele.onxxx = function(event){}
- 程序this指向dom元素本身
-
dom.addEventListener(type,function,false)
- 程序this指向dom元素本身
-
dom.attachEvent( ‘on’ + 事件类型, 处理函数);
- 程序this指向window
- 如何解决?使用封装函数来实现具体想用的功能,然后使用call来改变this的指向
实现封装事件处理函数,传入元素,事件类型,以及调用函数
function addEvent(elem, type, handle) {
if(elem.addEventListener){
elem.addEventListener(type, handle, false);
}else if(elem.attachEvent){
elem.attachEvent('on' + type, function () {
handle.call(elem);
});
}else{
elem['on' + type] = handle;
}
}
如何解除事件?
- ele.onxxx = function(event){},直接把函数换成null
- dom.addEventListener(type,function,false);
dom.removeEventListener(type,function,false);函数部分必须一致,都是特定的 - dom.attachEvent( ‘on’ + 事件类型, 处理函数);
dom.detachEvent( ''on + 事件类型, 处理函数);
如果绑定匿名函数,无法进行解除
事件处理模型–事件冒泡、捕获
-
事件冒泡:
- 结构上(非视觉)嵌套关系的元素,会存在事件冒泡的功能,即同一个事件,自子元素冒泡向父元素(自底向上)
- 一般默认是事件捕获,就是dom.addEventListener(type,function,false);第三个参数为false,就会触发事件冒泡
-
事件捕获:
- 结构上(非视觉)嵌套关系,会存在事件捕获的功能,即同一个事件,自父元素捕获至子元素(事件源元素)。(自顶向下)
- IE没有捕获事件
- 把dom.addEventListener(type,function,flase);第三个参数改为true,就会触发事件捕获
-
触发顺序是先捕获,再冒泡
一个对象的一个事件,只能遵循一种事件类型
- focus,blur,change,submit,reset,select等事件不冒泡
取消事件冒泡和捕获
-
取消冒泡
- W3C标准event.stopPropagation(),不支持ie9及以下版本
- IE独有的event.cancelBubble = true;
event是绑定事件的函数的事件对象,就是在事件处理函数里面传入一个形参(系统自动会传入一个事件对象)系统会传入许多关于此时事件执行时的情况
- 封装函数
function stopBubble(event) { if(event.stopPropagation){ event.stopPropagation(); }else{ event.cancelBubble = true ; } }
-
取消默认事件
- 默认事件:表单提交,a标签跳转,右键菜单等
- return false;以对象属性的方式注册的事件才生效
以句柄的事件绑定才可以 - event.preventDefault();W3C标注,IE9以下不兼容
- event.returnValue = false;兼容IE
- 封装阻止默认事件的函数 cancelHandler(event);
function cancelHandler(event) { if(event.preventDefault){ event.preventDefault(); }else{ event.returnValue = false; } }
事件对象
- window.event用于IE
var event = e || window.event;
- 事件源对象:(每一个事件的事件源对象都不一样都不一样)
- event.target 火狐只有这个
- event.srcElement IE只有这个
- Chrome上述两个都有
- 兼容性写法
function func(e) {
var event = e || window.event;
var target = event.target || event.srcElement;
}
事件委托
- 利用事件冒泡和事件源对象进行处理
- 优点:
- 性能 不需要循环所有的元素一个个绑定事件
- 灵活 当有新的子元素时不需要重新绑定事件
实现demo,可以随意拖拽的小方块
var div = document.getElementsByTagName('div')[0];
var disX,
disY;
div.onmousedown = function (e) {
disX = e.pageX - parseInt(div.style.left);
disY = e.pageY - parseInt(div.style.top);
document.onmousemove = function (e) {
var event = e || window.event;
var x = event.pageX,
y = event.pageY;
div.style.left = x - disX + 'px';
div.style.top = y - disY + 'px';
}
document.onmouseup = function () {
div.onmousemove = null;
}
}
需提高:(未完成)
要求:要改成函数的形式,绑定事件,取消冒泡等等
事件2,二十分钟左右
鼠标帧频比事件监听帧频快怎么办?
div.setCapture();会将位置外发生的事情获取在调用功能的div上
- div.setCapture();仅在IE里面可以用
- div.releaseCapture();与上面相对应,作用是释放事件
事件分类
-
鼠标事件
- click,点击事件
click = mousedown + mouseup
执行顺序是先down,后up,最后click - mousedown,表示鼠标按下去
- mousemove,鼠标移动的事件
- mouseup,表示按下去的鼠标起来
- contextmenu,右键菜单
- mouseover,鼠标进入区域要发生的事(老版本)
- mouseout,鼠标离开区域的时候要发生的事(老版本)
- onmoseenter,鼠标进入区域要发生的事(新版本)
- mouseleave,鼠标离开区域的时候要发生的事(新版本)
- click,点击事件
-
利用button判断是点击鼠标左键还是右键
event返回button属性会告诉你是使用左键点击还是右键还是中间滚动轮
属性值为0是左键,1为中间滚动轮,2为右键
div.onmousedown = function (e) {
if (e.button == 0) {
console.log('left');
}else if(e.button == 1){
console.log('center');
}else if(e.button ==2){
console.log('right');
}
}
-
DOM3规定:click事件只能监听左键,只有mousedown和mouseup可以判断鼠标键
-
如何解决mousedown和click的冲突
当鼠标按下去和抬起来的时间超过300毫秒的时候,判断为非点击
var firstTime = 0;
var lastTime = 0;
var key = false;
document.onmousedown = function () {
firstTime = new Date().getTime();
}
document.onmouseup = function () {
lastTime = new Date().getTime();
if(lastTime - firstTime < 300){
key = true;
}
}
document.onclick = function () {
if(key) {
console.log('click');
key = false;
}
}
-
键盘事件
- keydown
- keyup
- keypress,一直按住会一直触发
- keydown > keypress > keyup(顺序)
- keydown和keypress的区别
- keydown可以响应任意键盘按键,keypress只可以响应字符类键盘按键
- keypress返回ASCII码,可以转换成相应字符
- keydown监测字符是不准的,如果是对字符串类型的监测,使用keypress更好,还可以区分大小写
- 事件对象的which属性,返回的是键盘上面的序号
- String.fromCharCode(e.charCode),String上面的静态方法fromCharCode可以将Unicode编码转化为字符,(Unicode编码包括ASCII码)
-
文本类操作事件
- input,只要文本内容有变化,就会触发这个事件
- change,如果聚焦前后内容发生改变,才会触发事件
- blur,表示当对象失去焦点的时候触发的事件
- focus,表示对象有焦点的时候触发的事件
// 输入框功能完善 var input = document.getElementsByTagName('input')[0]; input.onfocus = function () { if (this.value == '请输入用户名') { this.value = ''; this.style.color = '#000'; } } input.onblur = function () { if (this.value == '') { this.value = '请输入用户名'; this.style.color = '#999'; } }
-
窗体操作类(window上面的事件)
- scroll,当滚动条滚动的时候就会触发事件
- load,当页面上所有需要加载的部分全部加载完毕的时候,触发这个事件(效率最低)
- readyState,IE上面和load功能一样的属性,里面是一个字符串,会动态改变里面的值,如果加载完毕,值为complete或者loaded
- onreadystatechange,IE提供的用于监测readystate的方法
randerTree = domTree + cssTree
JSON + 异步加载 + 时间线
JSON : 就是一种传输数据的格式(以对象为样板,本质上就是对象,但用途有区别,对象是本地用的,json是用来传输的)
之前前后端交互数据就是利用xml传输数据,现在使用JSON传输数据,JSON虽然也是个对象,但和之前的对象有的一个最大的区别就是属性名必须要带双引号
- JSON.parse();将字符串形式的JSON转变为对象形式,用于转变后端传给前段的数据string -> json
- JSON.stringify();会将写的JSON形式的代码转变成字符串的形式,用于给后端传输数据json -> string
dom树,深度优先(dfs),dom树的完成是指解析完毕而不是加载完毕(加载完毕指引入图片之类的,会异步加载,也就是同时进行)
reflow,重排,是效率最低的一种方式,会让randerTree重排,dom节点的删除,添加,dom节点的宽高变化,位置变化,offsetWidth,offsetLeft,要尽量避免重排
repaint,重绘,可以理解为改变颜色,效率浪费较少,可以接受
异步加载js
js加载的缺点:加载工具方法没必要阻塞文档,过得js加载会影响页面效率,一旦网速不好,那么整个网站都将等待js加载而不进行后续渲染等工作
有些工具方法需要按需加载,用到再加载,不用不加载
- 三种方法
- defer 异步加载,但要等到dom文档全部解析完(dom树解析结束)才会被执行。只有ie可以用,也可以把代码写在内部,ie9以下可以用
- async 异步加载,加载完就执行,async只能加载外部脚本,不能把js写在script标签里,ie9以上以及其他浏览器可用
- 这两种方法都是属性名和属性值一样的,不过属性值的写入是字符串形式
- 前两种执行时也不阻塞页面
- 创建script,插入到dom中,加载完毕后callback,这种情况他会先加载,在需要调用的时候才会调用,如下所示
实现只有在script部分下载完毕之后才执行的函数封装,避免因为异步加载导致错误<script> var script = document.createElement('script'); script.type = 'text/javascript'; script.src = "demo.js"; document.head.appendChild(script); </script>
上述代码在传入的时候,callback在js文件中定义,在此时的执行的时候报错undefined,function loadScript(url, callback) { var script = document.createElement('script'); script.type = 'text/javascript'; if (script.readyState == 'complete' || script.readyState == 'loaded') { script.onreadystatechange = function () { if (script.readyState == 'loaded') { callback(); } } }else{ script.onload = function () { callback(); } } script.src = url;//避免因为加载速度过快导致函数不能执行 document.head.appendChild(script); }
- 解决方法一是使用函数引用将想要执行的函数名包裹住,然后在执行过程中js文件加载完毕之后再用,就不会报错
loadScript('demo.js',function () { test(); });
- 解决方法二是使用eval(),将想要调用的函数以字符串形式传入,然后使用eval(),将字符串内容当做js代码来执行
loadScript('demo.js','test()');
- 解决方法三是在js文件里面实现函数功能的时候,提前将各个函数放在一个对象里面,以字符串的形式传入,让后在封装函数里面调用的时候,直接使用[]调用那个函数
回调函数,callback
加载时间线
- 创建Document对象,开始解析web页面,解析html元素和他们的文本内容后添加Element对象和Text节点到文档中,这个阶段document.readyState = ‘loading’
- 遇到link外部css,创建线程加载,并继续解析文档
- 遇到script外部js,并且没有设置async,defer,浏览器加载并阻塞,等待js加载完成并执行该脚本,然后继续解析文档
- 遇到script外部js,并且设有async,defer,浏览器创造线程加载,并继续解析文档
对于async属性的脚本,脚本加载完成后立即执行。(异步禁止使用document.write()) - 遇到img等,先正常解析dom结构,然后浏览器异步加载src,并继续解析文档
- 当文档解析完成后,document.readyState = ‘interactive’
- 当文档解析完成后,所有设置有defer的脚本会按顺序执行。(注意要async的不同,但同样禁止使用document.write())
- document对象触发DOMContentLoaded事件,这也标志着程序从同步脚本执行阶段,转化为事件驱动阶段
- 当所有async的脚本加载完成并执行后,img等加载完成后,document.readyState = ‘complete’,window对象触发load事件
- 从此,以异步响应方式处理用户输入,网络事件等
-
document.write();如果在onload之后进行这句代码的执行,会将前面的全部文档流都清空,然后用括号内的东西代替
-
事件名是全小写
console.log(document.readyState);
document.onreadystatechange = function () {
console.log(document.readyState);
}
- window.onload
- $(document).ready(function(){ }),指当dom解析完就执行的部分
上述两者的区别是第二个更快
正则表达式(RegExp)
实现多行:可以在改变html里面的内容的时候,在每个空格或者回车前面加上转移字符\,把空格转义掉,然后就不会报错;也可以通过+连接字符串实现文本换行,方便阅读
在正则表达式里面查找符号,需要加上\转义字符,这样才能表示单纯的那个符号文本
正则表达式的作用:匹配特殊字符或有特殊搭配原则的字符的最佳选择
在字符串之前加上^符号表示是字符串的开头
- 创建的两种方式
- 直接写(推荐)
- var reg = /abc/;这样直接创建
- new RegExp()
- var reg = new RegExp(‘abcd’,‘i’);//第一个参数是他的规则,第二个参数是属性
- var reg1 = new RegExp(reg);//加new表示创建了两个不一样的正则表达式,虽然看起来一样,但实际上是不一样的;如果不加,reg1和reg完全是一样的,只是不一样的引用
- 属性
- i属性,表示ignorecase,意思是忽略大小写
- var reg = /abc/i;
- g属性,全局匹配,一次匹配结束之后,还会继续匹配
- m属性,执行多行匹配,
- var reg = /^a/gm;
var str = ‘abc\na’;此时会找到两个a满足条件 - 当想要判断的字符串使用了\n换行的时候,换行后就会匹配两个
- var reg = /^a/gm;
- 需要注意lastIndex
- 表达式
- var reg = /[0-9][0-9][0-9]/g;
- 一个方括号代表一位,字符串相应的位置只能是那个里面的内容
- ^放在表达式里面表示非,就是!
- 最后一个|表示或,使用|必须要加小括号
- 元字符
- 可以在表达式里面写元字符
- \w完全等于[0-9A-z]
- \W完全等于[^\w]
- 单词边界就是字符串里面用空格隔开,表示单词,单词的首字母和最后一个字母都是单词边界
- 量词
- 贪婪匹配原则(能多不少)
- 如何变成非贪婪匹配呢?
在任何一个量词后面加上?,表示进行非贪婪匹配(能少不多) - 实际上是元字符/表达式先乘量词,然后再匹配字符串,要注意空’'的存在,当识别完字符串的时候,会有量词0和所求元字符相乘,然后产生空
- 正向预查,正向断言(?=n)
- 就是给想要查找的字符串添加一个附属条件
- 非正向预查(?!n)
- 就是不要有那个条件的字符串
- 就是不要有那个条件的字符串
- 方法
- test()方法,测试字符串是不是满足正则表达式里面的内容,返回true,false
- exec()方法,在g属性的调控下,会按照lastIndex返回的光标位置来查找想要的字符串,并且继续往后找,返回的是一个类数组
- 小括号也是子表达式,会记录括号里面的匹配内容
- \1是反向引用,表示反向引用第一个子表达式里面的内容,有\2\3\4之类的
- 支持正则表达式string对象的方法
- match,就是把符合内容的字符串挑出来,返回符合要求的字符串,如果在有子表达式的情况下,在没有g属性的情况下,他还会以类数组的形式返回字符串和子表达式的内容,如果有g属性,那就只返回想要的字符串
- search,返回想要的字符串的位置(不会考虑重复,只会返回找到的第一个的位置),如果没有找到,就会返回-1
- split,按照想要的字符串分割原字符串,如果有子表达式,还会返回子表达式的内容
- replace,第二个参数将替换第一个参数,replace函数不具备访问全局的能力,所以在没有属性g的情况下,都是只替换一个
- 使用$1$2可以反向引用第一个参数里面的子表达式,就和\1\2类似
- 第二个参数也可以是函数,函数的第一个参数是正则表达式匹配的结果,第二个参数是第一个子表达式匹配的内容,第三个参数是第二个子表达式匹配的内容
- 让最后返回的是想要的字符串
- 如果想替换为 就 这 样 书 写 就这样书写 就这样书写 , 连 着 书 写 两 个 ,连着书写两个 ,连着书写两个 , 第 一 个 ,第一个 ,第一个表示转义字符
// 转换成小驼峰式命名
var reg = /-(\w)/g;
var str = 'the-first-name';
console.log(str.replace(reg,function ($, $1) {
return $1.toUpperCase();
}));
// 将字符串逆置
var reg = /(\w)\1(\w)\2/g;
var str = 'aabb';
console.log(str.replace(reg, '$2$2$1$1'));
// 字符串去重
var str = 'aaaaaaaabbbbbbbbbccccccccc';
var reg = /(\w)\1*/g;
console.log(str.replace(reg, '$1'));
//原理:把一个和一串一样的替换
// 转换为科学记数法
var str = '1000000000';
var reg = /(?=(\B)(\d{3})+$)/g;
console.log(str.replace(reg, '.'));
// 原理:将空替换为.,并且在是在非单词边界的前提下
附上w3cschool的链接:https://www.w3school.com.cn/jsref/jsref_obj_regexp.asp