龙空技术网

JavaScript知识整理(二)

Python程序员涵涵 267

前言:

此刻各位老铁们对“js键盘方向键”大概比较关怀,兄弟们都想要了解一些“js键盘方向键”的相关内容。那么小编在网摘上搜集了一些对于“js键盘方向键””的相关知识,希望看官们能喜欢,我们一起来了解一下吧!

mouseout和mouseleave的区别

二者都是鼠标移出。mouseout冒泡。 mouseleave不冒泡。(出去冒泡,离开不冒泡)

mouseout对应上面的mouseover ,mouseleave对应上面的mouseenter。

注册事件的第二种方法(监听法)

就是谁发生、怎么发生、发生了什么 的第二种表达方式。

谁发生.addEventListener(怎么发生,发生了什么的函数)
怎么发生:这里的触发事件不带on,比如click发什么了什么的函数: function() { 要发生的事情 };
//例如上面的唐伯虎点秋香例子btn.addEventListener('click', function() {	alert('点秋香');})
节点操作01改变元素内容
element.innerText//从起始位置到终止位置的内容。但它去除html标签,同时空格和换行也会去掉
element.innerHTML//起始位置到终止位置的全部内容,包括html标签,同时保留空格和换行
innerText 和 innerHTML的区别innerText 不识别html标签 非标准 去除空格和换行innerHTML 识别html标签 按照W3C标准 保留空格和换行这两个属性都是可读写的,可以获取元素里面的内容。例如:
<p>2333</p><script>	var p = document.getElementByTagName('p');	console.log(p.innerText);	console.log(p.innerHTML);</script>

常见元素的属性操作

三种操作情况:

innerText 、innerHTML 改变元素内容

src、 href

id、alt、title

表单元素的属性操作

利用DOM可以操作如下表单元素的属性:

type , value , checked , selected , disabled

<body>	<button>按钮</button>	<input type="text" value="输入内容" />	<script>		//1,获取元素		var btn = document.querySelector('button');		var inp = document.querySelector('input');		//2,注册事件--谁发生 怎么发生 发生什么		btn.addEventListener('click', function() {		//inp.innerHTML = '被点击了'; 这个是 普通盒子 比如div标签里面的内容被修改,不是value里的内容被改变		//表单里面的值 文字内容是通过valve来修改的			inp.value = '我被点击了';		//如果想要某个表单被禁用,不能重复点击disabled 我们想要这个按钮 button禁用		//btn.disbled = true; 这样就被禁用了		this.disabled = true;//这里的this就是btn,因为是btn发生的,这里的this就特指btn了。		//this指向的是发生的那个元素 btn		})	</script></body>

案例:京东登陆界面的密码表单输入密码时,默认不显示密码。点击小眼睛图标时,显示密码。再点击又不显示密码。

//2,注册事件 谁发生 怎么发生 发生什么var flag = 0;eye.addEventListener('click', function() {	//每次点击 flag一定要变化	if(flag == 0) {		pwd.type = 'text';		eye.src = '---';		flag = 1;//这里就是要变化了。原来是0,这里就要变成1	} else {			pwd.type = 'password';			eye.src = '---';			flag = 0;//这里又变化了。原来是1,点过一次就变成0了		}})

样式属性操作

我们可以通过JS修改元素的大小、颜色、位置等样式。

element.style = ’ ';行内样式操作

element.className 类名样式操作

注意:

JS 里面的样式采取驼峰命名法 比如 fontSize , backgroundColor 。注意,这里没有连接的 - 了。

JS修改style 样式操作,产生的是行内样式,css权重比较高。

className 会直接更改元素的类名,会覆盖原先的类名。

第3条里,如果原来的类名还想保留,那就可以这样做,假如原来的类名是class=‘first’ ,现在要用的是class='change’并且不想把原来的first类型替换掉,那就写成 元素.className = ‘first change’ 就阔以了。

<body>	<div></div>	<script>		//1,获取元素		var div = document.querySelector('div');		//2,注册事件。谁发生 怎么发生 发生什么		div.onclick = function() {			//div.style里面的属性  采取驼峰命名法			this.style.backgroundColor = 'purple';			this.style.width = '200px';		}	</script></body>

这里是this是指向函数的调用者,即div在调用这个函数。 相当于div.style (如上图的div)

如果调用者不是当前的元素,就不能用this了。(如下图function里的box.style 就不能写成this.style)

因为是btn在调用函数,然后让box产生变化。 如果用了this,就是指btn在发生变化了。所以这里不能用this。

当一个元素需要更改的样式较多时,适合用element.className来完成。

