node属性
v1.node
描述:node是DOM中的最小单位,可以认为DOM概念下页面中所有的内容都是节点。
V2.node属性
描述:node属性如非特殊说明,则对所有的节点都生效。
3.nodeName \ nodeType
描述:返回节点的名称和节点的类型(节点类型采用常数表示)
语法:
node.nodeName
node.nodeTypev注意:对于元素节点,nodeName会返回大写的元素名
例子:
var span = document.querySelector('span');
console.log(span.nodeName); //SPAN
4.ownerDocument属性
描述:返回当前节点所在的文档的document节点
语法:
node.ownerDocument注意:document节点的ownerDocument属性返回null
例子:
console.log(div1.ownerDocument);
console.log(div2.ownerDocument);
console.log(span.ownerDocument);
console.log(document.ownerDocument);
v5.nextSibling属性
描述:返回紧跟在当前节点后的第一个同级节点
语法:
node.nextSibling注意:文本也是节点!!!!
例子:
console.log(div2.nextSibling);
console.log(div1.nextSibling.nextSibling);
// 查看div1中所有子节点
var el = div1.firstChild;
var i = 1;
while (el) {
console.log(i + '. ' + el.nodeName);
el = el.nextSibling;
i++;
}
V6.previousSibling属性
描述:所有注意事项和内容均和nextSibling完全相同,唯一区别在于返回前一个兄弟节点。
V7.parentNode属性
描述:返回当前节点的父节点,如果没有父节点则返回null。
例子:
console.log(div2.parentNode.parentNode.parentNode.parentNode.parentNode);
8.parentElement属性
描述:返回当前节点的父元素节点,如果没有父节点或者父节点不是元素节点,都返回null。
例子:
console.log(div2.parentNode.parentNode.parentNode.parentNode);
console.log(div2.parentElement.parentElement.parentElement.parentElement);
v9.childNodes属性
描述:返回一个由当前节点的所有子节点构成的节点集合(nodeList)
例子:
var childList = div1.childNodes;
console.log(childList);
console.log(childList instanceof Array);
console.log(childList instanceof Object);
console.log(childList.length);
console.log(childList[0]);
10.firstChild \ lastChild属性
描述:返回当前节点的第一个 \ 最后一个子节点,如果不存在则返回null
例子:
console.log(div1.firstChild);
console.log(div1.lastChild);
11.textContent属性
描述:属性返回当前节点,及其所有后代节点的内容
例子:
console.log(document.body.textContent)
12.nodeValue
描述:本属性用来读写节点的内容(仅对文本节点有效,其他类型节点使用均无效果)
例子:
console.log(span.firstChild.nodeValue);
span.nodeValue = '这是一个从新设置的span';
node节点的方法
v1. appendChild()方法
描述:本方法接收一个【节点对象】做参数,并将这个节点作为最后一个子节点插入当前节点。
语法:
node.appendChild(subNode);例子:
var div = document.querySelector('div');
var h2 = document.createElement('h2');
h2.innerHTML = '这是h2';
div.appendChild(h2);
console.log(div.childNodes);
v2. hasChildNodes()方法
描述:本方法用来判断一个节点是否存在子节点。如果有则返回true,否则false
语法:
node.hasChildNodes();例子:
var div = document.querySelector('div');
var h2 = document.querySelector('h2');
console.log(div.hasChildNodes());
console.log(h2.hasChildNodes());
v3. cloneNode()方法
描述:本方法表示拷贝一个节点。接收一个布尔值做参数表示是否同时拷贝该节点的所有子节点。
默认或不写参数都表示false(不拷贝)。
语法:
var newNode = node.cloneNode(boolean);注意:
(1) 节点拷贝:复制一个节点,包括复制节点的内容,属性。
(2) 深拷贝(deep copy): 不光拷贝当前节点,还拷贝所有子节点
浅拷贝: 只拷贝当前节点,不拷贝子节点
(3) 拷贝的节点拥有和原节点一模一样的属性,但会丧失绑定在原节点上的事件。
例子:
var btn = document.querySelector('button');
btn.onclick = function () {
var newBtn = btn.cloneNode(true);
document.body.appendChild(newBtn);
};
V4. insertBefore()方法
描述:本方法用于将一个节点插入到当前节点的指定位置
语法:
var newNode = node.insertBefore(newNode, subNode);说明:
(1) 第一个参数表示想要插入的新节点
(2) 第二个参数表示当前节点的某一个子节点
(3) 本方法在执行结束后,会将新节点作为执行结果返回。根据实际情况不是必须保存。
例子:
var h2 = document.createElement('h2');
h2.innerHTML = '这是h2';
//把h2标签插入到div2节点的前面
var result = div1.insertBefore(h2, div2);
console.log(div1.childNodes);
console.log(result);
v5. removeChild()方法
描述:表示从当前节点中删除某个节点
语法:
var deleteNode = node.removeChild(deleteNode);说明:本方法会返回删除的节点,根据实际情况可以不保存。
例子:
btn.onclick = function () {
if(div1.hasChildNodes()){
div1.removeChild(div1.firstChild);
}else{
alert('已经没有子节点了!');
}
};
V6. replaceChild()
描述:表示将原节点中的某个旧节点,替换为新节点
语法:
var oldNode = node.replaceChild(newNode, oldNode);注意:本方法会返回替换走的旧节点,根据实际情况可以不保存
例子:
btn.onclick = function () {
var textNode = document.createTextNode('已赞');
btn.replaceChild(textNode, btn.firstChild);
btn.setAttribute('disabled', 'disabled');
};
7. contains()方法
描述:用来判断当前节点是否包含参数节点,包含返回true,否则返回false
语法:
node.contains(anotherNode);说明:新创建的节点是被保存在内存中,只要没放到页面上就不被包含在页面内。
例子:
console.log(document.body.contains(div2));
console.log(document.body.contains(div1));
8. isEqualNode()方法
描述:用来判断两个节点是否相等(属性相同,类型相同,子节点相同)
语法:nodeA.isEqualNode(nodeB);
例子:
console.log(div2.isEqualNode(div22));
console.log(div2.isEqualNode(div1));
console.log(span.isEqualNode(span2));
尺寸和位置
1.屏幕的尺寸和位置,通过screen对象获取;
screen === window.screen; //true;
//screen.width 屏幕的像素宽度
console.log('屏幕的宽度---' + screen.width);
//screen.height 屏幕的像素高度
console.log('屏幕的高度---' + screen.height);
//screen.availWidth 屏幕的可用宽度,Windows系统下,通常是去除任务栏宽度值
console.log('屏幕的可用宽度---' + screen.availWidth);
//screen.availHeight 屏幕的可用高度,Windows系统下,通常是去除任务栏的高度值
console.log('屏幕的可用高度---' + screen.availHeight);
//screen.availLeft 屏幕的最左边相对于主屏幕最左边的偏移值
console.log('距离左边的偏移值---' + screen.availLeft);
//screen.availTop 屏幕的最顶边相对于主屏幕最顶边的偏移值
console.log('距离顶边的偏移值---' + screen.availTop);
2.元素的尺寸和位置
页面中所有的元素都有基本的属性,其中有些基本属性与元素的位置和尺寸相关。元素位置相关的属性,都是相对位置,即元素相对于其偏移容器(offsetParent)的偏移量
var ele = document.getElementById("element"); //获取某一个元素对于 offsetLeft 和 offsetTop 这两个值,是相对于偏移容器的。
1. 元素是通过 position 定位的: offsetLeft 和 offsetTop的值,是 left 值和 top 值。
2. 元素是通过 float 或者 margin 定位的: offsetLeft 和 offsetTop 的值,是 margin-left 和margin-top 的值。
3. 如果同时存在,获取的是 left + margin-left 的值
// ele.offsetParent 获取偏移容器
console.log('偏移容器---', ele.offsetParent);
// ele.offsetLeft 元素相对与偏移容器的左边的偏移量
console.log('左边的偏移量---', ele.offsetLeft);
// ele.offsetTop 元素相对于偏移容器的顶边的偏移量
console.log('顶边的偏移量---', ele.offsetTop);clientLeft 和 clienTop
获取元素边框,以像素表示。如果元素的文本内容方向是从右向左,并且元素内容有溢出,比如,<div dir="rtl">hello</div>,这样会在左边产生一个滚动条, 会包含滚动条的宽度,即是滚动条和边框的宽度之和
// ele.clientLeft 通常情况下是元素盒子的左边框的宽度
console.log('元素盒子的左边框宽度---', ele.clientLeft);
// ele.clientTop 通常情况下是元素盒子的顶边框的宽度
console.log('元素盒子的顶边框的宽度---', ele.clientTop);scrollLeft 和 scrollTop
scrollLeft: 表示滚动条到元素左边(横向)的距离,可以用来设置内容区域滚动到某一位置,也可以获取当前滚动条的位置
scrollTop: 表示滚动条到顶边(纵向)的距离,可以用来设置内容区域滚动到某一位置,也可以获取当前滚动条的位置。
// ele.scrollTop 获取滚动条的高度
console.log('获取整个文档滚动条的高度---', ele.scrollTop);
console.log('获取整个文档滚动条的高度---', document.documentElement.scrollTop);
// ele.scrollLeft 获取滚动条的宽度
console.log('获取整个文档滚动条的宽度---', document.documentElement.scrollLeft);
// ele.scrollTop = 50 设置内容区域滚动到50的位置
document.documentElement.scrollTop = 50
console.log('outerWidth:' + window.outerWidth);
console.log('outerHeight:' + window.outerHeight);console.log('innerWidth:' + window.innerWidth);
console.log('innerHeight:' + window.innerHeight);console.log('clientWidth:'+document.documentElement.clientWidth);
console.log('clientHeight:'+document.documentElement.clientHeight);console.log('pageXOffset:'+window.pageXOffset);
console.log('pageYOffset:'+window.pageYOffset);console.log(window.screenX);
console.log(window.screenY);console.log(window.navigator.userAgent);querySelector系列方法与getElementsBy系列方法对比有什么不同?
(i) 两者的W3C标准不同
querySelector 系列属于W3C中的Selectors API(JS)规范
getElementsBy 系列则属于 W3C的DOM 规范。
(ii) 两者浏览器的兼容不同
querySelector 系列基本能被所有浏览器支持。
getElementsBy 系列则通常只有在考虑兼容性的时候才被提起(尽管两者功能近似)
(iii) 接受参数不同
querySelector 系列接收的参数是一个css选择器名。
getElementsBy 系列接收的参数只能是单一的 className、tagName 和 name。
(iv) 返回值不同
querySelectorAll() 返回的是一个静态节点列表(Static NodeList)
getElementsBy 系列的返回的是一个动态节点列表(Live NodeList)。
经典例子:
querySelector系列方法:
// 在循环内,尽管对ul产生了影响,但不会影响到变量list的值。
// 以为list在获取的那一刻值被保存起来,不受影响因此,有多少个li,就循环多少次
// 而通过querySelectorAll得到的这个列表,因为不受影响,因此称为静态节点列表
var ul = document.querySelectorAll('ul')[0];
var list = ul.querySelectorAll('li');
for(var i = 0; i < list.length ; i++){
ul.appendChild(document.createElement('li'));
}
getElementsBy系列方法:
// 在循环内,对ul产生了影响,并立即反映到了list之内。
// 通过getElementsBy系列方法的到的列表,会随着内容的变化而立即产生变化,不用重新赋值
// 那么这种不需要重新赋值,在内容变化后就会立即改变的列表,称为动态节点列表
var ul = document.querySelectorAll('ul')[0];
var list = ul.getElementsByTagName('li');
for(var i = 3; i < list.length ; i++){
ul.appendChild(document.createElement('li'));
}
扩展:框架集(被遗弃了)
框架及布局使用标签为frameset标签,本标签和body标签同级,二者同时只能存在一个!
(1) frameset 标签表示声明一个框架集(页面集合)
rows、cols 属性代表框架集中框架所占的宽高,单位可以是像素或百分比
(2) frame标签表示声明一个框架(页面)
src 属性代表框架要加载的页面的url地址
name 属性表示框架名称
(3) noframes 标签表示不支持框架集布局的页面显示提示信息用
例子:
<frameset rows="20%,*">
<noframes>对不起,您的浏览器不支持本页面布局方式,请更换更厉害的浏览器!</noframes>
<frame src="http://www.baidu.com"/>
<frameset cols="20%,*">
<frame src="leftSide.html"/>
<frame src="" name="rightSide"/>
</frameset>
</frameset>
iframe:内联框架
能够写在body里,和正常的元素一样显示的框架。
通过width,height设置宽高,
通过frameborder设置属性,
通过src设置显示内容
例子:
<a href="http://bbs.bjsxt.com" target="iframeMe">去论坛</a>
<iframe name="iframeMe" frameborder="1" width="500" height="400"></iframe>
事件概述
1.事件
描述:事件本质上是一种交互操作,经常配合函数使用。当事件发生时函数同时执行。
2.事件传递
描述:事件不仅能够和触发者进行交互,还能够在特定的情况下沿着domTree逐级传递,
和domTree中的各个节点进行交互。事件的这种特性称为【事件传递机制】
名词:
(1) (事件真正的)触发者:事件第一次在哪个节点上发生,这个节点就称为是触发者。
(2) 特定情况:domTree中其他节点也绑定了这个事件的情况
类型:
(1) 事件冒泡:事件从最具体的元素开始触发,沿domTree逐级向上传递,直到最不具体的节点停止
(2) 事件捕获:事件从最不具体的节点开始触发,沿domTree逐级向下传递,直到最具体的元素为止。
注意:
如非特殊强调,所有的事件传递都采用事件冒泡!
例子:
btn.onclick = function () {
console.log('事件触发:按钮被点击!');
};
div.onclick = function () {
console.log('事件触发:div被点击!');
};
document.body.onclick = function () {
console.log('事件触发:body被点击!');
};
document.documentElement.onclick = function () {
console.log('事件触发:html被点击!');
};
document.onclick = function () {
console.log('事件触发:document被点击!');
};
事件绑定
1.html事件(html级事件)
描述:绑定操作发生在html代码中的事件,称为 html 事件
语法:
绑定:
on+事件名 = '函数1(); 函数2();...'
移除:
on+事件名 = null
注意:
(1) 所有html事件都采用冒泡传递
(2) 函数执行顺序按照绑定顺序为准
(3) 绑定多个函数的时候,函数应当采用分号隔开,而不是以分号结尾。
弊端:
(1) 耦合性太强
(2) 如果绑定函数未能正确加载,则会在触发事件的时候报错。
例子:
function func1(){ console.log('这是第1个函数'); }
function func2(){ console.log('这是第2个函数'); }
function func3(){ console.log('这是第3个函数'); }
<div onclick="func1(), func2(), func3()"></div>
document.querySelector('div').setAttribute('onclick', null);
2.DOM0事件(DOM0级事件)
描述:在脚本中通过 on+事件名 方式绑定的事件,称为 dom0 事件
语法:
添加:
元素节点.on+事件名 = function(){}
移除:
on+事件名 = null;
注意:
(1) dom0方式绑定的事件均为冒泡事件
(2) dom0方式只能给一个元素节点,一个事件绑定一个执行函数。
如果给一个事件绑定多个执行函数,则取最后绑定的函数为准
弊端:一次只能给一个事件绑定一个函数。
例子:
div2.onclick = function () {
console.log('div2被点击');
};
div2.onclick = function () {
console.log('div2又被点击');
;
div2.onclick = function () {
console.log('div2咋总被点击'); // 只有它生效
};
div2.onclick = null; // 移除点击事件,不是移除这个绑定函数。3.DOM2事件(dom2级事件)
描述:在脚本中通过 addEventListener 函数绑定的事件,称为 dom2 事件
语法:
元素节点.addEventListener(type, listenFunc, useCapture);
参数:
(1) 第一个参数表示绑定事件的类型,没有on!是个字符串!
(2) 第二个参数表示监听函数,就是事件发生的时候执行的那个函数
(3) 第三个参数表示是否采用捕获机制,默认不写 和 false 都代表冒泡机制,true 代表捕获。
注意:dom2 事件允许绑定多个执行函数,并且执行顺序按照绑定顺序执行。
btn.addEventListener('click', function() { console.log('1');});btn.addEventListener('click', function() { console.log('2');});移除:
通过 removeEventListener 函数移除绑定事件
node.removeEventListener('type', 外部函数名, useCapture);注意:匿名函数无法移除,如果dom2事件想要移除,则必须通过外部函数名进行绑定事件。
例子:
function func(){
console.log('div2 的dom2事件函数');
div2.removeEventListener('click',func);
};
div2.addEventListener('click', func);
鼠标事件
描述:通过鼠标操作触发的事件,称为鼠标事件
原则:
(1) 所有鼠标事件如非特殊说明,均为冒泡事件
(2) 可以给一个元素添加多个不同的鼠标事件,多个事件之间互不影响
(3) mouseenter 和 mouseleave 两个事件不冒泡,仅在当前节点触发。
类型:
(1) click 单击事件、dblclick 双击事件
div2.onclick = function () {
console.log('这是div2上的单击事件');
};
div2.ondblclick = function () {
console.log('这是div2上的双击事件');
};
(2) mousedown 按下事件、mouseup 抬起事件、mousemove 移动事件
div2.onmousedown = function () {
div2.style.backgroundColor = 'red';
};
div2.onmouseup = function () {
div2.style.backgroundColor = 'skyblue';
};
div2.onmousemove = function () {
console.log('鼠标移动事件触发');
};
(3) mouseenter 鼠标进入事件、mouseleave 鼠标离开事件 (常用)
div.onmouseenter = function () {
console.log('鼠标进入!');
};
div.onmouseleave = function () {
console.log('鼠标移出!');
};
(4) mouseover 鼠标进入事件(冒泡)、mouseout 鼠标离开事件(冒泡)
div2.onmouseover = function () {
console.log('鼠标进入div2');
};
div2.onmouseout = function () {
console.log('鼠标离开div2');
};
(5) clientX 、clientY
获取鼠标的坐标!并设置div定位属性为鼠标坐标即可。
event.clientX // 鼠标横坐标
event.clientY // 鼠标纵坐标这两个属性在事件绑定的函数内容可以直接使用,但在外部无效,没有单位!!!!!
div.onmouseenter = function (e) { console.log(e.clientX);}文档事件
1. load、error 事件
描述:节点加载成功、节点加载失败之后自动调用的事件。
例子:
在 HTML 中:<body onload="fun1()">
<body onerror="fun1()">
在 JavaScript 中:window.onload=function(){ };
window.onerror=function(){ };2.DOMContentLoaded
描述:页面 DomTree 构建完毕时自动触发
DomTree构建完毕:可以理解为除了外部图片、视频等文件没有加载之外,页面已经加载完毕
3.readystatechange
描述:当页面的readyState加载状态发生改变时,自动触发
4.文档加载顺序
解析HTML结构。
加载外部脚本和样式表文件。
解析并执行脚本代码。
DOM树构建完成。// DOMContentLoaded执行
加载图片等外部文件。
页面加载完毕。 // load执行
例子:
// 页面处于刚开始加载的状态
console.log(document.readyState);
// 给页面添加readyStateChange事件,当文档状态改变时自动触发
document.addEventListener('readystatechange', function () {
console.log('文档加载状态发生改变:当前状态为:' + document.readyState);
});
//给页面添加DOMContentLoaded事件,当文档domTree构建完毕时自动触发
document.addEventListener('DOMContentLoaded', function () {
console.log('文档DOM已经构建完毕');
});
//页面彻底加载完成时触发
window.onload = function () {
console.log('文档彻底加载完毕');
};
//图片资源加载完毕后,自动触发
document.querySelector('img').onload = function () {
console.log('图片加载完毕!');
};
焦点事件
描述:焦点事件分为获得焦点事件 focus 和 失去焦点事件 blur
分别会在元素节点获得焦点和失去焦点时自动触发
语法:
获得焦点事件:
元素节点.onfocus = function(){}
失去焦点事件:
元素节点.onblur = function(){}注意:
(1) 焦点事件可以使用dom0绑定也能使用dom2绑定。
(2) 焦点事件不支持冒泡传递。
例子:
var input = document.querySelector('input');
input.onfocus = function () {
console.log('获得了焦点');
};
input.onblur = function () {
console.log('失去了焦点');
};
滚动事件scroll
描述:滚动事件是指当页面 或 元素发生滚动时,自动调用的事件
(1) 页面滚动事件
内容:scrollTop、scrollLeft 表示页面的滚动距离(没有单位)
语法:
document.documentElement.scrollTop \ scrollLeft注意:页面滚动距离不仅能够读取,还能够设置。
例子:
// 点击按钮,滚动到1000的距离document.querySelector('button').onclick = function () { document.documentElement.scrollTop = 1000;};// 给文档添加滚动事件,当文档滚动时本事件自动发生。window.onscroll = function () { // 滚动事件调用一次,就输出一次滚动距离 console.log(document.documentElement.scrollTop);};
(2)元素滚动事件
描述:元素发生滚动时,自动调用的事件
内容:获取元素的滚动距离
元素节点.scrollTop \ scrollLeft注意:元素滚动如果想要发生,那么元素至少应该存在滚动条
例子:
button.onclick = function () {
// 让div回到顶部
div.scrollTop = 0;
};
键盘事件
描述:由用户操作键盘触发的事件称为键盘事件
注意:键盘事件采用冒泡传递。
说明:一般情况下键盘事件会绑定给 input 或者 textarea 元素,但是因为键盘事件支持冒泡机制,因此直接绑定给 body 也是可以的。
类型:
(1 ) keydown:键盘按键在按下时触发的事件。如果按住不放则连续触发。
(2) keyup:键盘按键在抬起时触发的事件。
(3) keypress:键盘在按下(可显示的)按键时触发的事件,如果按住不放则连续触发, 能够识别大小写
(4) keyCode : 在键盘事件中获取按下按键的编码值
例子:
document.body.onkeydown = function () {
console.log('keydown:' + event.keyCode);
};
document.body.onkeyup = function () {
console.log('键盘已抬起!')
}
document.body.onkeypress = function () {
console.log('keypress:' + event.keyCode);
};
触摸事件
描述:在移动端设备中由触摸操作触发的事件,称为触摸事件
注意:触摸事件在PC端不生效
类型:
(1) touchstart 当手指触摸屏幕时触发;即使已经有一个手指放在了屏幕上也会触发。
(2) touchmove 当手指在屏幕上滑动时连续的触发。
(3) touchend 当手指从屏幕上移开时触发。
(4) touchcancel 当系统停止跟踪触摸时触发,如电话接入或者弹出信息,一般在这个操作中来做一些暂停游戏类的操作
强调:
(1) 如非特殊说明,事件均为冒泡事件
(2) 手机触摸事件必须使用dom2来进行绑定
(3) 可以给一个元素添加多个触摸事件
例子:
document.body.addEventListener('touchstart', function () {
console.log('touchstart----触摸到一个 DOM 元素时触发');
});
document.body.addEventListener('touchmove', function () {
console.log('touchmove-----滑动时触发');
});
document.body.addEventListener('touchend', function() {
console.log('touchend从一个 DOM 元素上移开时触发');
});
2.获取触摸点的坐标
这三个事件又分别对应三个相同的触摸列表:
touches:正在触摸屏幕的所有手指的一个列表
targetTouches:正在触摸当前 DOM 元素上的手指的一个列表
changedTouches:涉及当前事件的手指的一个列表。
document.body.addEventListener('touchstart', function () { console.log(event.touches); console.log(event.targetTouches); console.log(event.changedTouches);});事件返回的 TouchList 列表。它对应的就是前面提到的三种事件(touchstart、touchmove、touchend)中的一种,在触发时生成的一个对象列表。列表里最有用的就是 Touch 对象了,Touch 对象里存放着对应事件的一些相关的信息,我们就是通过这种个事件里这些属性的有机结合来实现各种效果,都是只读属性!
TouchList {0: Touch, length: 1}
length:1
0:Touch
clientX:65 // 触摸点在浏览器窗口中的横(x)坐标
clientY:18 // 触摸点在浏览器窗口中的纵(y)坐标
force:1 // 触摸点压力大小
identifier:0 // 触摸点唯一标识(ID),可以根据它来判断跟踪的是否是同一次触摸过程
pageX:65 // 触摸点在页面中的横坐标
pageY:18 // 触摸点在页面中的纵坐标
radiusX:11.5 // 触摸点椭圆的水平半径
radiusY:11.5 // 触摸点椭圆的垂直半径
rotationAngle:0 // 旋转角度
screenX:560 // 触摸点在屏幕中的横坐标
screenY:175 // 触摸点在屏幕中的纵坐标
target:div#touchLog 触摸目标
__proto__:Touch
__proto__:TouchList通过上面的 radiusX,radiusY,rotationAngle 这三个属性就可以计算出你的手指触摸手机屏幕时的一个接触面,只不过这个接触面是用一个近似的椭圆来表示,也就是说它不是一个真正意义上的接触面,而是一个大概的接触面。相信心细的朋友应该会看到 TouchList 对象里有一个 length 属性,并且它的值为 1 ,这说明当前只有一个手指触发了事件(比如:touchstart 事件),换句话说,此时你只有一个手指放到了手机屏幕上,这个手指对应的一些信息存放在 Touch 对象里。因为只有一个手指放在了屏幕上,所以这个 TouchList 里只有一个 Touch 对象,并且是第一个下标为 0 。TouchList 列表里还有一个 target 属性,这个应该很好理解,就是触摸的目标。
this对象
(1) 对于直接调用来说,不管函数被放在了什么地方, this 一定是 window对于
(2) 对象中的函数来说,谁调用了函数,谁就是 this
(3) 对于 new 的方式来说, this 被永远绑定在了对应 new 上面,不会被任何方式改变 this
(4) this在闭包中:闭包中的 this 指向window
(5) 延时器和定时器调用中的 this 指向window
(6) 事件中的this:
HTML:this 指向 window
DOM0:this 指向绑定该事件的元素
DOM2级:this 指向绑定该事件的元素
(7) 自执行函数: this 指向 window
(8) call 和 apply 和 bind 函数:第一个参数是谁,this指向谁
(9) 箭头函数里面的 this 在它申明时确定,跟他当前作用域的 this 一样
(10) 严格模式下,函数里面的 this 指向 undefined,函数外面(全局作用域)的this还是指向window
1. fn()
this => window
2. obj.fn()
this => obj
3. fn.call(xxx)
this => xxx
4. fn.bind(xxx)
this => xxx
5. fn.apply(xxx)
this => xxx
6. new Fn()
this => 新的对象
7. fn=()=>{}
this => 外面的this
event对象
描述:当 domTree 中某个事件发生时,
同时【自动产生】的一个用来描述【事件发生时所有信息】的对象,称为事件对象。
获取:
(1) 在脚本中直接通过关键词event来获取
btn.onclick = function () {
console.log(event); // MouseEvent {....}
console.log(typeof event); // object
};(2) 在添加事件监听时,通过绑定函数传参形式获取。一般形参为e或者eve.
注意:event 对象实际上是 window 浏览器对象的一个属性,因此在外部也能直接使用。
只不过在事件之外访问的时候没有内容,是空值没意义,因此习惯上还是在事件函数内部使用。
btn.onclick = function (e) {
console.log(e); // MouseEvent {isTrusted: true, screenX: 21, screenY: 113, clientX: 21, clientY: 19, …}altKey: falsebubbles: truebutton: 0buttons: 0cancelBubble: falsecancelable: trueclientX: 21clientY: 19composed: truectrlKey: falsecurrentTarget: nulldefaultPrevented: falsedetail: 1eventPhase: 0fromElement: nullisTrusted: truelayerX: 21layerY: 19metaKey: falsemovementX: 0movementY: 0offsetX: 11offsetY: 7pageX: 21pageY: 19path: (5) [button, body, html, document, Window]relatedTarget: nullreturnValue: truescreenX: 21screenY: 113shiftKey: falsesourceCapabilities: InputDeviceCapabilities {firesTouchEvents: false}srcElement: buttontarget: buttontimeStamp: 603.3699996769428toElement: buttontype: "click"view: Window {parent: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}which: 1x: 21y: 19__proto__: MouseEvent
console.log(event); // MouseEvent {isTrusted: true, screenX: 21, screenY: 113, clientX: 21, clientY: 19, …}altKey: falsebubbles: truebutton: 0buttons: 0cancelBubble: falsecancelable: trueclientX: 21clientY: 19composed: truectrlKey: falsecurrentTarget: nulldefaultPrevented: falsedetail: 1eventPhase: 0fromElement: nullisTrusted: truelayerX: 21layerY: 19metaKey: falsemovementX: 0movementY: 0offsetX: 11offsetY: 7pageX: 21pageY: 19path: (5) [button, body, html, document, Window]relatedTarget: nullreturnValue: truescreenX: 21screenY: 113shiftKey: falsesourceCapabilities: InputDeviceCapabilities {firesTouchEvents: false}srcElement: buttontarget: buttontimeStamp: 603.3699996769428toElement: buttontype: "click"view: Window {parent: Window, postMessage: ƒ, blur: ƒ, focus: ƒ, close: ƒ, …}which: 1x: 21y: 19__proto__: MouseEvent
};
event对象的常用属性和方法
(1) type 属性
描述:表示发生的事件类型,本属性只读
语法:
event.type
(2) bubbles 属性
描述:用来获取当前触发的事件是否支持冒泡,支持返回true,不支持返回false。
语法:
event.bubbles例子:
btn.onclick = function (e) {
console.log(e.bubbles); // true
e.stopPropagation(); //阻止事件传播
};
(3) eventPhase 属性
描述:获取事件传导至当前节点时,所处于的状态
说明:本属性为只读属性,有三个可能值
返回 1 表示事件在当前节点处于捕获状态
返回 2 表示当前节点是事件的真正触发者
返回 3 表示事件在当前节点处于冒泡状态
例子:
// 冒泡状态
btn.onclick = function (e) {
console.log('冒泡状态btn:' + e.eventPhase);
};
document.body.onclick = function (e) {
console.log('冒泡状态body:' + e.eventPhase);
};
document.onclick = function (e) {
console.log('冒泡状态document:' + e.eventPhase);
};
// 捕获状态
btn.addEventListener('click', function (e) {
console.log('捕获状态btn:' + e.eventPhase);
}, true);
document.body.addEventListener('click', function (e) {
console.log('捕获状态body:' + e.eventPhase);
}, true);
document.addEventListener('click', function (e) {
console.log('捕获状态document:' + e.eventPhase);
}, true);
v(4) target 属性
描述:获取事件的真正触发者。
语法:eve.target
注意:在现在阶段,事件内部可以认为 eve.target 等同于 this 的作用。
例子:
btn.onclick = function (e) {
console.log(e.target) // 返回 btn
}
v(5) currentTarget 属性
描述:获取事件的监听者(当前触发者)
语法:eve.currentTarget
注意:事件在哪个节点触发,currentTarget 属性就是谁
例子:
btn.onclick = function (e) {
console.log(e.currentTarget) // 返回 btn
}
v(6) stopPropagation() 方法
描述:能够阻断事件从当前节点传播到下一个节点。
语法:
eve.stopPropagation();例子:
document.body.onclick = function (e) {
e.stopPropagation();
};
v(7) preventDefault ()
描述:能够阻断(取消)当前节点的默认行为
语法:
eve.preventDefault();例子:
var anchor = document.querySelector('a');
anchor.onclick = function (e) {
e.preventDefault();
};
v(8) cancelable 属性
描述:用来判断当前节点能否取消默认行为,true表示能够取消
语法:
eve.cancelable例子:
div2.onclick = function (e) {
if( e.cancelable ){
e.preventDefault();
}else{
console.log('当前节点不存在默认行为,无需取消!');
}
};
BOM概述
描述:bom是浏览器对象模型(browser Object model),是由一组对象构成的规则。
注意:bom的核心对象是window对象,window对象相当于浏览器窗口
说明:
(1) BOM包括了DOM
(2) BOM处理页面之间的交互,而DOM处理页面之内的交互。
(3) BOM没有统一的规则
window对象
1.window对象
描述:window对象可以理解为浏览器窗口
注意:所有定义在全局作用域中的变量、函数都会变成window对象的属性和方法,
在调用的时候可以省略window。
2.window的常见属性和方法
(1) window.name
描述:是一个在页面切换之后,甚至域名变更之后仍然会存在的容器。
说明:借助window.name可以实现页面与页面之间的数据传递,称为【跨域传输】
例子:
//如果想要获取一个页面内的信息,那么这个页面必须加载。
var btn = document.querySelector('button');
btn.onclick = function () {
var iframe = document.createElement('iframe');
iframe.src = '(3)anotherPage.html';//加载保存了信息的页面
iframe.style.display = 'none';
document.body.appendChild(iframe);
//当iframe加载完毕,意味着window.name的内容已经被赋值完毕了
iframe.onload = function (eve) {
var iframeWindowName = eve.target.contentWindow.name;
eval(iframeWindowName);
console.log(num);
}
};浏览器中的警示框
1. alert() 方法
描述:alert() 是window提供的一个,用来提示用户信息的方法。
语法:
alert(string);注意:
(1) 本方法没有返回值(返回值是undefined)
(2) alert() 方法弹出的对话框是模态对话框,在对话框关闭之前程序暂停,直到关闭后才继续执行
例子:
alert('提示信息!');
2. prompt() 方法
描述:prompt() 也是 window 提供的一个,用来提示并收集用户信息的方法
语法:
prompt(text, defaultText);
// text 可选, 要在对话框中显示的纯文本// defaultText 可选, 默认要输入文本(1) 如果直接点击取消按钮,则返回null注意:
(2) 如果有默认参数并直接点确定,则返回默认参数。如果输入内容则返回输入的内容。
(3) 如果没有默认参数并直接点确定,则返回空字符串。如果输入内容则返回输入内容。
(4) prompt() 方法弹出的对话框是模态对话框,在对话框关闭之前程序暂停,直到关闭后才继续执行
例子:
btn.onclick = function () {
let result = prompt('你是who?');
console.log(result);
}
3. confirm() 方法(最常见)
描述:window 提供的一个用来提示用户信息的方法
语法:
confirm(text);// text 可选,要在对话框中显示的纯文本
注意:
(1) 点击确认按钮返回true,取消按钮返回false
(2) confirm() 方法弹出的对话框是模态对话框
例子:
btn.onclick = function () {
let result = confirm('是否要删除?');
console.log(result);
}
定时器 / 延迟器
1. 间隔调用 (定时器)
描述:本方法的特征是能够自动每间隔一定时间,调用一次指定函数。
语法:
var timer = null;
timer = setInterval(间隔调用的函数,执行函数的间隔ms);
移除:
clearInterval()例子:
var timer = null;
timer = setInterval(function(){
console.log('hi,nimabi');
},2000);
// es6 箭头函数写法(推荐)
timer = setInterval(() => {
console.log('hi,nimabi');
}, 1000)
// clearInterval(timer); 扩展:
(1)setInterval 方法放回的是一个数字队列,创建定时器的序号。
清除定时器的时候可以直接通过数字队列来清除定时器。
例子1:
setInterval(function(){ console.log('hi,1'); }, 2000);
setInterval(function(){ console.log('hi,2'); }, 2000);
setInterval(function(){ console.log('hi,3'); },2000);
// 清除第一个和第二个
clearInterval(1);
clearInterval(2);
(2)如果使用间隔调用的函数是一个带参函数,则声明部分需要采用下列的方式。
例子:
var timer = null;
function showWord(abc){
console.log(abc);
};
timer = setInterval('showWord("你好")',2000);
(3) 在定时器内部,函数的真正调用者是 window
使用箭头函数,它的 this 继承上级的 this
var timer = null;
setInterval(function(){
console.log(this); // window
},2000);
setInterval(() => {
console.log(this); // 继承上级的 this
},2000);
(4) 定时器在创建完毕后不会立刻开始执行,而是会等待【任务队列中任务执行完毕】之后在开始执行。
var timer1 = null;
timer1 = setInterval(function(){
console.log('hi1');
},2000); //后
console.log(timer1); //先
2. 延迟调用 (延迟器)
描述:表示函数等待一定时间后在执行
说明:除了语法结构和表示的含义不同之外,其余注意事项全和定时器一样
语法:
var timer = null;
timer = setTimeout(间隔调用的函数,执行函数的间隔ms);例子:
var timer = null;
timer = setTimeout(function(){
console.log('这是一个延迟调用');
} , 2000);
移除:
clearTimeout (延迟器表示);
页面加载顺序
1.defer
让这个外部脚本在dom加载完毕后,在加载
避免了因外部引入文件过大或网络卡顿造成的【文件阻塞】
<script src="js/myJs.js" defer></script>2.async
让外部脚本和dom同时加载,异步执行
弊端:不能确定谁先加载完成。
<script src="js/myJs.js" async></script> 3.以上两个script的属性,仅对外部脚本生效。
回流和重绘
1.重绘(repaint) 和 回流(reflow)
描述:
重绘:页面中元素发生可见性的变化,导致页面重新渲染的现象称为重绘
回流:页面中元素发生位置或尺寸的变化,导致部分页面或整个页面重新加载的现象称为回流
说明:
(1) 回流必将引起重绘,但重绘不一定引发回流
(2) 这两个现象都是浏览器加载页面时可能导致加载变慢的问题,要尽可能的避免
2.减少回流和重绘的途径
描述:因为页面中各种操作基本都会引发回流和重绘,因此完全避免是不可能的。
所以为了提高浏览器性能,我们要尽可能的减少引发他们的状况。
途径:
(1) 不要一项一项的去改变样式,尽可能一口气写完。(可以写在一起,不要被打断就行)
最好使用 .style 或者 .style.cssText
(2) 读写dom操作尽量放在一起
(3) 当大量读写dom操作无法避免的时候,可以使用文档碎片节点doucmentFragment来解决问题。
(4) 使用fixed和absolute能够减少回流和重绘
window.history对象
描述:表示页面栈对象
说明:栈区特征为【后进先出】,堆区特征为【先进先出】。
内容:
(1) window.history.back() 跳转到栈中的上一个页面
(2) window.history.forward() 跳转到栈中的下一个页面
(3) window.history.go(num) 跳转到栈中的指定页面
(4) window.history.length 栈中页面的数量
注意:
通过window.history对象中提供的方法进行的页面跳转并不会向栈中添加新的页面。
而通过window.location.href或者通过a标签进行的跳转,则会向栈中添加新的页面。
补充:
栈区特征是【后进先出】,不仅仅意味着后添加的内容先被移除栈,
还意味着栈中的内容如果想要添加到指定位置,必须先将其之前的内容先退栈才行!
call 、bind 、 apply 更改 this 指向
apply 第一个为this指向,后面的都是所带的参数(参数都必须放在一个数组里)
.apply(this指向, ['参数'...])call 第一个为this指向,后面的都是所带的参数
.call(this指向, '参数'...).bind(this指向, '参数'...)()例子:
let name = '王子成';
let age = 20;
var A = '我是外面的哈哈哈'; // 用 let 定义对象里面无法获取
const obj = {
name: 'obj-wzc',
age: 10,
A: '我是obj的哈哈哈',
B: this.A,
myFun1 (b) {
console.log(`${this.name}的年龄是${this.age}, A:${this.B}, 用的方法${b}`)
},
myFun2 (a, b) {
console.log(`${this.name}的年龄是${this.age},他来自${a}, 用的方法${b}`)
}
};
const db = {
name: '狗子',
age: 20
};
obj.myFun1('直接调用'); // obj-wzc的年龄是10,他来自中国, 用的方法直接调用
obj.myFun2.call(db, '中国', 'call()'); // 狗子的年龄是10,他来自中国, 用的方法call()
obj.myFun2.bind(db, '中国', 'bind()')(); // 狗子的年龄是10,他来自中国, 用的方法bind()
obj.myFun2.apply(db, ['中国', 'apply()']); // 狗子的年龄是10,他来自中国, 用的方法apply()
闭包
描述:本质上是一种将【函数内部】和【函数外部】连接起来的手段
作用:
(1) 允许在函数外部,访问函数内部的局部变量。
(2) 将局部变量的生存周期延长至全局作用域,避免被垃圾回收机制杀死。
注意:
(1) 不要滥用闭包,因为可能导致变量内存不释放从而导致内存泄露
(2) 闭包的实际调用者都是window,所以闭包中的this均指向了window
例子:
function func() {
var num = 999;
return function () {
console.log(num);
};
}
var result = func();
result(); // 999
类和对象
描述:
(1) 类是一种抽象的,并不实际存在的,表示一种事物共有特征的描述。
(2) 对象是一种具体的,实际存在的,类中的某一个个体。
JS中通过构造函数的帮助制定类。通过【new命令调用构造函数】创建类中的对象
语法:
function 类名 (对象属性值1,对象属性值2,...){
this.对象属性1 = 对象属性值1;
this.对象属性2 = 对象属性值2;
...
}
var 对象 = new 类名(实际属性1,实际属性2,...);作用:
快速构建对象,不必每次创建对象都重新编写对象结构。
例子:
function People(pname, page, pheight, pabilibty){
this.userName = pname;
this.userAge = page;
this.userHeight = pheight;
this.userAbility = pabilibty;
}
var frank = new People('张先森', '18', '180', function () {console.log('变得帅');});
console.log(frank); // People {userName: "张先森", userAge: "18", userHeight: "180", userAbility: ƒ}
面向过程思想与面向对象思想
1.面向过程思想
描述:解决问题围绕【如何解决】来开展编程,核心是找到解决问题的方法(函数)
2.面向对象思想
描述:解决问题围绕【谁能解决】来开展变成,核心是找到解决问题的对象
说明:JS本身是面向过程的语言,只不过为了解决面向对象的问题,提出了各种手段来模拟面向对象
3.面向对象中,对象的特征:“公有、私有”
公有:对象中的属性和方法,在对象外部能够直接访问,这样的属性和方法就称为公有属性和公有方法
私有:对象中的属性和方法,仅能在对象内部访问,在对象外不不能直接访问,需要通过特权函数才能访问,这样的属性和方法称为私有属性和私有方法
特权函数:在JS中对象能够用来访问内部局部变量的函数,使用特权函数来模拟私有的赋值调用过程
例子:
function People(pname, pability){
//JS用局部变量来模拟私有属性和私有方法
var secret = '梦';
this.getSecret = function () {
console.log(secret);
};
//公有属性
this.pname = pname;
this.pability = pability;
}
var frank = new People('张先森', function () {
console.log('吃了睡睡了吃');
});
//公有属性和公有方法能够在对象之外直接访问
console.log(frank.pname); // 张先森
frank.pability(); // 吃了睡睡了吃
//私有属性不能在对象之外直接访问,私有方法可以
console.log(frank.secret) // undefined
frank.getSecret(); // 梦
原型
描述:原型 prototype 是 JS 为函数提供的一个对象类型的属性。
说明:向原型中添加的属性和方法,能够被【由类创建的对象】共同拥有。
注意:本属性不需要手动添加,prototype 属性自动被所有的函数拥有,直接使用就可以。
本质:本质上原型的存在就是为了给类的对象添加公有属性
补充:
JS中提供了一种属性访问机制
(1) 如果是通过类创建的对象,在访问属性的时候会先去对象本身内查找。
(2) 如果没有找到,则会去【创建这个对象的类】的原型中查找。
如果在原型内找到了这个属性,也相当于这个对象拥有这个属性。
语法:
function 类名(公有属性值1,公有属性值2,...){
var 私有属性名1:'私有属性值1',
var 私有方法1:function (){},
this.公有属性名1:公有属性值1,
this.公有属性名2:公有属性值2,
...
}
类名.prototype.公有属性3 = 公有属性值3;例子:
function People(pname, page, pability) {
//私有属性
var secret = '梦';
//公有属性(大家都有的,但是内容不相同的公有属性)
this.pname = pname;
this.page = page;
this.pability = pability;
//特权函数(特权函数实际上也是公有的,只不过特殊之处在于能够读写私有属性)
this.getSecret = function () {
return secret;
};
this.setSecret = function (newSecret) {
secret = newSecret;
};
}
//公有属性(大家都有的,而且内容都一样的公有属性)
var frank = new People('张先森', 18, function () {
console.log('我能白话!');
});
console.log(frank.pname); // 张先森
console.log(frank.page); // 18
frank.pability(); // 我能白话!
frank.setSecret('成为刘诗诗的老公!');
console.log(frank.getSecret()); // 成为刘诗诗的老公!
People.prototype.eyesNum = 2;
console.log(frank.eyesNum); // 2
2.原型相关的知识
结构:JS为原型提供了两个默认的属性
(1) constructor 构造器:指向这个类本身(指明了原型归哪个类所有)
(2) __proto__ 原型指向:指向这个原型本身,提供给【类创建的对象】使用。
弊端:原型中不能保存数组这类引用类型的数据,
因为地址传递的问题会导致出现修改的连锁变化
例子:
function fun1 () {};
// 构造器
console.log(fun1.prototype.constructor); // f ()
// 原型指向
console.log(fun1.__proto__); // ƒ () { [native code] }
console.log(fun1.__proto__ === Function.prototype); // true
原型链
描述:【对象的__proto__属性】和【对象的构造函数的原型的__proto__属性】
构成的链式结构称为原型链
白话:对象的原型,跟他父类的原型绑在一起,拧成一根链子。那么这根链子就称为原型链
注意:
(1) 原型链的顶端是Object
(2) Object类的原型(Object.prototype)没有__proto__属性。
作用:
访问对象的属性的时候,先在对象本身中查找;
如果在对象中没能找到这个属性,则会沿着原型链逐级向上查找,
在原型链的任何一级如果找到这个属性,都视同对象拥有这个属性。
-------被称为是【继承】
构建:设置子类的prototype属性是父类的实例,即可构建原型链
例子:
// 构建原型链的代码
// 创建一个类,添加一个公有属性叫money
function Father() { }
Father.prototype.money = '数不清';
var mayun = new Father();
//创建一个类,并将prototype属性赋值为Father类的一个对象
function Son() { }
Son.prototype = mayun;
//创建一个Son类的对象
var frank = new Son();
console.log(frank.money); // 数不清
设计模式
1.工厂模式
弊端:创建的对象无法确定归属于哪一个类
例子:
function Car(lun1, lun2, lun3, lun4, ability) {
var car = {};
car.lun1 = lun1;
car.lun2 = lun2;
car.lun3 = lun3;
car.lun4 = lun4;
car.ability = ability;
return car;
}
var car1 = Car('左前轮1', '右前轮1', '左后轮1', '右后轮1', '会跑1');
console.log(car1 instanceof Car); // false
console.log(car1); // {lun1: "左前轮1", lun2: "右前轮1", lun3: "左后轮1", lun4: "右后轮1", ability: "会跑1"}
2.构造函数模式
弊端:面对共有的,属性相同的公有属性,没办法一次写清,必须每次都为这个属性分配内存。
例子:
function Car(lun1, lun2, lun3, lun4, ability) {
this.lun1 = lun1;
this.lun2 = lun2;
this.lun3 = lun3;
this.lun4 = lun4;
this.ability = ability;
}
var car1 = new Car('前左轮1', '前右轮1', '后左轮1', '后右轮1', '能开1');
console.log(car1 instanceof Car); // true
3.原型模式
弊端:省内存到极致的问题就是,面对不同属性值的公有属性时,反而增加了内存的负担
例子:
// 构造函数
function Person() { };
Person.prototype.name = '张三';
Person.prototype.sayName = function () {
console.log(this.name);
};
let person1 = new Person();
person1.sayName(); //张三
let person2 = new Person();
person2.sayName(); // 张三
console.log(person1.sayName == person2.sayName); //true
4.混合模式
弊端:没办法在每一个领域做到完美
例子:
function Car(lun1, lun2, lun3, lun4) {
this.lun1 = lun1;
this.lun2 = lun2;
this.lun3 = lun3;
this.lun4 = lun4;
}
Car.prototype.ability = function () {
console.log('爷会飞');
};
var car1 = new Car('左前轮1', '右前轮1', '左后轮1', '右后轮1');
var car2 = new Car('左前轮2', '右前轮2', '左后轮2', '右后轮2');
car1.ability(); // 爷会飞
car2.ability(); // 爷会飞
5.动态原型模式
// 懒加载:使用的时候才加载并占有内存,不使用的时候就相当于不存在。
function Car(lun1, lun2, lun3, lun4) {
this.lun1 = lun1;
this.lun2 = lun2;
this.lun3 = lun3;
this.lun4 = lun4;
// Car中没有_initialized时
if (typeof Car._initialized == 'undefined') {
// 原型中的内存仅会在调用函数的时候才被占用,如果函数一直不被使用,则原型就一直不会占有内存。
Car.prototype.ability = function () {
console.log('爷会飞');
};
Car._initialized = true;
}
}
var car1 = new Car(['左前轮1', '右前轮1', '左后轮1', '右后轮1']);
var car2 = new Car(['左前轮2', '右前轮2', '左后轮2', '右后轮2']);
car1.ability() // 调用时它才会占用
正则表达式
描述:正则表达式是一种检索字符串的规则,经常表现为字符串的样子
语法:
/正则表达式主体/修饰符(可选)本质:正则表达式本质上是对象类型,只不过表现为字符串的样子
例子:
// 规则:检索frank字符串
var reg1 = /frank/;
//规则:忽略大小写的,检索frank字符串
var reg2 = /frank/i;
console.log(typeof reg1); // object
console.log(typeof reg2); // object
修饰符
描述:修饰符是检索字符串时规则的制定者之一,修饰符表示应当按照何种规则进行检索。
类型:常见的修饰符有三种 i g m
说明:
(1) i 修饰符:代表了【忽略大小写】的规则
(2) g 修饰符:代表了【全局匹配】的规则
(3) m 修饰符:代表了【换行匹配】的规则,对^$字符有影响。
正则表达式的用法
(1) search() 方法
描述:正则表达式在 search 中表示制定规则,让 search 在字符串中检索【符合正则制定的规则】的字符串
a. 如果找到返回第一次出现的下标
b. 如果查找失败,返回-1
例子:
var str = 'hello World! goodbye world!';
var index = str.search(/world/i);
console.log(index); // 6
(2) replace() 方法
描述:让 replace 根据参数一的规则进行查找,并将【满足规则一的所有内容】替换为参数二
强调:replace 方法本身不会改变原字符串,而是会生成一个新的字符串
例子:
var str = 'hello World! goodbye world!';
var newStr = str.replace(/world/gi, '(frank)');
console.log(newStr); // hello (frank)! goodbye (frank)!
console.log(str); // hello World! goodbye world!
(3) match() 方法
描述:
(a.) match 能够匹配,符合参数规则的字符串第一次出现的信息
var str = 'hello World! goodbye world!';
var info = str.match(/world/i);
console.log(info); // ["World", index: 6, input: "hello World! goodbye world!", groups: undefined](b.)
match 能够匹配【所有符合参数规则的子字符串】,并构成集合返回
var str = 'hello World! goodbye world!';//只有存在修饰符g的时候,match才会返回集合var info = str.match(/world/gi);console.log(info); // (2) ["World", "world"]检索模式
描述:检索模式是指【正则表达式主体】可以采用何种方式编写,也是规则的制定者之一
类型:表达式模式、元字符模式、量词模式
注意:
a.检索模式中的几种模式可以混合使用,来达到精确制定规则的效果
b.在正则主体当中一个[]中括号代表一个字符,一个()小括号代表一个词组
(1) 表达式模式
描述:表达式模式是指【通过表达式书写来制定检索规则】的方式
类型:[abc]、[0-9]、(m|n)
(a.) [abc]模式
描述:本模式代表的规则是【存在于方括号中,即满足】
注意:本模式是针对于正则主体使用的,因此中括号必须写在正则主体中才生效
例子:
// 规则为:全局中忽略大小写检索单个字符,单个字符只要是 (a 或者 b) 之一即满足
var str = '12abc12ABC';
var newStr = str.replace(/[ab]/gi,'(frank)');
console.log(newStr); // 12(frank)(frank)c12(frank)(frank)C
// 规则为:全局中忽略大小写检索两个挨在一起的字符
// 第一个必须是 (1 或者 2),第二个必须是 (a 或者 b)
var str = '12abc12ABC';
var newStr = str.replace(/[12][ab]/gi,'(frank)');
console.log(newStr); // 1(frank)bc1(frank)BC
(b.) [0-9]模式
描述:本模式代表的规则是【存在于范围内,即满足】
注意:范围前面的必须小于后面的,否则会报错!
例子:
// 规则为:全局中忽略大小写检索两个挨在一起的字符
// 第一个必须是 (1 或者 2),第二个必须是 0-9 的数字var str = '137abc125abc';
var newStr = str.replace(/[135][0-9]/gi,'(frank)');
console.log(newStr); // (frank)7abc(frank)5abc
(c.) (m|n)模式
描述:本模式代表的规则是【符合以|分隔的选项之一,即满足】
注意:本模式可以匹配的不仅仅是字符,还可以是词组
例子:
// 规则为:全局中忽略大小写检索挨在一起的字符或者词组
// ab 或者 ABC
var str = '12abc12abABC';
var newStr = str.replace(/(ab|ABC)/g,'(frank)');
console.log(newStr); // 12(frank)c12(frank)(frank)(2)元字符模式
描述:元字符模式是指通过元字符进行字符串检索的模式
类型:\d、\s、\b、\w、\W、...
注意:一个元字符代表一个字符
(a.) \d元字符
描述:\d代表的规则是【是数字,即满足】
例子:
var str = '12abc12abABC';
var newStr = str.replace(/\d/g,'(frank)');
console.log(newStr); // (frank)(frank)abc(frank)(frank)abABC
(b.) \s元字符
描述:\s代表的规则是【是空格,即满足】
例子:
var str = ' 12abc 12ab ABC ';
var newStr = str.replace(/\s/g,'(frank)');
console.log(newStr);//(frank)12abc(frank)12ab(frank)ABC(frank)
(c.) \b元字符
描述:\b代表的规则是【是词语边界,即满足】
例子:
var str = '12abc 12ab ABC';
var newStr = str.replace(/\b/g,'(frank)');
console.log(newStr); // (frank)12abc(frank) (frank)12ab(frank) (frank)ABC(frank)(d.) 其他:
. 匹配任何单个字符,除了换行
\D 非数字
\S 非空白
\w 数字 字母 下划线 \W 非 [0-9a-zA-Z_]
\n 换行
\t 制表符
(3)量词模式
描述:通过设置量词进行内容检索的模式称为量词模式
量词:能够描述内容出现次数的词语(+\*\?)
注意:量词通常不单独作为正则主体,而是会配合其他模式一起使用。
强调:量词只对其前面第一个字符生效!!!!!!!!!!!!!!!!!!!!!
类型:n+、n*、n?
(a.) n+量词模式
描述:n+代表的规则是【存在一个或多个n,即满足】
规律:n+量词在匹配的时候实际上是,能匹配多少就匹配多少,直到不满足才停止。
例子:
var str = 'a1abb2ab3baab';
var newStr = str.match(/a+/g);
console.log(newStr); // ["a", "a", "a", "aa"]
var str = '1234abc';
var list = str.match(/\d+/g);
console.log(list); // 1234
(b.) n*量词模式
描述:n*代表的规则是【存在零个或多个n,即满足】
规律:n*量词在匹配的时候实际上是,能匹配多少就匹配多少,直到不满足才停止。
例子:
var str = 'a1abb2ab3baab'; var newStr = str.match(/b*/g); console.log(newStr); // (13) ["", "", "", "bb", "", "", "b", "", "b", "", "", "b", ""]
(c.) n?量词模式
描述:n?代表的规则是【存在零个或一个n,即满足】
规律:n?量词在匹配的时候实际上是,能匹配多点就匹配多点,只要一满足就立即结束。
例子:
var str = 'a1abb2ab3baab';
var newStr = str.match(/b?/g);
console.log(newStr); // (14) ["", "", "", "b", "b", "", "", "b", "", "b", "", "", "b", ""]
正则RegExp对象
描述:JS为正则表达式提供了一个正则类(正则的构造函数)RegExp。
通过构造函数创建的对象称为正则对象
语法:
var 名字 = new RegExp('正则主体','修饰符');注意:
a.通过构造函数创建正则对象,参数必须为字符串格式
b.构造函数创建的正则表达式,和字面量创建的具有相同的作用,只不过长得不一样。
例子:
var str = '123abc12abABC';
var reg = new RegExp('\\d[a-z]+','gi');
var newStr = str.replace(reg,'(frank)');
console.log(newStr); // 12(frank)1(frank)
(1) test()
描述:本方法是 RegExp 对象中提供的一个方法,
用来判断在【指定字符串中】是否存在【满足正则表达式规则】的子字符串。
存在就返回 true,反之返回 false
语法:
正则表达式.test(指定字符串)例子:
var regExp = new RegExp('abcd','g');
console.log(regExp.test('12abc12abABC'));//false
var regExp = new RegExp('abc','g');
console.log(regExp.test('12abc12abABC'));//true补充:
RegExp 类中提供的方法对于正则表达式都是通用的,无论是字面量创建的正则,还是构造函数创建的正则。
console.log(/abc/g.test('12abc12abABC')); // true 正则表达式高级
1. ^ 初位字符和 $ 末位字符
描述:
^初位字符:以某个内容开头
$末位字符:以某个内容结尾
语法:
var reg = new RegExp('^temp', '');
var reg = new RegExp('temp$', '');例子:
var reg = new RegExp('^abc','gi');
var str = '12abc12abABC';
if( reg.test(str) ){
console.log('以abc开头的字符串');
} else {
console.log('不是以abc开头的字符串');
}注意:
如果一个子字符串被包裹在 ^ 和 $ 之间,那么匹配结果只能是这个字符串本身。
其余都不能匹配成功
例子:
var reg = new RegExp('^abc$','gi');
var str = 'abc';
if( reg.test(str) ){
console.log('以abc开头并结尾的字符串');
} else {
console.log('不是');
}
2.重复类
描述:重复类是指在正则表达式中通过 {} 大括号检索的一种模式的称谓。
{} 用来表示所匹配的内容连续出现的次数。一般重复类会配合表达式模式一起使用。
语法:
var reg = new RegExp('正则表达式主体{重复类}', '修饰符');类型:
subStr{n} 表示检索内容恰好出现n次
subStr{n,} 表示检索内容至少出现n次
subStr{n, m} 表示检索内容至少出现n次,至多出现m次。
注意:
对于重复类,有些是能匹配多少就匹配多少【{n,},{n,m}】
有些是匹配到就立即结束【{n}】
例子:
var reg = new RegExp('[a-z]{6}', 'gi');
var str = '12abc12abABCDEFGHIJKLMNOPQRSTUVWXYZ';
var result = str.match(reg);
console.log(result); // (4) ["abABCD", "EFGHIJ", "KLMNOP", "QRSTUV"]强调:
对于重复类而言,如果不存在组匹配符号(),那么重复类仅对其前面的第一个字符生效
例子:
var reg = new RegExp('abc{2}','gi');
var str = '12abcabc12abccab';
var result = str.match(reg);
console.log(result); // ["abcc"]
3.贪婪模式 和 懒惰模式
描述:
贪婪模式:只要符合正则要求就一直向下匹配,直到不满足条件为止
懒惰模式:只要匹配到最低符合正则要求的内容,就立即结束。
说明:
greed 和 lazy 都是固化在正则内部的两种检索模式,不会主动表现出来。
而是会配合其他的检索模式一同生效。
语法:
n+、n*、{n,}、{n,m} 都是使用贪婪模式的表现符号
n?、{n}、{n,}?、n*?、... 都是懒惰模式的表现符号
例子:
// 贪婪
var str = 'a1abb2ab3baab';
var info = str.match(/b[a-z]*/gi);
console.log(info); // (3) ["bb", "b", "baab"]
// 懒惰
var str = 'a1abb2ab3baab';
var info = str.match(/b[a-z]?/gi);
console.log(info); // (4) ["bb", "b", "ba", "b"]
4.脱字符
描述:当且仅当^符号出现在中括号的首位的时候,表示【不是...即成立】的规则。
语法:
var reg = /[^匹配内容]/修饰符注意:
(1) 如果^出现在正则首位,但没有写在中括号首位,表示初位字符
如果^出现在正则主体当中,但没写在中括号首位,表示普通字符
(2) [^]表示匹配任意字符
例子:
var pageStr = '<img width="200" /> <img> <img width="300" /> <img width="400" />';
// 以 <img 开头,后面不是 > ,以 /> 结束的文本
var reg = /<img[^>]*\/>/gi;
var list = pageStr.match(reg);
console.log(list); // (3) ["<img width="200" /><img width="300" /><img width="400 "/>"]数组去重
1.indexOf数组去重
注意:本数组去重方法存在一个重大的弊端,就是非常耗费时间(当数组元素过多时)
昵称:牺牲时间换空间
例子:
var arr = ['a','b','a','c','a'];
var newArr = [];
for(var i=0; i<arr.length; i++) {
if(newArr.indexOf(arr[i]) == -1) {
newArr.push(arr[i]);
}
}
console.log(newArr); //(3) ["a", "b", "c"]
2.hash表数组去重
解释:哈希表(hash):散列值表,无序的键值对集合。
注意:本数组去重方法存在一个重大的弊端,就是非常耗费内存(当数组元素过多时)
昵称:牺牲空间换时间
例子:
var arr = ['a','b','a','c','a'];
var resultArr = [];
var hash = {};
for(var i=0; arr[i]!=undefined; i++){
if(!hash[arr[i]]){
resultArr.push(arr[i]);
hash[arr[i]] = 100;
}
}
console.log(resultArr); // (3) ["a", "b", "c"]
console.log(hash); // {a: 100, b: 100, c: 100}3. ES6去重
利用 ES6 的 set 方法。
Set() 数据结构,它类似于数组,其成员的值都是唯一的
let arr = [1, 1, 2, 3, 5, 3, 1, 5, 6, 7, 4];
function unique(arr) {
// 利用Array.from() 将Set结构转换成数组
return Array.from(new Set(arr))
}
console.log(unique(arr)); // (7) [1, 2, 3, 5, 6, 7, 4]
冒泡排序
基本思想:
依次比较两个相邻的数,如果不符合规则则互换位置。
那么一轮比较下来就能够将最大或最小的值放在数组最后一位。
继续对除【最后一位】之外的所有元素重复上述过程
例子:
var arr = [5, 4, 3, 2, 1];
// 一轮比较,一轮比较能够得到一个最大值
for (var i=1; i<arr.length; i++) {
// 一轮比较中,要比较多少次
for (var j=0; j<arr.length -i; j++) {
// 如果前面的一个值大于后面的值,则将大的值放后面
if (arr[j] > arr[j + 1]) {
var temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
console.log(arr);
/*
(5) [4, 3, 2, 1, 5]
(5) [3, 2, 1, 4, 5]
(5) [2, 1, 3, 4, 5]
(5) [1, 2, 3, 4, 5]
*/
}
递归函数
描述:自己能够调用自己的函数,称为递归函数
注意:
(1) 在递归之外,递归变量赋初值
(2) 在递归之内,设置递归能够执行下去的条件
(3) 递归执行结束后,要让递归变量向着递归能够结束的方向发生变化
例子:
// 递归变量赋初值
var times = 1;
function tellStory() {
// 设置递归的终止条件
if (times > 5) return;
console.log('从前有座山');
console.log('山里有座庙');
console.log('庙里有个老和尚');
console.log('老和尚在讲故事');
console.log('讲的什么故事呢');
console.log('-----times:' + times + '--------');
// 递归变量向着递归结束的方向发生改变
times++;
// 递归能够循环执行的保证
tellStory();
}
tellStory();
快速排序
依托:递归函数
原理:
(1) 在已知数据集合当中随便取一个基准值(pivot)
(2) 将其余数据以基准值为中心,大于的放右面,小于的放左面
(3) 对左右两个子集重复步骤(1)(2)
例子:
var arr = [1, 4, 7, 2, 5, 8, 3, 6, 9];
//创建快速排序函数
function quickSort(tempArr) {
//递归终止条件
if (tempArr.length <= 1) return tempArr;
//取基准
var pivotIndex = Math.floor(tempArr.length / 2);
var pivot = tempArr.splice(pivotIndex, 1);
//分左右
var leftArr = [];
var rightArr = [];
for (var i = 0; i < tempArr.length; i++) {
if (tempArr[i] > pivot) {
rightArr.push(tempArr[i]);
} else {
leftArr.push(tempArr[i]);
}
}
return quickSort(leftArr).concat(pivot, quickSort(rightArr));
}
var finalArr = quickSort(arr);
console.log(finalArr); // (9) [1, 2, 3, 4, 5, 6, 7, 8, 9]
JSON
什么是 JSON?
JSON格式:
- 数据为 键/值 对。
- 数据由逗号分隔。
- 大括号保存对象
- 方括号保存数组
(1)JSON 数据: 一个名称 对应 一个值
JSON 数据格式为 键/值 对,就像 JavaScript 对象属性。
键/值对包括字段名称(在双引号中),后面一个冒号,然后是值:
"name":"Runoob"(2)JSON 对象
JSON 对象保存在大括号内,就像在 JavaScript 中, 对象可以保存多个 键/值 对:
{"name":"Runoob", "url":"www.runoob.com"}(3)JSON 数组
JSON 数组保存在中括号内,就像在 JavaScript 中, 数组可以包含对象:
"sites":[
{"name":"Runoob", "url":"www.runoob.com"},
{"name":"Google", "url":"www.google.com"},
{"name":"Taobao", "url":"www.taobao.com"}
](4)JSON 值可以是:数字(整数或浮点数)、字符串(在双引号中)、逻辑值(true 或 false)、数组(在方括号中)、对象(在花括号中)、null
例子:
{
"code": "1",
"data": [
{
"title": "NBA进攻R级别防守SSS级别的球员在CBA会是什么水平",
"typeid": 3
},
{
"title": "NBA那么多肌肉男,为何只有詹姆斯被赞是“人类身体标本”?",
"typeid": 3
}
],
"msg": "",
"total": 25919
}JSON解析(Javascript Object Notation)
描述:对象的字符串表现形式,本质上是一种轻量级的数据交换格式
(1) JSON.stringify() 方法用于将 JavaScript 值转换为 JSON 字符串。
语法:
JSON.stringify(value, replacer, space)参数说明:
value: 必需, 要转换的 JavaScript 值(通常为对象或数组)。
replacer: 可选。用于转换结果的函数或数组。
(1)如果 replacer 为函数,则 JSON.stringify 将调用该函数,并传入每个成员的键和值。使用返回值而不是原始值。如果此函数返回 undefined,则排除成员。根对象的键是一个空字符串:""。
(2)如果 replacer 是一个数组,则仅转换该数组中具有键值的成员。成员的转换顺序与键在数组中的顺序一样。
space: 可选,文本添加缩进、空格和换行符,如果 space 是一个数字,则返回值文本在每个级别缩进指定数目的空格,如果 space 大于 10,则文本缩进 10 个空格。space 也可以使用非数字,如:\t。
注意:
(1)JSON字符串统一采用单引号定义,而JSON字符串内容中如果出现引号则使用双引号。
(2)JSON封装过程:把js对象转换成JSON字符串。因为后台只认识JSON字符串
(3)JSON解析过程,把JSON字符串转换成js对象。因为字符串没办法直接提取有用信息
返回值:返回包含 JSON 文本的字符串。
例子:
var str = {"name":"wzc", "age":"18"}
jsonStr = JSON.stringify(str, null, 2) //使用两个空格缩进
console.log(jsonStr);
/*
{
"name": "wzc",
"age": "18"
}
*/(2)JSON.parse() 方法用于将一个 JSON 字符串转换为对象。
语法:
JSON.parse(text, reviver)参数说明:
text: 必需, 一个有效的 JSON 字符串。
reviver: 可选,一个转换结果的函数, 将为对象的每个成员调用此函数。
返回值:返回给定 JSON 字符串转换后的对象。
例子:
var Json = `
{
"code": "1",
"data": [
{
"title": "NBA进攻R级别防守SSS级别的球员在CBA会是什么水平",
"typeid": 3
},
{
"title": "NBA那么多肌肉男,为何只有詹姆斯被赞是“人类身体标本”?",
"typeid": 3
}
],
"msg": "",
"total": 25919
}
`;
var obj = JSON.parse(Json);
console.log(obj) // {code: "1", data: Array(2), msg: "", total: 25919}
JQuery
jQuery 安装
1.本地:可以从 http://jquery.com 中下载。
<script src="jquery-1.10.2.min.js"></script>2.线上:如果您不希望下载并存放 jQuery,那么也可以通过 CDN(内容分发网络)
引用它。
<script src=" https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>jq对象
描述:$() 函数的执行结果(返回值),是一个 jq 对象,jq 对象是一个包含了满足选择器条件的元素节点的信息集合,可以像使用数组一样使用。本质:是一个对象
注意:$() = jQuery() // 两者方法一致
jq 可以转换成 js 对象:
var $divs = $('div');
$divs.css('background-color','red');
console.log($divs[0]); //获取jq中第一个js对象,通过中括号获取
console.log($divs.get(1)); //获取jq中第二个js对象,通过.get(n)获取
jq 对象只能使用 jq 自己的属性和方法
例子:
var $divs = $('div');
console.log($divs); // 批量选中
$divs[0].style.backgroundColor = 'red'; // js对象调用jq方法,报错
length 属性
描述:本方法和属性为jq对象所有,表示jq对象中包含多少个js元素节点
语法:jq对象.length
例子:
var $divs = $('div');
$divs.css('backgroundColor','red');
console.log($divs.length); // 1
jQuery 选择器
| 选择器 | 实例 | 选取 |
|---|---|---|
| * | $("*") | 所有元素 |
| #id | $("#lastname") | id="lastname" 的元素 |
| .class | $(".intro") | 所有 class="intro" 的元素 |
| element | $("p") | 所有 <p> 元素 |
| .class.class | $(".intro.demo") | 所有 class="intro" 且 class="demo" 的元素 |
| :first | $("p:first") | 第一个 <p> 元素 |
| :last | $("p:last") | 最后一个 <p> 元素 |
| :even | $("tr:even") | 所有偶数 <tr> 元素 |
| :odd | $("tr:odd") | 所有奇数 <tr> 元素 |
| :eq(index) | $("ul li:eq(3)") | 列表中的第四个元素(index 从 0 开始) |
| :gt(no) | $("ul li:gt(3)") | 列出 index 大于 3 的元素 |
| :lt(no) | $("ul li:lt(3)") | 列出 index 小于 3 的元素 |
| :not(selector) | $("input:not(:empty)") | 所有不为空的 input 元素 |
| :header | $(":header") | 所有标题元素 <h1> - <h6> |
| :animated | 所有动画元素 | |
| :contains(text) | $(":contains('W3School')") | 包含指定字符串的所有元素 |
| :empty | $(":empty") | 无子(元素)节点的所有元素 |
| :hidden | $("p:hidden") | 所有隐藏的 <p> 元素 |
| :visible | $("table:visible") | 所有可见的表格 |
| s1,s2,s3 | $("th,td,.intro") | 所有带有匹配选择的元素 |
| [attribute] | $("[href]") | 所有带有 href 属性的元素 |
| [attribute=value] | $("[href='#']") | 所有 href 属性的值等于 "#" 的元素 |
| [attribute!=value] | $("[href!='#']") | 所有 href 属性的值不等于 "#" 的元素 |
| [attribute$=value] | $("[href$='.jpg']") | 所有 href 属性的值包含以 ".jpg" 结尾的元素 |
| :input | $(":input") | 所有 <input> 元素 |
| :text | $(":text") | 所有 type="text" 的 <input> 元素 |
| :password | $(":password") | 所有 type="password" 的 <input> 元素 |
| :radio | $(":radio") | 所有 type="radio" 的 <input> 元素 |
| :checkbox | $(":checkbox") | 所有 type="checkbox" 的 <input> 元素 |
| :submit | $(":submit") | 所有 type="submit" 的 <input> 元素 |
| :reset | $(":reset") | 所有 type="reset" 的 <input> 元素 |
| :button | $(":button") | 所有 type="button" 的 <input> 元素 |
| :image | $(":image") | 所有 type="image" 的 <input> 元素 |
| :file | $(":file") | 所有 type="file" 的 <input> 元素 |
| :enabled | $(":enabled") | 所有激活的 input 元素 |
| :disabled | $(":disabled") | 所有禁用的 input 元素 |
| :selected | $(":selected") | 所有被选取的 input 元素 |
| :checked | $(":checked") | 所有被选中的 input 元素 |
补充:$() 函数在使用的时候内部写引号,在写选择器。但有几种特殊情况不用添加引号
$(window)
$(document)
$(this)
jq中添加事件监听
1. jq中添加事件监听
语法:
jq对象.事件名( 回调函数 );特性:因为jq对象是批量的,因此在jq中添加事件监听的时候也是批量添加的。
例子:
var $divs = $('div');
$divs.click(function () {
$(this).css('background-color','red');
});
2. jq中事件名称
说明:jq中添加事件监听时,事件名称和js中基本保持一致。
只不过需要注意添加事件监听时一律没有on!
测试:
(1) jq可以给一个元素添加多个不同类型的事件,且互相触发不影响
(2) jq可以给一个元素添加多个相同类型的事件,且执行顺序按照添加顺序执行
例子:
var $div1 = $('.div1');
$div1.click(function (){
console.log('div1的单击事件');
});
$div1.click(function () {
console.log('div1的另一个单击事件');
});注意:
在jq中添加事件监听的时候,允许链式声明的写法。
且除最后一个添加的函数末尾写分号外,其余事件监听函数末尾都不需要写分号。
例子:
var $div1 = $('.div1');
$div1.click(function () {
console.log('第一个点击事件');
}).click(function () {
console.log('第二个点击事件');
}).dblclick(function () {
console.log('双击事件');
});
3. 下面是 jQuery 中事件方法的一些例子:
.ready(function) // 文档的就绪事件(当文档完成加载时)
.click(function) // 点击事件
.dblclick(function) // 双击事件
.focus(function) // 获得焦点事件
.mouseover(function) // 鼠标悬停事件4. jq中添加事件监听的其他方法
(1) on() \ off() 方法
描述:on()方法用于添加事件监听,off()方法用于取消事件监听
语法:
jq对象.on('事件名',回调函数);
jq对象.off('事件名');注意:off方法在取消事件的时候,取消的是一类事件,而不是一个事件!
例子:
var $div1 = $('.div1');
var $div2 = $('.div2');
$div1.on('click', function () {
console.log('div1通过on方法绑定的点击事件');
});
$div2.on('click', function () {
$div1.off('click');
console.log('div1上的事件已经被off方法取消掉了');
});
(3) one() 方法
描述:one方法添加的事件监听只能执行一次
语法:
jq对象.one('事件名', 回调函数);例子:
var $div1 = $('.div1');
$div1.one('click', function () {
console.log('这是一个点击事件');
});
jq中常见方法
1. css() 方法
描述:本方法为jq对象读写css样式的方法,相当于js中的style属性。
语法:
jq对象.css('属性名', '属性值');说明:
(1) 第一个参数是必要参数,第二个参数是可选参数。
(2) 如果只写第一个参数则代表读取属性的值,而写两个参数代表设置属性的值。
例子:
var $div1 = $('.div1');
var $div2 = $('.div2');
$div1.click(function () {
$(this).css('background-color', 'red');
});
$div2.click(function () {
console.log($div1.css('background-color'));
});补充:如果 css() 方法需要一次修改多个css样式,则参数可以写成JSON格式
例子:
var $div1 = $('.div1');
$div1.click(function () {
$(this).css({
"background-color":"yellow",
"border":"10px solid pink",
"width":"150px",
"height":"200px"
});
});
2. show()、hide()方法
描述:show() 方法表示jq对象立即显示,hide() 方法表示jq对象立即隐藏
语法:
jq对象.show(动画时间ms);说明:
(1) 方法内部的参数是可选参数,表示动画执行时间,单位是毫秒,
如果不写则默认执行时间为0。
(2) 方法的动画实际上是一个宽高渐变,透明度渐变的动画,
是从display:none到display:block之间的改变
例子:
var $div1 = $('.div1');
$('button:eq(0)').click(function () {
$div1.show();
});
$('button:eq(1)').click(function (){
$div1.hide();
});
$('button:eq(2)').click(function () {
$div1.show(5000);
});
$('button:eq(3)').click(function () {
$div1.hide(5000);
});
3. hover()
描述:jq中hover() 方法规定当鼠标指针悬停在被选元素上时要运行的两个函数。方法触发 mouseenter 和 mouseleave 事件。
语法:
hover(function(){
// 移入事件
}, function(){
// 移出事件
});注意: 如果只指定一个函数,则 mouseenter 和 mouseleave 都执行它。
例子:
$('tr:gt(0)').hover(function () {
tempColor = $(this).css('background-color');
$(this).css('background-color','red');
}, function () {
$(this).css('background-color',tempColor);
});
4. slideUp() 和 slideDown()方法
描述:slideUp 方法表示jq对象上拉消失,slideDown 方法表示jq对象下拉出现
语法:
jq对象.slideUp();
jq对象.slideDown();补充:对于这两个方法即使不写参数,也会默认有一定的动画时间,只不过比较短而已。
例子:
var $div1 = $('.div1');
$('button:eq(0)').click(function () { $div1.slideUp(); });
$('button:eq(1)').click(function () { $div1.slideDown(); });
$('button:eq(2)').click(function () { $div1.slideUp(5000); });
$('button:eq(3)').click(function () { $div1.slideDown(5000); });注意:
对于这两个方法存在一个隐藏的属性,称为“边界”。默认边界为上边界。
边界可以手动设置,设置方法为给jq对象添加定位属性。
强调:
slideUp 和slideDown 方法执行的起始点和结束点分别是
display:none 和 display:block
5. fadeIn() 和 fadeOut() 方法
描述:fadeIn() 表示淡入,fadeOut() 表示淡出
语法:
jq对象.fadeIn();
jq对象.fadeOut();说明:淡入和淡出的起始点和终止点分别为 display:none 和 display:block。
而不是 opacity:0 和 opacity:1
例子:
var $div1 = $('.div1');
$('button:eq(0)').click(function () { $div1.fadeIn(); });
$('button:eq(1)').click(function () { $div1.fadeOut(); });
$('button:eq(2)').click(function () { $div1.fadeIn(5000); });
$('button:eq(3)').click(function () { $div1.fadeOut(5000); });
6. addClass() 和 removeClass()
描述:addClass方法为追加类,在原有的基础上添加一个类名
removeClass方法为移除类,在已知的属性值列表中删除一个类名
语法:
jq对象.addClass('类名');
jq对象.removeClass('类名');注意:对于这两个方法,参数是【类名】,不是选择器!!!
例子:
var $div1 = $('.div1');
$('button:eq(0)').click(function () { $div1.addClass('bgRed'); });
$('button:eq(1)').click(function () { $div1.removeClass('bgRed'); });
7. attr() 方法
描述:用于修改jq对象的属性,本方法会覆盖原有的属性值
语法:
jq对象.attr('属性名','属性值');例子:把原来的class替换成abc
$('.div1').attr(‘class’ , ‘abc’);补充:如果attr方法只有一个参数,则代表读取这个属性的属性值。
8. text() 方法描述:设置或返回所选元素的文本内容
语法:
jq对象.text('文本内容');例子:
$('div').text();
$('div').text('文本已修改!');9. html()
描述:用来读写和设置jq对象的文本内容,相当于原生 js 中的 innerHTML属性,如果方法没有参数,代表读取内容。如果写了参数,代表设置内容。
语法:
jq对象.html('文本内容');例子:
$div1.html();
$div1.html('文本已修改');
10. val() 方法
描述:设置或返回表单字段的值
语法:
jq对象.val();例子:
$('div').val();$('div').val('我是新的输入框的值!');11. animate()
描述:表示设置jq对象的自定义动画
语法:
jq对象.animate(JSON格式的参数,动画执行时间ms);说明:
第一个参数是JSON格式,表示动画结束时jq对象的状态,哪怕只有一个属性发生改变,也要写成JSON格式
例子:
$('.div1').click(function () {
$(this).animate({
'left':800,
'width':'200px',
'height':'350px'
}, 2000);
});
(1)动画顺序:jq动画执行时遵守以下两个原则
(2)同步原则:同一个元素如果存在多个animate命令,则按照添加顺序执行。
$('.div1').click(function () {
$(this).animate({'left':800}, 2000)
.animate({'width':'200px'}, 2000)
.animate({'height':'350px'}, 2000);
});(3)异步原则:不同元素如果存在多个animate命令,则他们同时执行。
$('.div1').animate({'left':800}, 2000);
$('.div2').animate({'left':800}, 2000);注意:对于一个jq对象而言,一个animate完成所有动画,和多个animate分别完成所有动画效果完全不等价
(4)局限性:只能够修改一些可以被量化的属性,而对于没有量化的属性则无法进行动画。
例子:
$('.div1').click(function () {
//一次执行完毕
$(this).animate({'left':800, 'width':'200px', 'height':'350px'}, 2000);
//按照出现的顺序分次执行
$(this).animate({'left':800},2000)
.animate({'width':'200px'},2000)
.animate({'height':'350px'},2000);
});
(5)匀速运动(可选参数)
描述:animate 动画实际上是一个 ease-inout 的动画,linear 属性能够让动画匀速运动
语法:
jq对象.animate(JSON格式参数, 时间, 'linear');说明:linear属性是animate方法的第三个参数
例子:
$('.div1').animate({'left':800}, 5000, 'linear', function (){
$(this).css('background-color','red');
});
$('.div2').animate({'left':800}, 5000, function (){
$(this).css('background-color','red');
});(6)回调函数(可选参数)
描述:回调函数表示 animate 动画执行完毕后,要做什么
说明:回调函数是 animate 方法的第四个参数
例子:
$('.div1').click(function () {
$(this).animate({'left':800},2000, function () {
$('.div1').css('background-color','red');
});
});
12. stop() 方法
描述:stop方法用于结束jq对象的动画
语法:
jq对象.stop(clearAllAnimation, gotoEnd);(1) 两个参数都是布尔值,默认都是false,可以不写
(2) 第一个参数代表是否清除所有动画序列中的动画,false表示只清除当前动画。
(3) 第二个参数代表是否立即完成当前动画(达到动画结束状态),false表示不完成。
13. delay() 方法
描述:delay() 方法对队列中的下一项的执行设置延迟。
例子:
$('.container img').each(function (i) {
$(this).delay(i*500).fadeIn(100).fadeOut(100).fadeIn(100).fadeOut(100).fadeIn(100);
});
Jq节点关系
1. children() 方法
描述:本方法用于获取一个jq对象的所有【直接子节点】
语法:
jq对象.children('选择器名');说明:
(1) 参数为可选参数,如果不写代表选中jq对象中所有直接子节点
(2) 如果写参数,则代表选中jq对象中所有直接子节点中【满足选择器】的节点
例子:
$('div').click(function () {
$(this).children().css('background-color','red');
$(this).children('.teshu').css('background-color','red');
});
2. find() 方法
描述:本方法用于查找一个jq对象中【符合选择器要求】的后代节点
语法:
jq对象.find('选择器名');说明:find() 方法并不是只能查找直接子节点,而是对所有后代节点都能有效
例子:
$('div').click(function () {
$(this).find('span').css('background-color','red');
});
3. parent() 方法
描述:本方法用来获取当前jq对象的直接父节点
语法:
jq对象.parent();说明:本方法不需要参数,且仅能获取直接父节点,对祖先节点无效。
例子:
$('span').click(function () {
$(this).parent().css('border','10px solid red');
});
4. parents() 方法
描述:本方法用来获取当前jq对象的所有祖先节点,直到html节点为止。
语法:
jq对象.parents('选择器名');说明:
(1) 本方法参数为可选参数,如果不写表示获取所有祖先节点
(2) 如果写参数,则代表选中祖先节点中,满足选择器的节点
例子:
$('span').click(function () {
$(this).parents().css('border','10px solid red');
$(this).parents('.div1').css('border','10px solid red');
});
5. siblings()方法
描述:本方法用来获取当前jq对象的所有兄弟节点,除本身外
语法:
jq对象.siblings('选择器名');说明:
(1) 本方法参数为可选参数,如果不写则选中当前jq对象的所有兄弟节点
(2) 如果写参数,则代表选中兄弟节点中,满足选择器的节点。
例子:
$('p').click(function () {
$(this).siblings().css('background-color','red'); $(this).siblings('.teshu').css('background-color','red');});
6. next()、prev()、nextAll()、prevAll()方法
描述:以上四个方法都是用来访问jq对象的指定兄弟节点,如果写参数,则代表选中节点中,满足选择器的节点。
语法:
jq对象.next();
jq对象.prev();
jq对象.nextAll();
jq对象.prevAll();
说明:
(1) next() 方法用来访问当前jq对象的后一个兄弟节点
(2) prev() 方法用来访问当前jq对象的前一个兄弟节点
(3) nextAll() 方法用来访问当前jq对象的后面所有的兄弟节点
(4) prevAll() 方法用来访问当前jq对象的前面所有的兄弟节点
例子:
$('p').click(function () {
$(this).prevAll('.teshu').css('background-color','red');
})
jq节点顺序
1. index()
描述:本方法用于返回当前jq对象在兄弟节点中的排名,序号从0开始
语法:
jq对象.index();例子:
$('p').click(function () {
console.log($(this).index());
});2.对应
说明:jq中的对应实际上指的是eq()函数,作用是从集合中筛选出指定序号的节点
语法:
jq对象.eq(n);说明:序号从0开始
例子:
var $div1_p = $('.div1 p');
var $div2_p = $('.div2 p');
$div1_p.click(function () {
//点击div1中p标签的时候,让div2中对应序号的p跟随改变
$div2_p.eq($(this).index()).css('background-color','red');
});
jq节点遍历
1. each()方法
描述:遍历jq对象的每一个js节点,并让每一个js节点分别执行参数中的回调函数
语法:
jq对象.each(回调函数);注意:在each()方法的回调函数中,$(this)指代当前循环的这个js对象,而不是jq对象本身。
例子:
$('div').each(function () {
$(this).children().eq(1).css('background-color','red');
});
jq节点操作
1. append()、appendTo()、prepend()、prependTo()方法
描述:以上四个方法都用来给某个jq对象内部添加内容,只不过语法略有不同
语法:
(1) a.append(b): 给jq对象a中的内容之后,追加jq对象b
(2) b.appendTo(a): 把jq对象b,追加到jq对象a中的内容之后。
例子:
var $div = $('div');
$div.click(function () {
$(this).append($('<h2>这是一个h2</h2>'));
$('<h2>这是一个h2</h2>').appendTo($(this));
});(3) a.prepend(b): 给jq对象a中的内容之前,添加jq对象b
(4) b.prependTo(a): 把jq对象b,添加到jq对象a中的内容之前。
例子:
var $div = $('div');
$div.click(function () {
$(this).prepend($('<h2>这是一个h2</h2>'));
$('<h2>这是一个h2</h2>').prependTo($(this));
});
2. after()、insertAfter()、before、insertBefore()方法
描述:以上四个方法都用来给某个jq对象外部添加内容,只不过语法略有不同
语法:
(1) a.after(b): 给jq对象a的后面,添加一个同级jq对象b
(2) b.insertAfter(a): 把jq对象b,添加到jq对象a的后面
例子:
var $div = $('div');
$div.click(function () {
$(this).after($('<h2>这是一个h2</h2>'));
$('<h2>这是一个h2</h2>').insertAfter($(this));
});(3) a.before(b): 给jq对象a前面,添加一个同级jq对象b
(4) b.insertBefore(a): 把jq对象b,添加到jq对象a的前面
例子:
var $div = $('div');
$div.click(function () {
$(this).before($('<h2>这是一个h2</h2>'));
$('<h2>这是一个h2</h2>').insertBefore($(this));
});
3.节点守恒定律
描述:通过搜索获得的节点,在页面中同一时刻,只能出现在唯一的一个位置。
例子:
var $div1 = $('.div1');
var $div2 = $('.div2');
var $p = $('.teshu');
$div1.click(function () {
//点击div1,将p标签添加到div1中
$(this).append($p);
});
$div2.click(function () {
//点击div2,将p标签添加到div2中
$(this).append($p);
});
4. wrap()
描述:表示给当前jq对象添加一个父级元素节点
语法:
a.wrap(b);说明:给a添加一个父级元素节点b
例子:
var $div2 = $('.div2');
$div2.click(function () {
$(this).wrap($('<div></div>'));
});
5. empty() \ remove()
描述:
empty() 方法表示清空jq对象的内容
remove() 方法表示将自身删除
语法:
jq对象.empty();
jq对象.remove();例子:
$('.teshu').click(function () {
$(this).empty();
$(this).remove();
});
6. clone()
描述:相当于原生js中的 cloneNode() 方法
语法:
jq对象.clone();例子:
var $div1 = $('.div1');
var $div2 = $('.div2');
var $p = $('.teshu');
$div2.click(function () {
//点击div1,将【p标签的克隆】添加到div1中
$(this).append($p.clone());
});
jquery方式创建标签及添加属性
var $td = $("<td>"); // 创建td标签
$td.attr(class,'box'); // 设置标签属性class=‘box’
$td.html('哈哈哈哈'); // 设置td标签文本值为'哈哈哈哈'
$("#tr_id1").append($td); // 将新创建的td标签插到id为tr_id1的标签中AJAX
Ajax(Asynchronous JavaScript And XML)概念:
通过XMLHttpRequest对象向服务器提出请求并处理响应,进行页面的局部更新。
1. AJAX都有哪些优点和缺点?
ajax的优点:
1、最大的一点是页面无刷新,用户的体验非常好。
2、使用异步方式与服务器通信,具有更加迅速的响应能力。
3、“按需取数据”,可以最大程度的减少冗余请求,和响应对服务器和带宽的负担,节约空间和宽带租用成本。
4、基于标准化的并被广泛支持的技术,不需要下载插件或者小程序。
ajax的缺点:
1、ajax不支持浏览器back按钮。
2、安全问题 AJAX暴露了与服务器交互的细节。
3、对搜索引擎的支持比较弱。
4、破坏了程序的异常机制。
5、不容易调试。
2. 创建 XMLHttpRequest 对象的语法:
let xhr = new XMLHttpRequest();3. 向服务器发送请求
如需将请求发送到服务器,我们使用 XMLHttpRequest 对象的 open() 和 send() 方法:
// 规定请求的类型、URL 以及是否异步处理请求
// method:请求的类型;GET 或 POST
// url:文件在服务器上的位置
// async:true(异步)或 false(同步)
xmlhttp.open(method, url, async);
//将请求发送到服务器
// 参数仅用于 POST 请求
xmlhttp.send();
4. GET 还是 POST?
与 POST 相比,GET 更简单也更快,并且在大部分情况下都能用。
然而,在以下情况中,请使用 POST 请求:
- 无法使用缓存文件(更新服务器上的文件或数据库)
- 向服务器发送大量数据(POST 没有数据量限制)
- 发送包含未知字符的用户输入时,POST 比 GET 更稳定也更可靠
5. 请求方式
GET
get方法在Rest中主要用于获取资源,能够发送参数,不过有限制,且参数都会以?开头的形 式附加在URL尾部。规范的get方法处理器应该是幂等的,也就是说对一个资源不论发送多少次get请求都不会更改数据或造成破坏。
特点: 可被缓存,保留在浏览器历史记录中,可被收藏为书签,不应在处理敏感数据时使用,有长度限制,只应当用于取回数据
POST
post方法在Rest请求中主要用于添加资源,参数信息存放在请求报文的消息体中相对安全,且可发送较大信息
特点: 不会被缓存,不会保留在浏览器历史记录中,不能被收藏为书签,对数据长度没有要求
PUT
DELETE
6. ajax的同步和异步区别:
同步:阻塞的:同步就是指一个进程在执行某个请求的时候,若该请求需要一段时间才能返 回信息,那么这个进程将会一直等待下去,直到收到返回信息才继续执行下去;
异步:非阻塞的:异步是指进程不需要一直等下去, 而是继续执行下面的操作,不管其他进程的状态。当有消息返回时系统会通知进程进行处理,这样可以提高执行的效率。
7. onreadystatechange 事件
当请求被发送到服务器时,我们需要执行一些基于响应的任务。
每当 readyState 改变时,就会触发 onreadystatechange 事件。
readyState 属性存有 XMLHttpRequest 的状态信息。
在 onreadystatechange 事件中,我们规定当服务器响应已做好被处理的准备时所执行的任务。
当 readyState 为 4 , status 为 200 时,表示响应已就绪!
| onreadystatechange | 存储函数(或函数名),每当 readyState 属性改变时,就会调用该函数。 |
| readyState | 存有 XMLHttpRequest 的状态。从 0 到 4 发生变化。
|
| status | 200: "OK" 404: 未找到页面 |
8. 服务器响应
获取服务器数据: responseText // 获得字符串形式的响应数据。
9.简述 ajax 的过程:
1. 创建 XMLHttpRequest 对象,也就是创建一个异步调用对象
2. 创建一个新的 HTTP 请求,并指定该 HTTP 请求的方法、URL 及验证信息
3. 设置响应 HTTP 请求状态变化的函数
4. 发送 HTTP 请求
5. 获取异步调用返回的数据
6. 使用 JavaScript 和 DOM 实现局部刷新
10. 原生 ajax 请求完整实例
let xhr;
if (window.XMLHttpRequest) {
// IE7+, Firefox, Chrome, Opera, Safari 浏览器执行代码
xhr = new XMLHttpRequest();
} else {
// IE6, IE5 浏览器执行代码
xhr = new ActiveXObject("Microsoft.XMLHTTP");
}
xhr.onreadystatechange = () => {
// 判断是否请求成功
if (xhr.readyState === 4 && xhr.status === 200) {
//返回数据
console.log(xhr.responseText);
}};
xhr.open("GET", url, true);
xhr.send();
jQuery - AJAX
1. jq封装好的 ajax 请求
$.ajax({
url: "https://www.jsanai.com/api/selfnews/newslist",
dataType: "json",
type: "GET",
async: "true",
data: { id: 1 },
success (res) {
console.log(res.data);
},
error () {
console.error('请求错误!');
}
});- url 发送请求的地址
- dataType 服务器返回数据的类型:
- type 请求方式:默认为get
- async 异步方式,默认为 true,即异步方式。当设置为 false 时,为同步方式。
- data 请求参数
- success 请求成功时执行
- error 请求失败时执行
2. jQuery.getJSON() 是 jQuery.ajax() 函数的简写形式.
语法:jQuery.getJSON( url [, data ] [,
success ] )
$.getJSON(url , "", function(data) {
console.log(data)
});