DOM
属性节点
Element.className
className属性用来读写当前元素节点的class属性。它的值是一个字符串,每个class之间用空格分割。
// HTML 代码 <div class="one two three" id="myDiv"></div>
var div = document.getElementById('myDiv');
div.className
// "one two three"
Element.style
每个元素节点都有style用来读写该元素的行内样式信息
不过,连词号需要变成骆驼拼写法。
var divStyle = document.querySelector('div').style;
divStyle.backgroundColor = 'red';
divStyle.border = '1px solid black';
divStyle.width = '100px';
divStyle.height = '100px';
divStyle.fontSize = '10em';
divStyle.backgroundColor // red
divStyle.border // 1px solid black
divStyle.height // 100px
divStyle.width // 100px
Element.style返回的只是行内样式,并不是该元素的全部样式。通过样式表设置的样式,或者从父元素继承的样式,无法通过这个属性得到。元素的全部样式要通过window.getComputedStyle()得到。
属性节点
获取属性和设置属性(自定义属性)
Element.getAttribute方法接受一个字符串作为参数,返回同名属性的值。如果没有该属性,则返回null。
var mydiv = document.getElementById('mydiv');
var id = mydiv.getAttribute('id');
Element.setAttribute方法用于为当前节点设置属性。如果属性已经存在,将更新属性值,否则将添加该属性。该方法没有返回值。
// HTML 代码为
// <button>Hello World</button>
var b = document.querySelector('button');
b.setAttribute('name', 'myButton');
b.setAttribute('disabled', true);
Element.removeAttribute方法移除指定属性。该方法没有返回值。
document.getElementById('div1').removeAttribute('id')
outerHTML
outerHTML 包括整个标签,而不仅限于标签内部的内容
innerText
innerText只获取元素内的文本内容,html标签将被忽略
获取孩子节点 childNodes和children
Element.children属性返回一个类似数组的对象(HTMLCollection实例),包括当前元素节点的所有子元素。如果当前元素没有子元素,则返回的对象包含零个成员
这个属性与Node.childNodes属性的区别是,它只包括元素类型的子节点,不包括其他类型的子节点。而childNodes属性包含空白节点
高级选取
Element.firstElementChild属性返回当前元素的第一个元素子节点,Element.lastElementChild返回最后一个元素子节点。如果没有元素子节点,这两个属性返回null。
兄弟节点
nextElementSibling 下一个节点
previousElementSibling 上一个节点
Element.nextElementSibling属性返回当前元素节点的后一个同级元素节点,如果没有则返回null。
Element.previousElementSibling属性返回当前元素节点的前一个同级元素节点,如果没有则返回null。
(分别对应的还有 firstChild,lastChild,nextSibling ,previousSibling方法 不过这些个方法都能获取到文本节点)
Element.parentNode可以获取父节点
元素的全部样式要通过window.getComputedStyle()得到。
行内样式(inline style)具有最高的优先级,改变行内样式,通常会立即反映出来。但是,网页元素最终的样式是综合各种规则计算出来的。因此,如果想得到元素实际的样式,只读取行内样式是不够的,需要得到浏览器最终计算出来的样式规则。PL
window.getComputedStyle方法,就用来返回浏览器计算后得到的最终规则。它接受一个节点对象作为参数,返回一个 CSSStyle 实例,包含了指定节点的最终样式信息。所谓“最终样式信息”,指的是各种 CSS 规则叠加后的结果。
var div = document.querySelector('div');
var styleObj = window.getComputedStyle(div);(只能获取样式,不能设置)
styleObj.backgroundColor
上面代码中,得到的背景色就是div元素真正的背景色
兼容性问题
低版本ie 使用
box.currentStyle 获取全部样式
box.insertBefore(newNode, existNode) 插入节点
在box的子节点existNode前面插入一个新节点
document.createTextNode() 创建文本节点
var t = document.createTextNode('你好');
box.appendChild(t) ;
在box尾部添加一个文本节点
offsetWidth/offsetHeight
Element.offsetHeight属性返回一个整数,表示元素的 CSS 垂直高度(单位像素),包括元素本身的高度、padding 和 border
Element.offsetWidth属性表示元素的 CSS 水平宽度(单位像素),其他都与Element.offsetHeight一致。
这两个属性都是只读属性
如果元素的 CSS 设为不可见(比如display: none;),则返回0
Element.offsetParent属性返回最靠近当前元素的、并且 CSS 的position属性不等于static的上层元素。
<div style="position: absolute;">
<p>
<span>Hello</span>
</p>
</div>
上面代码中,span元素的offsetParent属性就是div元素。
该属性主要用于确定子元素位置偏移的计算基准,
Element.offsetTop和Element.offsetLeft就是offsetParent元素计算的。
offsetLeft/offsetTop
Element.offsetLeft返回当前元素左上角相对于Element.offsetParent节点的水平位移,Element.offsetTop返回垂直位移,单位为像素。通常,这两个值是指相对于父节点的位移
方法 描述
getElementById():返回带有指定 ID 的元素。
getElementsByTagName():返回包含带有指定标签名称的所有元素的节点列表(集合/节点数组)。
getElementsByClassName():返回包含带有指定类名的所有元素的节点列表。
appendChild():把新的子节点添加到指定节点。
removeChild():删除子节点。
replaceChild():替换子节点。
insertBefore():在指定的子节点前面插入新的子节点。
createAttribute():创建属性节点。
createElement():创建元素节点。
createTextNode():创建文本节点。
getAttribute():返回指定的属性值。
setAttribute():把指定属性设置或修改为指定的值。
这段代码创建了一个新的
元素:
var para=document.createElement("p");
如需向
元素添加文本,您首先必须创建文本节点。这段代码创建文本节点:
var node=document.createTextNode("This is a new paragraph.");
然后您必须向
元素追加文本节点:
para.appendChild(node);
最后,您必须向已有元素追加这个新元素。
这段代码查找到一个已有的元素:
var element=document.getElementById("div1");
这段代码向这个已存在的元素追加新元素:
element.appendChild(para);
数组
数组
定义:数组是一个可以存储一组或一系列相关数据的容器。
为什么要使用数组?
1:为了解决大量相关数据的存储和使用的问题。
2:模拟真实的世界(班级、军队)。
创建数组
1:通过构造函数的方式来创建。 var a = new Array();
1.直接赋值
var a=new Array(数据1,数据2,…);
var a=new Array(数值)
如果括号中只有一个元素,并且这个元素是数值类型的,那么他就是指定数组的长度。 并且它的值都是undefined。
数组的属性:length 属性 (获取整个数组的长度)。
2.声明以后再赋值
var a=new Array(); a[0]=1; a[1]=2; a[2]=3;
2:JSON的方式创建数组。 var a=[];
1.直接赋值:
var a=[1,2,3,4];
2.声明以后再赋值:
var a=[]; a[0]=1; a[1]=2; a[2]=3;
JS数组可以存储任何类型的值。
访问数组
通过数组的(中括号)下标访问。
数组下标从0开始,他的最大值,是length-1。有8个元素的话,则长度是8,如果要访问最后一个元素,则访问7。因为下标从0开始,01234567。
数组的操作 (增删改查)
连接数组: (原数组不变)
arr.join(bystr); //把数组的各元素由bystr连接起来作为字符串;与字符串的split功能刚好相反
arr.toString(); //返回由逗号(,)连接数组元素组成的字符串
document.write(v.toString());document.write(v); //这两句效果一样
arr2 = arr.concat(元素, ...); //把元素添加到数组尾端后,返回另一数组;在参数里填入另一数组,返回合并数组
数组排序: (返回排序后的数组;改变原数组)
arr.reverse(); //按原顺序倒着排序
arr.sort(); //按字典顺序排序
获取子数组: (返回被删/被截取的元素数组)
arr.slice(start,end); //从start下标开始,截取到end;返回被截取的元素数组;不改变原数组
//start和end可用负数表倒数(-1代表最后一个元素);end<start时不截取;忽略end,截取start后的所有元素
arr.splice(start,n,value, ...); //从start(第几个删除)下标开始删除n(删除几个)个,再插入value(可理解为替换);改变原数组
//start为负数时表倒数;n<1表不删除;可忽略value(不插入);可忽略n,表删除后面所有;返回被删元素数组
4) 栈:(数组的基础; 改变原数组)
arr.pop(); //删最后的一个元素;返回删除的元素
arr.push(元素, ...); //添加元素到最后位置;返回数组长度; 等价于: arr[length] = newValue;
arr.unshift(元素, ...); //添加元素到最前位置(多个参数,则按参数顺序同时插入);返回数组长度
arr.shift(); //删最前的一个元素;返回被删除的元素
5) toString 和 valueOf
把每一项都调用 toString 方法,然后用半角逗号(,)连接每一项。
如: var arr = [1,2,3,4,5]; alert(arr); //output:1,2,3,4,5
遍历数组
1:for循环。
2:while循环。
3:for in循环。
for in的作用:
1:用于数组的遍历。
2:用于对象属性的遍历。
数组分类
整数数组/字符串数组/对象数组/二维数组
按照维度来分类
1.一维数组
2.二维数组
声明二维数组:
var arr=[ [1,2,3], [4,5,6]]; alert(arr[1][1]);
//5
排序算法
1:冒泡排序
5,1,3,2,4
1,5,3,2,4
1,3,5,2,4
1,3,2,5,4
1,3,2,4,5
1,2,3,4,5
思路分析:在要排序的一组数中,对当前还未排好的序列,从前往后对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒。
即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换。
function bubbleSort (arr) {
// 控制冒泡的轮数
for (var i = 0;i<arr.length-1;i++) {
// 控制每轮冒出一个数需要比较的次数
for (var j = 0; j < arr.length-1-i; j++) {
if (arr[ j ] > arr[j+1]) {
var temp=arr[ j ];
arr[ j ]=arr[ j+1 ];
arr[ j +1]=temp;
}
}
}
return arr;
}
2:选择排序
思路分析:选择排序和冒泡排序类似,也是依次对相邻的数进行两两比较。不同之处在于,它不是每比较一次就调换位置,而是一轮比较完毕,找到最大值(或者最小值)之后,将其放在正确的位置,其他数的位置不变。
1,5,3,2,4
1, 5,3,2,4 //1
1,2 5,3,4 //2
1,2,3 5,4//3
1,2,3,4 5 //4
1,2,3,4,5 //5
function selectionSort(arr){
var len = arr.length,min;
for (i=0; i < len; i++){
// 将当前位置设为最小值
min = i;
// 检查数组其余部分是否更小
for (j=i+1; j < len; j++){
if (arr[j] < arr[min]){
min = j;
}
}
// 如果当前位置不是最小值,将其换为最小值
if (i != min){
var temp = arr[i];
arr[i] = arr[min];
arr[min] = temp;
}
} return arr;
}
1. 函数的值传递和引用传递
1:值传递
定义:调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
2:引用传递
定义:调用函数时将实际参数的地址传递到函数中,这样在函数中如果对参数所进行的修改,将影响到实际参数。
堆和栈及索引思维
栈(stack)和堆(heap)
栈为自动分配的内存空间;而堆 则是动态分配的内存。
基本类型和引用类型
基本类型:存放在栈内存中的简单数据段,数据大小确定,内存空间大小可以分配。
5种基本数据类型有Undefined、Null、Boolean、Number 和 String,它们是直接按值存放的,所以可以直接访问。
引用类型:存放在堆内存中的对象,变量实际保存的是一个指针,这个指针指向另一个位置。每个空间大小不一样,要根据情况开进行特定的分配。
当我们需要访问引用类型(如对象,数组,函数等)的值时,首先从栈中获得该对象的地址指针,然后再从堆内存中取得所需的数据。
对象的两种创建方式
1.构造函数 创建对象
2.JSON形式创建对象 {name:’zhangsan’} 或者 {‘name’:’zhangsan’}
ajax
1 .ajax的概念
全称:Asynchronous(异步) Javascript And Xml
前端经常需要使用后端提供的接口获取数据,怎么向服务器请求数据呢,就是使用ajax
AJAX不是一种新的编程语言,而是一种用于创建更快更好以及交互性更强的WEB应用程序技术,该技术在98年前后得到了应用。
通过AJAX,你的JS可以通过JS的XMLHttpRequest对象在页面不重载的情况下与服务器直接进行通信。这样可以在服务器请求到想要的数据,而不是整个页面。AJAX的核心就是JS的XMLHttpRequest对象。xhr对象是在IE5中首次引入,它是一种支持异步请求的对象。
2.ajax的优势
1:无刷新更新数据。(局部刷新)
2:异步与服务器通信。(不让界面卡顿)
3:基于标准被广泛支持。
4:界面与应用分离。(前后端分离)
5:节省带宽
3.编写步骤
所有现代浏览器(IE7+,chrome,firefox,opera,safari)均内建XMLHttpRequest对象。但是IE5、6使用ActiveXObject对象
1-创建XMLHttpRequest对象
var xhr = null;
xhr = new XMLHttpRequest();
2-打开和服务器的连接
// url(接口)
var url = 'https://api.readhub.me/topic?lastCursor=40462&pageSize=20'
xhr.open('GET', url);
3-发送请求
//发送
xhr.send(null)
4-回调函数
xhr.onload 回调函数是在异步请求加载完成后所执行的函数,当JavaScript 监测到请求的数据全部传输完成后就会触发该函数
//指定回调函数,请求成功(回调)调用这个函数
xhr.onload= function() {
if(xhr.status == 200) {
//请求成功
//console.log(xhr.responseText)
var obj = JSON.parse(xhr.responseText)
console.log(obj)
}
}
完整的代码如下
//发起 ajax
//1.创建xmlhttprequest 对象
var xhr = null;
if(window.ActiveXObject) {
xhr = new ActiveXObject(’Microsoft.XMLHTTP’);
} else if(window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
}
2. 打开链接 请求方式get
// url(接口)
var url = 'https://api.readhub.me/topic?lastCursor=40462&pageSize=20'
xhr.open('GET', url);
3.发送
xhr.send(null);
4.指定回调函数,请求成功(回调)调用这个函数 onload(装载)
xhr.onload= function() {
if(xhr.status == 200) {
//请求成功
//console.log(xhr.responseText)
var obj = JSON.parse(xhr.responseText)responseText(返回的内容)
console.log(obj)
}
}
4.编写服务器接口
注意,在公司中我们的使用接口,都会有专门的接口文档,说明接口的功能和参数,格式如下
接口地址:http://127.0.0.1/mysql-api-username.php
接口功能:检测用户名是否存在
接口类型:get请求
接口参数:
参数 是否必选 参数说明
username y 用户名
接口请求示例:http://127.0.0.1/mysql-api-username.php?username=张三
返回json数据:
{
"isExist":false//表示是否存在用户
}
回调函数
封装ajax函数,我们就可以多次使用ajax功能,而不用重复的写创建xhr的代码。
我们每次调用ajax函数都会获取到数据,每次请求到数据,都需要对数据进行加工处理,显示在页面上。比如,登录的是时候调用登录接口,成功以后可能是跳转到首页。而请求新闻列表接口以后我们要把数据显示在列表上。所以我们可以再每次请求的时候,设置回调函数,在回调函数中获取数据!
代码如下
function ajax(url, callbackfn) {
var xhr = new XMLHttpRequest();
xhr.open('get', url);
xhr.send(null)
xhr.onload= function() {
if(xhr.status == 200) {
var obj = JSON.parse(xhr.responseText)
//回调函数
callbackfn(obj);
}
}
}
ajax(url1,function(obj){
console.log(obj)
});
ajax(url2,function(obj1){
console.log(obj1)
})
ajax的依赖调用
让两个请求有顺序
比如登录成功(调用登录接口)以后,我们才能获取这个用户的相关的信息(调用获取用户信息接口)
//登录
ajax(loginAPi,function(obj){
console.log(obj)
//获取用户信息
ajax(getUserInfoAPi,function(obj1){
console.log(obj1)
})
});
Promise介绍
Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象
ES6 规定,Promise对象是一个构造函数,用来生成Promise实例。
我们先来看看它的使用方法
const promise = new Promise(function(resolve, reject) {
// ... some code 这里写异步操作代码
ajax(api1,function(res){
// 异步操作成功,请求数据成功
resolve(value);//将promise设置为resolved(完成状态)
},function(error){
// 异步操作失败,请求数据失败
reject(error);将promise设置为rejected (失败状态)
})
});
resolve函数的作用是 在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;
reject函数的作用是 在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去
Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的,不一定要提供。这两个函数都接受Promise对象传出的值作为参数。
上面代码也可成如下形式
promise.then(function(value) {
// success
}).catch(function(error){
//error
})
在success 里面我们可以发起第二个请求
promise.then(function(value) {
// success
ajax(api2,function(res){
})
}).catch(function(error){
//error
})
这个时候我们的两个请求明显的就有顺序
像是这样 new Promise(ajax1).then(ajax2).catch() ,使用了链式调用代替了嵌套结构,这样就避免了层层嵌套使的代码可读性太差!
ajax的同源策略
同源策略(same origin policy)是一种约定,即只有本网站的网页上才能使用本网站的接口
所谓同源:是指协议、域名、端口都相同
比如你们公司的网站是www.xx.com,在你们的网站的页面上使用www.yy.com的接口是不被允许的!
想想问为什么不同源,不允许这样?如果你们公司的服务器(每年花费成本维护),别人公司在使用并且赚了钱,你们公司会愿意吗?!@#!@#
所以就有了同源策略,这个策略是由netscape公司引入浏览器的,他是浏览器最核心最基本的安全功能。现在所有支持JS的浏览器都会使用这个策略。
jsonp跨域
事情的发展总是不如人愿,那群挑事的公司又在抱怨:我们公司的服务器就是想让别人用(靠什么赚钱?你懂得,用的人多了自热能赚钱)!!@#!@#
怎么会有这样的公司呢?百度,谷歌,这些公司的搜索窗口会出现很多公司的网站。
去看看duba.com, 哪个公司出钱多,他的默认搜索引擎就是哪个公司!
同源策略的限制,使得他们要想想方设法要跨域!即域名不同,别人也能使用你们的接口!这个技术就是jsonp跨域,JSONP = JSON WITH PADDING,就是把json数据装在内部。
我们发现凡是拥有src这个属性的标签都拥有跨域的能力,如img,script。那我们就可以把数据装载到JS文件内,供客户端调用和进一步处理。
想一想,你的网站可以使用别人网站的图片吗?可以使用别人网站的js吗? 可以的。
整个过程像是这样的,a公司网站上放了一个js文件,a.js,内容如下
func({name:"张三",age:18});
b公司的网页引入了这个a.com/a.js
<script src="a.com/a.js" type="text/javascript" charset="utf-8"></script>
我们会发现,a.js在调用func这个函数,b公司的网页没有这个函数,就会报错。但是如果b公司实现了个函数呢
<script src="a.com/a.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript">
function func(obj){
}
</script>
这样就不会报错了,并且a公司的网页上拿到了b的数据! 这就是jsonp 跨域!
在实际使用中,具体步骤如下
1:定义一个回调函数(全局函数)。 (回调函数的名称要看a公司的规定)
2:创建script标签,指定src地址(b公司的接口),并添加到(a公司)页面中。
注:一般来说src必须跟着一个参数callback来指定回调函数名称
/定义回调函数
window.fn = function(res) {
}
//创建script标签
var sc = document.createElement('script')
sc.src = api;
document.body.appendChild(sc);
服务器端跨域
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。整个CORS通信过程,都是浏览器自动完成,不需要用户参与!
get和post
1.GET请求的数据会附在URL之后(就是把数据放置在HTTP协议头中),以?分割URL和传输数据,参数之间以&相连。
2.POST把提交的数据则放置在是HTTP包的包体中。
3:数据大小
GET请求传送的数据量比较小,最大2KB,这个受浏览器的限制。而POST请求传送的数据量比较大,一般默认为不受限制。其实大小受服务器的限制。
4:安全性
GET安全性非常低,POST的安全性较高。
下面是使用xhr,发送post请求的方法
使用send('lastCursor=40462&pageSize=20 ')设置请求体的内容
//发起 ajax
//1.创建xmlhttprequest 对象
var xhr = new XMLHttpRequest();
//2. 打开链接 请求方式 post
var url = 'http://127.0.0.1/bk/mysql-api-username.php'
xhr.open('POST', url);
//3.发送
//post 模拟表单的 需要增加请求头
xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
//get 请求 参数在url中
//post 请求参数 body中
//post参数如下形式
//lastCursor=40462&pageSize=20
var pa = 'username=张三';
xhr.send(pa);//设置请求体的内容
//指定回调函数,请求成功(回调)调用这个函数
//请求耗时操作
xhr.onreadystatechange = function() {
console.log(111, xhr.readyState)
if(xhr.status == 200) {
//请求成功
//console.log(xhr.responseText)
var obj = JSON.parse(xhr.responseText)
console.log(obj)
}
}
事件流
confirm 提示的意思,有取消和确定按键
事件基础
JavaScript 事件是由访问 Web 页面的用户引起的一系列操作。
当用户执行某些操作的时候,再去执行一系列代码。或者用来获取事件的详细信息,
如鼠标位置、键盘按键等。
事件处理函数
javaScript可以处理的事件类型为:鼠标事件、键盘事件、HTML事件
所有的事件处理函数都会都有两个部分组成,on + 事件名称
鼠标事件
onclick:用户单击鼠标按钮或按下回车键时触发
ondblclick:当用户双击主鼠标按钮时触发
onmousedown:当用户按下鼠标还未弹起时触发
onmouseup:当用户释放鼠标按钮时触发
onmouseover:当鼠标移到某个元素上方时触发
onmouseout:当鼠标移出某个元素上方时触发
onmousemove:当鼠标指针在元素上移动时触发
HTML 事件
onload:当页面或者资源完全加载后在 window 上面触发,或当框架集加载完毕后在框架集上触发。
onselect:当用户选择文本框(input 或 textarea)中的一个或多个字符触发
onchange:当文本框(input 或 textarea)内容改变且失去焦点后触发
onfocus:当页面或者元素获得焦点时在 window 及相关元素上面触发
onblur:当页面或元素失去焦点时在 window 及相关元素上触发
onresize:当窗口或框架的大小变化时在 window 或框架上触发
onscroll:当用户滚动带滚动条的元素时触发
事件对象
当触发某个事件时,会产生一个事件对象,这个对象包含着所有与事件有关的信息 。包括导致事件的元素、事件的类型、以及其它与特定事件相关的信息。
通过事件绑定的执行函数是可以得到一个隐藏参数的 。说明,浏览器会自动分配一个参数,这个参数其实就是 event 对象。
Event对象获取方式 (兼容性)
event.button属性
当前事件触发时哪个鼠标按键被点击
clientX、clientY属性
鼠标在可视区X坐标和Y坐标,即距离左边框和上边框的距离
screenX、screenY属性
鼠标在屏幕区X坐标和Y坐标,即距离左屏幕和上屏幕的距离
offsetX、offsetY属性
鼠标相对于事件源的X坐标和Y坐标
pageX、pageY
鼠标相对于文档的X坐标和Y坐标
键盘事件keyup、keydown、keypress
onkeydown:当用户按下键盘上任意键触发,如果按住不放,会重复触发
onkeypress:当用户按下键盘上的字符键触发,如果按住不放,会重复触发
onkeyup:当用户释放键盘上的键触发
组合键ctrkey、altkey、shiftkey
altKey属性,bool类型,表示发生事件的时候alt键是否被按下
ctrlKey属性,bool类型,表示发生事件的时候ctrl键是否被按下
shiftKey属性,bool类型,表示发生事件的时候shift键是否被按下
keyCode/which兼容
事件源(事件在哪个元素上产生)
事件的冒泡
事件按照从最特定的事件目标到最不特定的事件目标(document对象)的顺序触发。
阻止事件冒泡
//阻止事件冒泡
e.stopPropagation();
//低版本ie
e.cancelBubble = true;
浏览器的默认行为
JavaScript事件本身所具有的属性,例如a标签的跳转,Submit按钮的提交,右键菜单,文本框的输入等。
阻止默认行为的方式
w3c的方法是e.preventDefault(),
IE则是使用e.returnValue = false;
return false;
自定义右键菜单 oncontextmenu
DOM2级事件处理程序
添加事件监听器:ele.addEventListener(事件名,处理函数,布尔值)
现代浏览器(IE9、10、11 | ff, chorme, safari, opera)
注意:事件名不带on,处理函数为函数引用,布尔值代表冒泡(内到外)或捕获(外到内)
element.addEventListener(“click”,function(){},false);//false 事件冒泡
element.addEventListener(“click”,function(){},true);//true事件捕获
移除事件监听器:removeEventListener(事件名,处理函数)
IE8及以下的事件监听器:attachEvent(事件名,处理函数),detachEvent(事件名,处理函数)
注意:事件名带on
事件委托
利用事件冒泡的原理,把本应添加给某元素上的事件委托给他的父级(外层)。
使用案例
如果一个ul中有很多li,循环遍历所有的li,给li添加事件效率比较低,我们可以监听ul的点击事件,利用子元素的点击事件都会冒泡到父元素的特点,就可以知道什么时候点击了li。
好处:效率高,可以给未来元素添加事件
//通过id获取ul元素
var oUl = document.getElementById("list");
//通过css选择器获取ul中的所有li元素,返回一个类数组
var aLi = document.querySelectorAll("#list li");
//初次获取元素列表的长度
var startLen = aLi.length;
console.log(startLen);
//创建li元素节点
var nLi = document.createElement("li");
//创建文本节点
var textNode = document.createTextNode("我是li元素");
//将文本节点插入li元素节点中
nLi.appendChild(textNode);
//将组合后的li元素,再放入到ul元素内部子元素的末尾
oUl.appendChild(nLi);
拖拽效果
拖拽原理
三个事件:onmousedown、onmousemove、onmouseup
实现思路:
1:给目标元素添加onmousedown事件,拖拽的前提是在目标元素按下鼠标左键。
2:当onmousedown发生以后,此刻给document添加onmousemove事件,意味着此刻鼠标在网页的移动都将改变目标元素的位置。
3:在onmousemove事件中,设定目标元素的left和top,公式:
目标元素的left = 鼠标的clientX – (鼠标和元素的横坐标差,即offsetX)
目标元素的top = 鼠标的clientY– (鼠标和元素的纵坐标差,即offsetY)。
4:当onmousedown发生以后,此刻给document添加onmouseup事件,意味着此刻鼠标在网页的任意位置松开鼠标,都会放弃拖拽的效果。
5:在onmouseup事件中,取消document的onmousemove事件即可。