<head><style>.change {	background-color: purple;	color: #fff;	font-size: 25px;	margin-top: 100px;}</style></head><body>	<div>文本</div>	<script>		//当元素样式较多或者功能复杂的情况下,		//使用element.className获得修改元素样式,		var div = document.querySelector('div');		div.onclick = function() {			this.className = 'change';		}	</script></body>
JS排他思想

如果有同一组元素,我们想要其中一个元素实现某种样式的情况下,不想让其他同样的元素跟着实现这种样式,就需要用到循环的排他思想算法:

所有元素全部清除样式(干掉其他人)给当前元素设置样式(留下我自己)注意顺序不能颠倒。首先干掉其他人,再设置自己。

<ul class='baidu'>	<li><img src='1' /></li>	<li><img src='1' /></li>	<li><img src='1' /></li></ul><script>	//1,获取元素 	var imgs = document.querySelector('.baidu').querySelectorAll('img');	//console.log(imgs);	//2,循环注册事件	for(var i = 0; i < imgs.length; i++) {		imgs[i].onclick = function() {		//this.src 就是我们点击的图片的路径		//console.log(this.src);		//把这个路径this.src给body就可以了			document.body.style.backgroundImage = 'url(' + this.src + ')';		}	}</script>

说白了,就是先让包括自己的所有人都不显示,然后再让自己显示。 这样在自己显示的时候,别人就不显示了。

全选反选案例:

<script>	//1,全选和取消全选的做法: 	//让下面所有复选框的checked属性(选中状态) 跟随 全选按钮即可	//获取元素	var j_acAll = document.getElementById('j_cbAll');	var j_tbs = document.getElementById('j_tb').getElementByTagName('input');	//即 选出下面所有的复选框	//注册时间 谁发生 怎么发生 发生什么	j_cbAll.onclick = function() {		//this.checked 它可以得到当前复选框的选中状态 		//如果是true 就是选中, 如果是false 就是未选中		console.log(this.checked);		for(var i = 0; i < j_tbs.length; i++) {			j_tbs[i].checked = this.checked;		}	}	//2,下面的复选框需要全部选中,上面全选才能选中做法:	//给下面所有复选框绑定点击事件,每次点击,都要循环看是否都选中了	for(var i = 0; i < j_tbs.length; i++) {		j_tbs[i].onclick = function() {			//flag控制全选按钮是否选中			var flag = true;			//每次点击下面的复选框都要循环检查这4个小按钮是否全被选中			for(var i = 0; i < j_tbs.length; i++) {				if( !j_tbs[i].checked) {					flag = false;					break;				//退出for循环 这样可以提高运行效率				//因为只要一个没有选中,剩下的就无需再循环判断了				}			}			j_cbAll.checked = flag;		}	}</script>//每次点击,都要循环

操作属性

自定义属性的操作

获取属性值

element.属性 获取属性值作用:获取内置属性值,即元素本身自带的属性element.getAttribute(‘属性’);作用:可以获得原有属性值,也可以获得自定义的元素值。主要获取自定义的属性 (标准) 我们程序员自定义的属性。

获取、设置、移除元素属性的应用例子:

<body>	<div id="demo" index="1"></div>	<script>		var div = document.querySelector('div');		//1,获取元素的属性值		//(1)element.属性		console.log(div.id);//demo		//(2)element.getAttribute('属性')		//程序员自己添加的属性,我们称为自定义属性,比如这里的 index		console.log(div.getAttribute('id'));//demo		console.log(div.getAttribute('index'));//1		//2,设置元素的属性值		//(1)element.属性 = ‘值’;		div.id = 'test';		div.className = 'navs';		//(2)element.setAttribute('属性','值');		//主要针对自定义属性		div.setAttribute('index', 2);		div.setAttribute('class', 'footer');		//class特殊 这里写的就是class 不是className		//3,移除属性 element.removeAttribute('属性');		div.removeAttribute('index');	</script></body>
属性操作案例(必须会写)
<script>	//获取元素	var tab_list = document.querySelector('.tab_list');	var lis = tab_list.querySelectorAll('li');	var items = document.querySelectorAll('.item');	//for循环绑定点击事件	for(var i = 0; i < lis.length; i++) {		//开始给5个小li设置索引号index		lis[i].setAttribute('index',i);		lis[i].onclick = function() {			//1,上面的模块选项卡,点击某一个,当前这个底色会是红色,其他选项卡不变色。			//所以用到排他思想。干掉所有人,其余的li清除class这个类			for(var i = 0; i < lis.length; i++) {         						lis[i].className = '';					}			//留下我自己			this.className = 'current';			//2,下面的显示内容模块			var index = this.getAttribute('index');			console.log(index);			//干掉所有人 让其余的item 这些div 隐藏			for(var i = 0; i < items.length; i++) {				items[i].style.display = 'none';			}			//留下我自己 让对应的item显示出来			items[index].style.display = 'block';		}	}</script>

关于自定义属性

H5自定义属性

自定义属性目的:是为了保存并使用数据。有些数据可以保存到页面中而不用保存到数据库中。

1.设置H5自定义属性

H5规定自定义属性data- 开头做为属性名并且赋值。说白了就是,自定义属性要用data- 做开头。比如:

<div data-index="1"></div>

或者使用JS设置:

element.setAttribute('data-index', 2)
2.获取H5自定义属性

1,element.getAttribute(‘data-index’) 兼容性好

2,H5新增 element.dataset.index 或者element.dataset[‘index’] , ie11才开始支持,而且只能取data- 开头的自定义元素属性。

如果自定义属性里有多个 - 连接的单词,我们获取的时候,采取驼峰命名法。如 div.dataset.listName 或 div.dataset[‘listName’]

节点操作02

网页中的所有内容都是节点(标签,属性,文本,注释,空格等),在DOM中,节点使用node来表示。

HTML DOM树中的所有节点均可通过JS进行访问,所有HTML元素(节点)均可被修改,也可以创建或删除。

一般地,节点至少拥有nodeType(节点类型),nodeName(节点名称)和nodeValue(节点值)这三个基本属性。

元素节点 nodeType 为1属性节点 nodeType 为2文本节点 nodeType 为3(文本节点包含文字,空格,换行等)

我们实际开发中,节点操作主要操作的是元素节点。

节点层级

利用DOM树可以把节点划分为不同的层级关系,常见的是父子兄弟层级关系。

1,父级节点

node.parentNode
parentNode属性可返回某节点的父节点,注意是最近的一个父节点(亲爸爸)。如果指定的节点没有父节点,则返回null。
<div class="demo">	<div class="box">		<span class="erweima">X</span>	</div></div><script>	//1,父节点parentNode	var erweima = document.querySelector('.erweima');	//var box = document.querySelector('.box');	//得到的是离元素最近的父级节点(亲爸爸)	//如果找不到父节点,就返回null	console.log(erweima.parentNode);</script>
2,子节点

有两种获得方式,标准和非标准。

第一种: parentNode.childNodes(标准)//虽然是标准的,但是不提倡使用

parentNode.childNodes 返回包含指定节点的子节点的集合。该集合为即时更新的集合。

注意:返回值里面包含了所有的子节点,包括元素节点,文本节点(文字,空格,换行等)等。

如果只想要获得里面的元素节点,则需要专门处理。所以我们**一般不提倡使用childNodes** 。 专门处理需要的代码:

var ul = document.querySelector('ul');for(var i = 0; i < ul.childNodes.length; i++) {	if(ul.childNodes[i].nodeType == 1) {		//即 ul.childNodes[i]是元素节点		console.log(ul.childNodes[i];	}}
第二种: parentNode.children(非标准)//虽然是非标准,但是可以得到我们想要的元素节点,//所以推荐使用这个

parentNode.children是一个只读属性,返回所有子元素节点,其余节点不返回。所以重点掌握这个方法。

获取 第一个子元素和最后一个子元素

实际开发中,firstChild 和 lastChild 包含其他节点,操作不方便,而firstElementChild 和 lastElementChild又有兼容性问题。那么我们如何获取第一个子元素节点或最后一个子元素节点呢?

解决方案:

1.获取第一个子元素节点, parentNode.children[0];

2,获取最后一个子元素节点,

parentNode.children[parentNode.children.length - 1]

这样既可以获得想要的元素节点,又不存在兼容性问题。

节点操作案例:

<script>	//1,获取元素	var nav = document.querySelector('.nav');	var lis = nav.children;//得到4个小li	//2,注册循环事件 点谁谁发生	for(var i = 0; i < lis.length; i++) {		lis[i].onmouseover = function() {			this.children[i].style.display = 'block';		}		lis[i].onmouseout = function() {			this.children[i].style.display = 'none';		}	}</script>
节点层级--兄弟节点node.nextSibling返回当前元素的下一个兄弟节点,找不到则返回null 。同样,也是包含所有的节点。node.previousSibling返回当前元素上一个兄弟节点,找不到则返回null。同样,也包含所有的节点。node.nextElementSibling返回当前元素下一个兄弟元素节点,找不到则返回null。node.previousElementSibling返回当前元素的上一个兄弟元素节点,找不到则返回null。

1和2 取兄弟节点的时候,会把空格文本节点也取到。不适合用。

3和4取出来的确实是想要的兄弟节点,但是会有兼容性问题。

如何解决兼容性问题?

需要自己封装一个函数。

function getNextElementSibling(element) {	var el = element;	while(el == el.nextSibling) {		if(el.nodeType === 1) {			return el;		}	}	return null;}

不过兄弟节点用的较少。

创建元素节点

document.createElement('tagName');

创建 由tagName指定的HTML元素。因为这些元素原先不存在,是根据我们的需求 动态生成的,所以我们也称为动态创建元素节点。

添加节点:先创建,后添加node.appendChild(child)将一个节点添加到指定父节点的子节点列表末尾。类似于css里面的after伪元素。node是父节点,child是子级。node.insertBefore(child,指定元素)将一个节点添加到父节点的指定子节点前面。类似于css里面的before伪元素。

<body>	<ul>		<li>2333</li>	</ul>	<script>		//1,创建元素节点		var li = document.createElement('li');		//2,添加后节点 node.appendChild(child)		var ul = document.querySelector('ul');		ul.appendChild(li);		//添加前节点 node.insertBefore(child,指定元素);		var lili = document.creatrElement('li');		ul.insertBefore(lili,ul.children[0]);	</script></body>
发布留言板案例:
<body>	<textarea name="" id=""></textarea>	<button>发布</button>	<ul>	</ul>	<script>		//1,获取元素		var btn = document.querySelector('button');		var text = document.querySelector('textarea');		var ul = document.querySelector('ul');		//2,注册事件 谁发生 怎么发生 发生什么		btn.onclick = function() {			if(text.value == "") {				alert('内容不能为空!');				return false;			} else {					//(1)创建元素节点					var li = document.createElement('li');					//先创建li 才能赋值					li.innerHTML = text.value;					//(2)添加节点					ul.insertBefore(li,ul.children[0]);				}		}	</script></body>
删除子节点
node.removeChild(child)//举例:ul.removeChild(ul.children[0]);

从DOM中删除一个子节点,返回删除的节点。

复制(克隆)节点:先克隆,再添加

node.cloneNode()//返回调用该方法的节点的一个副本。//这里的node是要被克隆的那个元素节点

注意:

如果括号参数为空或者false,则是浅克隆,即只克隆节点本身,不克隆里面的子节点。如果括号里面的参数为true,则是深克隆,会复制节点本身以及里面所有的子节点。

<body>

三种动态创建元素的区别

document.write()element.innerHTMLdocument.createElement()

区别:

document.write()是直接将内容写入页面的内容流,但是文档流执行完毕,它会导致页面全部重绘。innerHTML是将内容写入某个DOM节点,不会导致页面全部重绘。innerHTML创建多个元素效率更高,不需要拼接字符串,采取数组形式拼接,结构稍微复杂。createElement()创建多个元素效率稍微低一点点,但是结构更清晰。

<!DOCTYPE html><html>	<head>		<meta charset="uft-8" />	</head>	<body>		<button>点击</button>		<div class="inner"></div>		<ul class="create"></ul>		<script>			//1,document.write()创建元素				var btn = document.querySelector('button');				btn.onclick = function() {					document.write('<div>2333</div>');				}				//2,innerHTML 创建元素				var inner = document.querySelector('.inner');				var arr = [];				for(var i = 0; i <= 10; i++) {					arr.push('<a href="">233</a>');				}				inner.innerHTML = arr.join(' ');				//3,document.createElement()创建元素				var create = document.querySelector('.create');				for (var i = 0; i <= 10; i++) {					var li = document.createElement('li');					create.appendChild(li);				}		</script>	</body></html>
DOM事件流事件流描述的是从页面中接收事件的顺序。事件发生时,会在元素节点之间按照特定的顺序传播,这个传播过程就是DOM事件流。

事件冒泡:IE最早提出,事件开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点的过程。

事件捕获:网景最早提出,由DOM最顶层节点开始,然后逐级向下传播到最具体的元素接收的过程。

注意:

1,JS代码中只能执行捕获或者冒泡其中的一个阶段。二者只能选其一。

2,onclick和attachEvent只能得到冒泡阶段。

3,addEventListener()中function()后面的参数,如果是true,表示在事件捕获阶段条用事件处理程序;如果是不写参数或者参数是false,表示在事件冒泡阶段调用事件处理程序。

4,实际开发中我们很少使用事件捕获,我们更关注事件冒泡。

5,有些事件是没有冒泡的,比如 onblur,onfocus,onmouseenter,onmouseleave。

事件对象

什么是事件对象?

eventTarget.onclick = function(event) { };或eventTarget.addEventListener('click', function(event) { })//这个event就是事件对象。可以写成e或者evt。//这个参数在前面学习中是没有写出来的。

官方解释:event对象代表事件的状态,比如键盘按键的状态,鼠标的位置,鼠标按钮的状态。

简单理解:事件发生后,跟事件相关的一系列信息数据的集合都放到这个对象里面,这个对象就是事件对象event,它有很多属性和方法。

比如:

1,谁绑定了这个事件。

2,鼠标触发事件的话,会得到鼠标的相关信息,如鼠标位置。

3,键盘触发事件的话,会得到键盘的相关信息,如按了哪个键。

这个event是个形参,系统帮我们设定为事件对象,不需要传递实参过去。

当我们注册事件时,event对象就会被系统自动创建,并依次传递给事件监听器(即事件处理函数)。

兼容性问题

事件对象的兼容性方案

事件对象本身的获取存在兼容性问题:

1,标准浏览器中是浏览器给方法传递的参数,只需要定义形参3 就可以获得到。 2,在IE6~8中,浏览器不会给方法传递参数,如果需要的话,需要到window.event中获取查找。

解决:

e = e || window.event;

阻止事件冒泡的两种方式

事件冒泡:开始时由最具体的元素接收,然后逐级向上传播到DOM最顶层节点。

事件冒泡本身的特性,会带来坏处,也会带来好处,需要我们灵活掌握。

阻止事件冒泡标准写法:利用事件对象里面的e.stopPropagation()方法非标准写法:IE6-8使用。 利用事件对象cancelBubble属性。

常用的是标准写法。IE浏览器因为兼容问题,不经常用。如果用了非标准写法,可以调试一下兼容性:

if(e && e.stopPropagation) {	e.stopPropagation();} else {	window.event.cancelBubble = true;	}

用法:

<body>	<div class="father">		<div class="son">son儿子</div>	</div>	<script>		//常见事件对象的属性和方法		//阻止冒泡 dom 推荐的标准 stopPropagation()		var son = document.querySelector('.son');		son.addEventListener('click', function(e) {		alert('son');		e.stopPropagation();//停止传播		e.canselBubble = true;//非标准 取消泡泡},false);var father = document.querySelector('.father');father.addEventListener('click', function() {	alert('father');	},false);document.addEventListener('click', function() {	alert('document');}	</script></body>
事件委托

事件委托也称为事件代理,在jQuery里面称为事件委派。

事件委托的原理

不是每个子节点单独设置事件监听器,而是事件监听器在其父节点上,然后利用冒泡原理影响设置每个子节点。

比如,给ul注册点击事件,然后利用事件对象的target来找到当前点击的li,因为点击li,事件会冒泡到ul上,ul有注册事件,就会触发事件监听器。

事件委托的作用

我们只操作了依次DOM,提高了程序的性能。

<body>	<ul>		<li>2333</li>		<li>2333</li>		<li>2333</li>		<li>2333</li>	</ul>	<script>		//事件委托的核心原理:给父节点添加监听器,		//利用事件冒泡影响每一个子节点。		var ul = document.querySelector('ul');		ul.addEventListener('click', function(e) {			//alert('2333');			//e.target 可以得到我们点击的对象			e.target.style.backgroundColor = 'pink';		})	</script></body>
鼠标事件对象

event对象代表事件的状态,跟事件相关的一系列信息的集合。现阶段我们主要是用鼠标事件对象mouseevent和键盘事件对象keyboardevent。

<style>	img {		position: absolute;		top: 2px;	}</style><body>	<img src=''>	<script>		var pic = document.querySelector('img');		document.addEventListener('mousemove', function(e) {		var x = e.pageX;		var y = e.pageY;		console.log(x, y);//输出x 和 y坐标		//千万不要忘记给left和top添加px单位!		pic.style.left = x + 'px';		pic.style.top = y + 'px';		});	</script></body>
常用的键盘事件注意:1,如果使用addEventListener,就不需要加on2,三个事件的执行顺序是: keydown-keypress-keyup

键盘事件对象

注意:onkeydown和onkeyup不区分字母大小写,onkeypress区分字母大小写。

在我们实际开发中,我们更多的使用keydown和keyup,它能识别所有的键(包括功能键)

Keypress不识别功能键,但是keyCode属性能区分大小写,返回不同的ASCII值。

注意:keydown和keyup在文本框里面的特点:他们两个事件触发的时候,文字还没有落入文本框中。keyup事件触发的时候,文字已经落入文本框里面了。因为键已经松开了。

案例:按下s键,搜索框获得焦点

<body>	<input type="text">	<script>		//核心思路:检测用户是否按下了s键。		//如果按下了s键,就把光标定位到搜索框里面。		//使用键盘事件对象里面的keyCode,		//判断用户按下的是否是s键。		//搜索框获得焦点:使用js里面的focus()方法		var sch = document.querySelector('input');		document.addEventListener('keyup', function(e) {			if(e.keyCode == 83) {				sch.focus();			}		})	</script></body>

--------------------DOM---end------------------------

BOM浏览器对象模型

什么是BOM?

BOM(Brower Object Model)即浏览器对象模型。它提供了独立于内容而与浏览器窗口进行交互的对象,其核心对象是window 。

BOM由一系列相关的对象构成,并且每个对象都提供了很多方法和属性。

BOM缺乏标准,JS语法的标准化阻止是ECMA,DOM的标准化组织是W3C,BOM最初是Netscape(就是网景公司)浏览器标准的一部分。

BOM构成

BOM比DOM更大,它包含DOM。

window对象是浏览器的顶级对象。它具有双重角色。

1,它是JS访问浏览器窗口的一个接口。

2,它是一个全局对象。定于在全局作用域中的变量和函数都会变成window对象的属性和方法。

在调用的时候可以省略window,前面学习的对话框都属于window对象方法,比如alert() ,prompt()等。

注意:window下的一个特殊属性 window.name

window对象的常用事件

窗口加载事件

这样就可以把js放在任何一个地方了,js代码都会执行了。

window.onload = function() { }或者window.addEventListener('load', function() { })(推荐使用,因为没有次数限制)

window.onload是窗口(页面)加载事件,当文档内容完全加载完成时会触发该事件(包括图像,脚本文件,css文件等),就会调用处理函数。

注意:

1,有了window.onload就阔以把JS代码写在页面元素的上方,因为onload是等页面内容全部加载完毕,再去执行处理函数的。

2,window.onload传统注册事件方式只能写一次,如果有多个,会以最后一个window.onload为准。

3,如果使用window.addEventListener则没有限制。

另一种情况:(加载较慢的情况)

document.addEventListener('DOMContenLoaded', function() { })

DOMContentLoaded事件触发时,仅当DOM加载完成时,不包括样式表,图片,flash等等。

IE9以上才支持。

如果页面的图片很多的话,从用户访问到onload触发可能需要较长的事件,交互效果就不能实现,必然影响用户的体验,此时用DOMContentLoaded事件比较合适。

调整窗口大小事件

window.onresize = function() {}window.addEventListener('resize', function() {})

window.onresize是调整窗口大小加载事件,当触发时就调用的处理函数。注意:1,只要窗口大小发生像素变化,就会触发这个事件。2,我们经常利用这个事件完成响应式布局。window.innerWidth是当前屏幕的宽度。

两种定时器第一种定时器:setTimeout()定时器

window.setTimeout(调用函数,延迟的毫秒数);

setTimeout()方法用于设置一个定时器,该定时器在定时器到期后执行调用函数。

注意:

1,window可以省略。

2,这个调用函数可以直接写函数,或者写函数名, 或者 '函数名()'三种形式。但是不推荐最后一种写法。

3,延迟的毫秒数可以省略,默认是0,如果写,必须是毫秒数。不需要带单位。

4,因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。

//语法规范: window.setTimeout(调用函数,延迟时间);//setTimeout(function() {//	console.log('午时已到');//}, 2000);function callback() {	console.log('立即斩首');}setTimeout(callback, 3000);

回调函数 callback

window.setTimeout(调用函数,延迟的毫秒数);

setTimeout()这个调用函数,我们也称为回调函数callback。

普通函数是按照代码顺序直接调用。

而这个函数,需要等待时间,时间到了才能取调用这个函数,因此我们称为回调函数。

简单理解:回调,就是回头调用的意思。上一件事干完,再回头调用这个函数。

以前讲的element.onclick = function() {}或者element.addEventListener(‘click’, fn);里面的函数也是回调函数。

停止定时器(让定时器停下来,别执行函数里的程序了)

clearTimeout(定时器名字);

window.clearTimeout(timeout ID)

注意:1,window可以省略。2,里面的参数就是定时器的标识符。

第二种定时器 setInterval()

window.setInterval(回调函数,间隔的毫秒数);

setInterval()方法重复调用一个函数,每隔这个时间,就去调用一次回调函数。

这是与setTimeout()最大的不同。setTimeout()定时器只调用一次回调函数。

注意:

1,window可以省略。

2,这个调用函数可以直接写函数,或者函数名或者采用字符串 ’ 函数名() ’ 三种形式。

3,间隔的毫秒数可以省略,默认是0,如果写,必须是毫秒数,不用带单位。

4,因为定时器可能有很多,所以我们经常给定时器赋值一个标识符。

案例:自动倒计时

<body>	<div>		<span class="hour">1</span>		<span class="minute">2</span>		<span class="second">3</span>	</div>	<script>		//1,获取元素		var hour = document.querySelector('.hour');		var minute = document.querySelector('.minute');		var second = document.querySelector('.second');		var inputTime = +new Date('2019-5-1 18:00:00');//用户输入时间总的毫秒数		countDown();//现调用一次函数,防止第一次刷新页面出现空白		//2,开启定时器		setInterval(countDown, 1000);		function countDown() {			var nowTime = +new Date();			//返回的是当前时间总的毫秒数			var times = (inputTime - nowTime) / 1000;			//times是剩余需要倒计时的总的秒数			var h = parseInt(times / 60 / 60 / % 24);//小时			h = h < 10 ? '0' + h: h;			//格式搞的好看一点			hour.innerHTML = h ;			//把倒计时的小时数给小时盒子			var m = parseInt(times / 60 % 60);//分钟			m = m < 10 ? '0' + m: m;			minute.innerHTML = m;			var s = parseInt(times % 60);//秒			s = s < 10 ? '0' + s: s;			second.innerHTML = s;		}	</script></body>

案例:发送短信验证

JS执行机制

JS是单线程:同一时间只做一件事。代码是从上到下一行一行的执行。

同步和异步: 最新的js可以创建多个任务了。

为了解决这个问题,利用多核CPU的计算能力,HTML5提出Web Worker 标准,允许JS脚本创建多个线程。于是,JS中 出现了同步和异步。

同步

前一个任务结束后再执行后一个任务,程序的执行顺序与任务排列顺序是一直的,同步的。比如做饭的同步做法:我们要烧水煮饭,等水开了(10分钟后),再去切菜,炒菜。

异步

在做一件事情时,因为这件事情会话费很长时间。在做这件事情的同时,还可以去处理其他事情。比如做饭的异步做法,在烧开水的同时,利用这10分钟,去切菜,炒菜。

同步任务

同步任务都在主线程上执行,形成一个执行线。

异步任务

JS的异步是通过回调函数实现的。 一般而言,异步任务有以下三种类型: 1,普通事件,如click,resize等 2,资源加载,如load,error等 3,定时器,包括setTimeout,setInterval等。

异步任务相关回调函数添加到任务队列中,任务队列也称为消息队列。

执行机制:任务分成同步任务和异步任务。先执行完同步任务,再去执行异步任务。

1,先执行执行栈中的同步任务。

2,异步任务(回调函数)放入任务队列中。

3,一旦执行栈中的所有同步任务执行完毕,系统就会按照次序读取任务队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。

由于主线程不断的重复获得任务、执行任务、再获取任务、再执行,所以这种机制被称为事件循环(event loop)。

location对象

URL

统一资源定位符(Uniform Resource Locator,URL)是互联网上标准资源的地址。互联网上的每个文件都有一个唯一的URL,它包含的信息指出文件的位置以及浏览器应该怎么处理它。

URL的一般语法格式为:

protocol://host[:port]/path/[?query]#fragment如:

location对象的属性案例:获取URL参数数据:数据在不同网页中传递

第一个页面:输入信息的界面

<body>	<form action="index.html">		用户名:<input type="text" name="uname">		<input type="submit" value="登录" />	</form></body>

第二个页面:接收信息的界面

<body>	<div></div>	<script>		console.log(location.search);//?uname=andy		//1,先去掉? substr('起始位置', 截取几个字符);		var params = location.search.substr(1);//uname=andy		//2,利用 = 号把字符串分割为数组 split('=');		var arr = params.split('=');		console.log(arr);//["uname", "ANDY"]		var div = document.querySelector('div');		//3,把数据写入div中		div.innerHTML = arr[1] + "欢迎您";	</script></body>
location对象的方法navigator对象:知道用户用了什么浏览器

navigator对象包含有关浏览器的信息,它有很多属性,我们最常用的是userAgent,该属性可以返回由客户机发送服务器的user-agent头部的值。

下面前端代码可以判断用户哪个中断打开的页面,实现跳转:

if((navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobild|BlackBerry|IEMobild|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i)) {window.location.href = ""; //手机} else {	window.location.href = ""; //电脑}//把这个代码赋值到<script></script>里面就阔以了。//要查哪个网页地址,就把地址补齐到href里。

window对象给我们提供了一个history对象,与浏览器历史纪录进行交互。该对象包含用户(在浏览器窗口中)访问过的URL。

history.back();history.forward();history.go(1);

PC网页端特效

知识点:

offsetclientscroll封装简单动画函数网页轮播图offset系列属性

offset翻译过来就是偏移量,我们使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。

获得元素举例带有定位父元素的位置获得元素自身的大小(宽度高度)注意:返回的数值都不带单位

offset系列常用属性:

offset翻译过来就是偏移量,我们使用offset系列相关属性可以动态的得到该元素的位置(偏移)、大小等。

获得元素举例带有定位父元素的位置获得元素自身的大小(宽度高度)注意:返回的数值都不带单位

offset系列常用属性:

只有上和左,没有下和右。

offset和style的区别案例:获取鼠标在盒子内的动态位置

![在这里插入图片描述]()

元素可视区client系列

client翻译过来就是客户端,我们使用client系列的相关属性来获取元素在可视区的相关信息。通过client系列的相关属性可以动态的得到该元素的边框大小、元素大小等。

注意和offset的区别。clientWidth是不含边框的。

立即执行函数

<body>	<script>		//1,立即执行函数:不需要调用,立马能够子级执行的函数		function fn() {			console.log(1);		}		fn();		//2,写法也可以传递参数进来		//(function() {})()或者(function() {}())		(function(a, b) {			console.log(a + b);			var num = 10;		})(1, 2);//第二个小括号可以看作是调用函数		(function sun(a, b) {			console.log(a + b);			var num = 10;//局部变量		}(2, 3));		//3,立即执行函数最大的作用就是 独立创建了一个作用域,		//里面所有的变量都是局部变量,不会右命名冲突的情况。	</script></body>
元素滚动scroll系列

scroll翻译过来就是滚动的,我们使用scroll系列的相关属性可以动态的得到该元素的大小、滚动距离等。

常用的是 element.scrollTop和element.scrollLeft。

window.pageXOffset 和 window.pageYOffset属性,返回文档在窗口左上角水平和垂直方向滚动的像素。

pageXOffset设置或返回当前网页相对于窗口显示区左上角的X位置。pageYOffset设置或返回当前页面相对于窗口显示区左上角的Y位置。

pageXOffset 和pageYOffset属性相当于scrollX和scrollY属性。

这些属性是只读的。

页面被卷去 的头部兼容性解决方案

需要注意的是,页面被卷去的头部,有兼容性问题,因此被卷去的头部通常有如下几种写法:

声明了DTD,使用document.documentElement.scrollTop未声明DTD,使用document.body.scrollTop新方法window.pageYOffset和window.pageXOffset , IE9开始支持。

function getScroll() {	return {	left: window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft || 0,	top: window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop || 0,	}}//使用的时候 getScroll().left
动画函数封装动画实现原理:

实现步骤:

获得盒子当前的位置让盒子在当前位置加上1个移动距离利用定时器不断重复这个操作加一个结束定时器的条件注意:此元素需要添加定位,才能使用element.style.left

因为要让盒子脱离标准流,所以要添加定位。

函数封装:

<script>	//简单动画函数封装obj目标对象 target 目标位置	function animate(obj, target) {		var timer = setInterval(function() {			if (obj.offsetLeft >= target) {			//运动到一定距离,就停止计时器				clearInterval(timer);			}			obj.style.left = obj.offsetLeft + 1 + 'px';		}, 200);	}	var div = document.querySelector('div');	//调用函数	animate(div, 300);</script>
动画函数给不同元素记录不同定时器

如果多个元素都使用这个动画函数,每次都要var声明定时器。我们可以给不同元素使用不同的定时器(自己专门用自己的定时器)

核心原理:利用JS是一门动态语言,可以很方便的给当前对象添加属性。

<script>	//var obj = {};	//obj.name = 'andy';	//简单动画函数封装obj是目标对象 target 是目标位置	//给不同的元素指定了不同的定时器	function animate(obj, target) {		obj.timer = setInterval(function() {			if(obj.offsetLeft >= target) {				clearInterval(obj.timer);			}				obj.style.left = obj.offsetLeft + 1 + 'px';		}, 200);	}	var div = document.querySelector('div');	var span = document.querySelector('span');	//调用函数	animate(div,300);	animate(span, 200);</script>

改进版:

<script>	//当我们不断的点击按钮,这个元素的速度会越来越快,因为开启了太多的定时器	//解决方案就是 让我们元素只有一个定时器执行	//先清除以前的定时器,只保留当前一个定时器执行	clearInterval(obj.timer);	function animate(obj, target) {		obj.timer = setInterval(function() {			if(obj.offsetLeft >= target) {				clearInterval(obj.timer);			}				obj.style.left = obj.offsetLeft + 1 + 'px';		}, 200);	}	var div = document.querySelector('div');	var span = document.querySelector('span');	//调用函数	animate(div,300);	animate(span, 200);</script>
案例:淘宝网页轮播图,也叫焦点图节流阀

防止轮播图按钮连续点击造成播放过快。

节流阀目的:当 上一个函数动画内容执行完毕,再去执行下一个函数动画,让事件无法连续触发。

核心思路:利用回调函数,添加要给变量来控制,锁住函数和解锁函数。

//开始设置一个变量 var flag = true;if(flag) {	flag = false;	do something...//关闭水龙头}//利用回调函数,动画执行完毕后,flag = true;//打开水龙头
案例:淘宝侧边栏的返回顶部

window.scroll(x,y) 整个窗口滚动到文档中的特定位置。

x是距离文档左边的距离,y是距离文档顶部的距离。x和y都不带单位。

标签: #js键盘方向键