Danmo的学习之路(JavaScript基础_下)

DOM

简介

注意,文本节点的nodeValue是文本内容,如果获取了文本节点想查看它的内容,不用innerHTML或者innerText属性,而是nodeValue,不过这种方法用的不多。

事件:用户和浏览器之间的交互行为,比如:点击按钮,鼠标移动、关闭窗口。

JavaScript 事件参考手册

获取对象

	<button id="btn">我是一个按钮</button>
	<script type="text/javascript">
	//获取按钮对象
	var btn = document.getElementById("btn");
	//修改按钮的文字
	btn.innerHTML = "I'm Button";		

触发事件执行代码的2种写法

1.结构和行为耦合

<button id="btn" onclick="alert('讨厌,你点我干嘛!');">我是一个按钮</button>
 <!--点击按钮弹出警告框-->

2.分离式写法(推荐)

	<button id="btn">我是一个按钮</button>
	<script type="text/javascript">
		//获取按钮对象
		var btn = document.getElementById("btn");
		//绑定一个单击事件
		//像这种为单击事件绑定的函数,称为单击响应函数
		btn.onclick = function(){
			alert("你还点~~~");
			};			
	</script>	

文档的加载onload

浏览器在加载一个页面时,是按照自上向下的顺序加载的,读取到一行就运行一行,如果将script标签写到页面的上边,在代码执行时,页面还没有加载,页面没有加载DOM对象也没有加载,会导致无法获取到DOM对象

onload事件会在整个页面加载完成之后才触发。为window绑定一个onload事件,该事件对应的响应函数将会在页面加载完成之后执行,这样可以确保我们的代码执行时所有的DOM对象已经加载完毕了

	<head>
		<script type="text/javascript">
			window.onload = function(){
				//如果要写在上方的script标签内,就需要把内容写在window.onload函数中
				//获取id为btn的按钮
				var btn = document.getElementById("btn");
				//为按钮绑定一个单击响应函数
				btn.onclick = function(){
					alert("hello");
				};
			};
		</script>
	</head>
	<body>
		<button id="btn">点我一下</button>
	</body>

定义myClick

这部分本来应该在DOM查询中,但为方便查询,单独提取出来:

只需关注上方定义myClick函数的方式,以及下方调用时的括号问题

	function myClick(idStr , fun){
	 /*定义一个函数,专门用来为指定元素绑定单击响应函数
	 参数:
	 idStr 要绑定单击响应函数的对象的id属性值
	 fun 事件的回调函数,当单击元素时,该函数将会被触发
	 */
		var btn = document.getElementById(idStr);
		btn.onclick = fun;
	}
	myClick("btn",function(){
		//获取id为bj的节点
		var bj = document.getElementById("bj");
		
		//返回#bj的父节点
		var pn = bj.parentNode;
		
		alert(pn.innerHTML);})
		//注意此处括号的写法,之前一直理解错了...

DOM查询(难点)

getElementById

可以根据ID来获取一组元素节点对象

<li id="bj">北京</li>
var bj = document.getElementById("bj");
//查找#bj节点
alert(bj.innerHTML);
//innerHTML 通过这个属性可以获取到元素内部的html代码

innerHTML用于获取元素内部的HTML代码的,对于自结束标签(比如下边的input),这个属性没有意义

getElementsByTagName

可以根据标签名来获取一组元素节点对象
这个方法会给我们返回一个类数组对象,所有查询到的元素都会封装到对象中
即使查询到的元素只有一个,也会封装到数组中返回

<li>上海</li>
<li>东京</li>
<li>首尔</li>
var lis = document.getElementsByTagName("li");
for(var i=0 ; i<lis.length ; i++){
	alert(lis[i].innerHTML);
}
//遍历输出

getElementsByName

可以根据name来获取一组元素节点对象

如果需要读取元素节点属性,直接使用 元素.属性名
例子:元素.id 元素.name 元素.value

注意:class属性不能采用这种方式,读取class属性时需要使用 元素.className

gender:
<input class="hello" type="radio" name="gender" value="male"/>
Male
<input class="hello" type="radio" name="gender" value="female"/>
Female
<br>
<br>
name:
<input type="text" name="name" id="username" value="abcde"/>
var inputs = document.getElementsByName("gender");
for(var i=0 ; i<inputs.length ; i++){
	alert(inputs[i].className);
	//打印内容为hello
}

查找某个父节点下的子节点

	var btn05 = document.getElementById("btn05");
	btn05.onclick = function(){
		//获取id为city的节点
		var city = document.getElementById("city");
		//获取city下的li节点
		var lis = city.getElementsByTagName("li");
	};

childNodes

它是属性,表示包括文本节点在内的所有节点,标签间空白也会当成文本节点

注意:在IE8及以下的浏览器中,不会将空白文本当成子节点

获取包括文本节点在内的所有节点:

	var btn05 = document.getElementById("btn05");
	btn05.onclick = function(){
		//获取id为city的节点
		var game = document.getElementById("game");
		//获取city下的li节点
		var nds = city.childNodes;
	};

在这里插入图片描述
如果用childNodes获取game下的子节点数,会得到5个空白文本节点+4个li节点=9个节点

Children

children属性可以获取当前元素的所有子元素

以上方为例,可以得到4个li节点,而不会得到5个空白文本节点,故常常使用Children而不是childNodes

firstChild可以获取到当前元素的第一个子节点(包括空白文本节点)

firstElementChild获取当前元素的第一个子元素(不支持IE8及以下的浏览器)

12.21

parentNode

返回父节点

关于下方的函数:function()就指的是花括号内的函数,myClick函数的意思是,当单击后,会根据id获取相应的节点,然后调用花括号内的函数。

比如单击按钮后出现提示框,是alert的作用,alert就在花括号里面←这样会更好理解。

	function myClick(idStr , fun){
		var btn = document.getElementById(idStr);
		btn.onclick = fun;
	}
	
	myClick("btn07",function(){
		//获取id为bj的节点
		var bj = document.getElementById("bj");
		
		//返回#bj的父节点
		var pn = bj.parentNode;
		
		alert(pn.innerHTML);})	
  • innerText:该属性可以获取到元素内部的文本内容,它和innerHTML类似,不同的是它会自动将html去除。

previousSibling

previousSibling 获取前一个兄弟节点(也可能获取到空白的文本)

previousElementSibling获取前一个兄弟元素,IE8及以下不支持

读取/修改 value值

读取value属性值:
用户在文本框中填写的内容将出现在提示框内。

	myClick("btn09",function(){
		//获取id为username的元素
		var um = document.getElementById("username");
		//读取um的value属性值
		//文本框的value属性值,就是文本框中填写的内容
		alert(um.value);
	});

设置value属性值:
用户点击按钮后,文本框中的内容会变成"今天天气真不错"。

	//设置#username的value属性值
	myClick("btn10",function(){
		//获取id为username的元素
		var um = document.getElementById("username");
		
		um.value = "今天天气真不错~~~";
	});

12.22

获取body、html

body:

  • 法一:var body = document.getElementsByTagName(“body”)[0];
  • 法二:在document中有一个属性body,它保存的是body的引用
    var body = document.body;

html:document.documentElement保存的是html根标签

var html = document.documentElement;

all

document.all代表页面中所有的元素

var all = document.all;

document.all还有一种替代方案:all = document.getElementsByTagName("*");

getElementsByClassName

getElementsByClassName()可以根据class属性值获取一组元素节点对象,缺点是不兼容IE8

querySelector(重点)

document.querySelector()

  • document.querySelector()需要一个选择器的字符串作为参数,可以根据一个CSS选择器来查询一个元素节点对象
  • 但是可以使用querySelector()代替getElementsByClassName(),解决IE8的问题
  • 使用该方法总会返回唯一的一个元素,如果满足条件的元素有多个,那么它只会返回第一个

document.querySelectorAll()

  • 该方法和querySelector()用法类似,不同的是它会将符合条件的元素封装到一个数组中返回,即使符合条件的元素只有一个,它也会返回数组

DOM增删改

document.createElement()可以用于创建一个元素节点对象

需要一个标签名作为参数,将会根据该标签名创建元素节点对象,并将创建好的对象作为返回值返回

var li = document.createElement("li");

document.createTextNode()可以用来创建一个文本节点对象

需要一个文本内容作为参数,将会根据该内容创建文本节点,并将新的节点返回

var gzText = document.createTextNode("广州");

appendChild()向一个父节点中添加一个新的子节点

用法:父节点.appendChild(子节点);

li.appendChild(gzText);

上边三条可以成为一套“组合拳”,不过下边有替换方案

	//获取id为city的节点
	var city = document.getElementById("city");
	
	//将广州添加到city下
	city.appendChild(li);

insertBefore()可以在指定的子节点前插入新的子节点

语法:父节点.insertBefore(新节点,旧节点);

	myClick("btn02",function(){
		//创建一个广州
		var li = document.createElement("li");
		var gzText = document.createTextNode("广州");
		li.appendChild(gzText);
		
		//获取id为bj的节点
		var bj = document.getElementById("bj");
		
		//获取city
		var city = document.getElementById("city");

		city.insertBefore(li , bj);

replaceChild()可以使用指定的子节点替换已有的子节点

语法:父节点.replaceChild(新节点,旧节点);

	myClick("btn03",function(){
		//创建一个广州
		var li = document.createElement("li");
		var gzText = document.createTextNode("广州");
		li.appendChild(gzText);
		
		//获取id为bj的节点
		var bj = document.getElementById("bj");
		
		//获取city
		var city = document.getElementById("city");
	
		city.replaceChild(li , bj);
		
		
	});

removeChild()可以删除一个子节点

语法:
他杀:父节点.removeChild(子节点);
自杀:子节点.parentNode.removeChild(子节点);

	//删除#bj节点
	myClick("btn04",function(){
		//获取id为bj的节点
		var bj = document.getElementById("bj");
		//获取city
		var city = document.getElementById("city");
		
		//city.removeChild(bj);
		
		bj.parentNode.removeChild(bj);
	});

12.25

JS影响CSS样式

style属性

  • 通过JS修改元素的样式:
    语法:元素.style.样式名 = 样式值
  • 通过style属性设置的样式都是内联样式,有较高的优先级
  • 如果在样式中写了!important,则此时样式会有最高的优先级,即使通过JS也不能覆盖该样式,此时将会导致JS修改样式失效

注意:如果CSS的样式名中含有-,
这种名称在JS中是不合法的比如background-color,需要将这种样式名修改为驼峰命名法
即:去掉-,然后将-后的字母大写

  • 读取box1的样式
    语法:元素.style.样式名
  • 通过style属性设置和读取的都是内联样式,无法读取样式表中的样式
	//修改样式
	box1.style.width = "300px";
	box1.style.height = "300px";
	box1.style.backgroundColor = "yellow";

	//读取样式
	alert(box1.style.width);

读取元素的样式(样式表)

使用currentStyle获取元素的当前显示的样式
  • 语法:元素.currentStyle.样式名
  • 如果当前元素没有设置该样式,则获取它的默认值(比如没设置宽度,获取auto)
  • currentStyle只有IE浏览器支持,其他的浏览器都不支持
alert(box1.currentStyle.width);
使用getComputedStyle()方法获取元素的当前显示的样式
  • 该方法是window的方法,可以直接使用
  • 需要两个参数
    第一个:要获取样式的元素
    第二个:可以传递一个伪元素,一般都传null
  • 该方法会返回一个对象,对象中封装了当前元素对应的样式,可以通过对象.样式名来读取样式,也可以使用方括号(如果要自己写一个函数,传入实参后,函数里需要用方括号)
  • 如果获取的样式没有设置,则会获取到真实的值,而不是默认值(即使没写宽度,也获取px值)
  • 该方法不支持IE8及以下的浏览器
alert(getComputedStyle(box1,null).width);

通过currentStyle和getComputedStyle()读取到的样式都是只读的,不能修改,如果要修改必须通过style属性。

定义获取样式的函数

定义一个函数,用来获取指定元素的当前的样式

参数:obj 要获取样式的元素、name 要获取的样式名

	function getStyle(obj , name){
		
		if(window.getComputedStyle){
			//正常浏览器的方式,具有getComputedStyle()方法
			return getComputedStyle(obj , null)[name];
			// 注意此处的name必须是方括号,如果是.name就写死了
		}else{
			//IE8的方式,没有getComputedStyle()方法
			return obj.currentStyle[name];
		}

12.26

其它操作样式的属性

这些属性都是只读的,不能修改

clientWidth clientHeight这两个属性可以获取元素的可见宽度和高度

  • 这些属性都是不带px的,返回都是一个数字,可以直接进行计算

  • 会获取元素宽度和高度,包括内容区和内边距

      alert(box1.clientWidth);
      alert(box1.clientHeight);
    

offsetWidth offsetHeight 获取元素的整个的宽度和高度,包括内容区、内边距和边框

	alert(box1.offsetWidth);

offsetParent 可以用来获取当前元素的定位父元素

  • 会获取到离当前元素最近的开启了定位的祖先元素
  • 如果所有的祖先元素都没有开启定位,则返回body

offsetLeft 当前元素相对于其定位父元素的水平偏移量
offsetTop 当前元素相对于其定位父元素的垂直偏移量

alert(box1.offsetLeft);

scrollWidth scrollHeight 可以获取元素整个滚动区域的宽度和高度

alert(box4.clientHeight);
alert(box4.scrollWidth);

scrollLeft 可以获取水平滚动条滚动的距离
scrollTop 可以获取垂直滚动条滚动的距离

alert(box4.scrollLeft);
alert(box4.scrollTop);

当满足scrollHeight - scrollTop == clientHeight
说明垂直滚动条滚动到底(可以用来验证用户是否读完协议)

当满足scrollWidth - scrollLeft == clientWidth
说明水平滚动条滚动到底

事件对象

当事件的响应函数被触发时,浏览器每次都会将一个事件对象作为实参传递进响应函数

在事件对象中封装了当前事件相关的一切信息,比如:鼠标的坐标、键盘哪个按键被按下 、鼠标滚轮滚动的方向…

	window.onload = function(){
		/*
		 * 当鼠标在areaDiv中移动时,在showMsg中来显示鼠标的坐标
		 */
		//获取两个div
		var areaDiv = document.getElementById("areaDiv");
		var showMsg = document.getElementById("showMsg");
		
		/*
		 * onmousemove
		 * 	- 该事件将会在鼠标在元素中移动时被触发
		 */
		areaDiv.onmousemove = function(event){
			
			/*
			 * 在IE8中,响应函数被处发时,浏览器不会传递事件对象,
			 * 	在IE8及以下的浏览器中,是将事件对象作为window对象的属性保存的,
			 *  对其它浏览器,其实不需要写window
			 *  过去火狐不兼容window.event,但现在兼容了
			 */		
			/*
			 * clientX可以获取鼠标指针的水平坐标
			 * cilentY可以获取鼠标指针的垂直坐标
			 */
			var x = window.event.clientX;
			var y = window.event.clientY;	
			//在showMsg中显示鼠标的坐标
			showMsg.innerHTML = "x = "+x + " , y = "+y;
	
		};		
	};

12.27

事件的冒泡

冒泡指的就是事件的向上传导,当后代元素上的事件被触发时,其祖先元素的相同事件也会被触发

在开发中大部分情况冒泡都是有用的,如果不希望发生事件冒泡可以通过事件对象来取消冒泡

可以将事件对象的cancelBubble设置为true,即可取消冒泡,取消时,是对后代元素进行取消,可以防止其祖先事件触发相同的事件

	window.onload = function(){			
		//为s1绑定一个单击响应函数
		var s1 = document.getElementById("s1");
		s1.onclick = function(event){
			event = window.event;
			alert("我是span的单击响应函数");
			
			//取消冒泡
			event.cancelBubble = true;
		};
		//为box1绑定一个单击响应函数
		var box1 = document.getElementById("box1");
		box1.onclick = function(event){
			event = window.event;
			alert("我是div的单击响应函数");	
			event.cancelBubble = true;
		};				
		//为body绑定一个单击响应函数
		document.body.onclick = function(){
			alert("我是body的单击响应函数");
		};	
	};		
	<body>
		
		<div id="box1">
			我是box1
			<span id="s1">我是span</span>
		</div>
		
	</body>

事件的委派

如果希望只绑定一次事件,即可应用到多个的元素上(即使元素是后添加的)可以将其绑定给元素的共同的祖先元素

事件的委派:

  • 指将事件统一绑定给元素的共同的祖先元素,这样当后代元素上的事件触发时,会一直冒泡到祖先元素,从而通过祖先元素的响应函数来处理事件
  • 委派利用了冒泡,通过委派可以减少事件绑定的次数,提高程序的性能
window.onload = function(){
		
		var u1 = document.getElementById("u1");
		
		//点击按钮以后添加超链接
		var btn01 = document.getElementById("btn01");
		btn01.onclick = function(){
			//创建一个li
			var li = document.createElement("li");
			li.innerHTML = "<a href='javascript:;' class='link'>新建的超链接</a>";
			
			//将li添加到ul中
			u1.appendChild(li);
		};

		//获取所有的a
		var allA = document.getElementsByTagName("a");

		//为ul绑定一个单击响应函数,从而影响其中的a
		u1.onclick = function(event){
			event = window.event;
			
			/*
			 * target
			 * 	- event中的target表示的触发事件的对象
			 */

			//如果触发事件的对象是我们期望的元素,则执行否则不执行
			if(event.target.className == "link"){
			// 当元素有多个类名时,这种方式有一定隐患
				alert("我是ul的单击响应函数");
			}			
		};
	};

事件的绑定

背景:使用 对象.事件 = 函数 的形式绑定响应函数,它只能同时为一个元素的一个事件绑定一个响应函数,不能绑定多个,如果绑定了多个,则后边会覆盖掉前边的。但我们想给一个元素绑定多个响应函数

addEventListener() ,通过这个方法可以为元素绑定响应函数

  • 参数:
    1.事件的字符串,不要on
    2.回调函数,当事件触发时该函数会被调用
    3.是否在捕获阶段触发事件,需要一个布尔值,一般都传false

  • 使用addEventListener()可以同时为一个元素的相同事件同时绑定多个响应函数,这样当事件被触发时,响应函数将会按照函数的绑定顺序执行

  • 这个方法不支持IE8及以下的浏览器

attachEvent(),在IE8中可以使用它来绑定事件

  • 参数:
    1.事件的字符串,要on
    2.回调函数
  • 这个方法也可以同时为一个事件绑定多个处理函数,不同的是它是后绑定先执行,执行顺序和addEventListener()相反

addEventListener()中的this,是绑定事件的对象
attachEvent()中的this,是window
需要统一两个方法this

写一个能兼容所有浏览器的bind函数

定义一个函数,用来为指定元素绑定响应函数:

参数:

  • obj 要绑定事件的对象
  • eventStr 事件的字符串**(不要on)**
  • callback 回调函数

补充:call方法

语法格式是 函数引用.call(调用者,参数1,参数2,参数3)

调用者.函数(参数1,参数2,参数3) == 函数.call(调用者,参数1,参数2,参数3)

(参数可以不写)

	window.onload = function(){
		var btn01 = document.getElementById("btn01");
		bind(btn01 , "click" , function(){
			alert(this);
		});
	
		
	};
	//定义一个函数,用来为指定元素绑定响应函数
	function bind(obj , eventStr , callback){
		if(obj.addEventListener){
			//大部分浏览器兼容的方式
			obj.addEventListener(eventStr , callback , false);
		}else{
			/*
			 * this是谁由调用方式决定
			 * callback.call(obj)
			 */
			//IE8及以下
			obj.attachEvent("on"+eventStr , function(){
				//在匿名函数中调用回调函数
				callback.call(obj);
				//相当于obj.callback,但是由于此时obj不确定,必须要这样写
				//此时this就是调用函数callback的对象,即obj
				//我的理解是,如果写成.就是写死了,如果是call()或者之前练习中出现的方括号,就没有写死
			});
		}
	}
	

事件的传播

关于事件的传播网景和微软有不同的理解

  • 微软认为事件应该是由内向外传播,也就是当事件触发时,应该先触发当前元素上的事件,然后再向当前元素的祖先元素上传播,也就说事件应该在冒泡阶段执行。

  • 网景认为事件应该是由外向内传播的,也就是当前事件触发时,应该先触发当前元素的最外层的祖先元素的事件,然后在向内传播给后代元素

  • W3C综合了两个公司的方案,将事件传播分成了三个阶段

    1.捕获阶段:在捕获阶段时从最外层的祖先元素,向目标元素进行事件的捕获,但是默认此时不会触发事件
    2.目标阶段:事件捕获到目标元素,捕获结束开始在目标元素上触发事件
    3.冒泡阶段:事件从目标元素向他的祖先元素传递,依次触发祖先元素上的事件
    在这里插入图片描述
    (外层代表祖先元素,内层代表后代元素)

  • 如果希望在捕获阶段就触发事件,可以将addEventListener()的第三个参数设置为true,一般情况下不会希望在捕获阶段触发事件,所以这个参数一般都是false

  • IE8及以下的浏览器中没有捕获阶段

1.1

滚轮事件

据说onmousewheel已经被废弃了,现在使用onwheel,并且没有火狐的兼容性问题,用到时在菜鸟教程上搜索。

  • onmousewheel鼠标滚轮滚动的事件,会在滚轮滚动时触发,但是火狐不支持该属性
  • 在火狐中需要使用 DOMMouseScroll 来绑定滚动事件,注意该事件需要通过addEventListener()函数来绑定

event.wheelDelta

  • 可以获取鼠标滚轮滚动的方向
  • wheelDelta这个值不看大小,只看正负,向上滚 120 向下滚 -120
  • 该属性火狐中不支持,在火狐中使用event.detail来获取滚动的方向,向上滚 -3 向下滚 3
window.onload = function(){
	//获取id为box1的div
	var box1 = document.getElementById("box1");			
	box1.onmousewheel = function(event){
		
		event = event || window.event;
		//判断鼠标滚轮滚动的方向
		if(event.wheelDelta > 0 || event.detail < 0){
			//向上滚,box1变短
			box1.style.height = box1.clientHeight - 10 + "px";
		}else{
			//向下滚,box1变长
			box1.style.height = box1.clientHeight + 10 + "px";
		}
		/*
		 * 使用addEventListener()方法绑定响应函数,取消默认行为时不能使用return false
		 * 需要使用event来取消默认行为event.preventDefault();
		 * 但是IE8不支持event.preventDefault();,如果直接调用会报错
		 */
		event.preventDefault && event.preventDefault();	
		/*
		 * 当滚轮滚动时,如果浏览器有滚动条,滚动条会随之滚动,
		 * 这是浏览器的默认行为,如果不希望发生,则可以取消默认行为
		 */
		return false;
	};
	//为火狐绑定滚轮事件
	bind(box1,"DOMMouseScroll",box1.onmousewheel);
};
function bind(obj , eventStr , callback){
	if(obj.addEventListener){
		//大部分浏览器兼容的方式
		obj.addEventListener(eventStr , callback , false);
	}else{
		/*
		 * this是谁由调用方式决定
		 * callback.call(obj)
		 */
		//IE8及以下
		obj.attachEvent("on"+eventStr , function(){
			//在匿名函数中调用回调函数
			callback.call(obj);
		});
	}
}

键盘事件

onkeydown

  • 按键被按下,说如果一直按着某个按键,则事件会一直触发
  • 当onkeydown连续触发时,第一次和第二次之间会间隔稍微长一点,其他会非常快,这种设计是为了防止误操作的发生

onkeyup 按键被松开

键盘事件一般都会绑定给一些可以获取到焦点的对象或者是document

keyCode

  • 可以通过keyCode来获取按键的编码,通过它可以判断哪个按键被按下
  • 除了keyCode,事件对象中还提供了几个属性altKey,ctrlKey,shiftKey
  • 这个三个用来判断alt ctrl 和 shift是否被按下,如果按下则返回true,否则返回false
window.onload = function(){
	document.onkeydown = function(event){
		event = window.event;		
		//判断y和ctrl是否同时被按下
		if(event.keyCode === 89 && event.ctrlKey){
			console.log("ctrl和y都被按下了");
		}
	};
	//获取input
	var input = document.getElementsByTagName("input")[0];
	input.onkeydown = function(event){
		event = window.event;
		//console.log(event.keyCode);
		//数字 48 - 57
		//使文本框中不能输入数字
		if(event.keyCode >= 48 && event.keyCode <= 57){
			//在文本框中输入内容,属于onkeydown的默认行为
			//如果在onkeydown中取消了默认行为,则输入的内容,不会出现在文本框中
			//此处用正则表达式更严谨
			return false;
		}
	};
};

BOM

BOM可以使我们通过JS来操作浏览器,它为我们提供了一组对象,用来完成对浏览器的操作

BOM对象

  • Window 代表的是整个浏览器的窗口,同时window也是网页中的全局对象
  • Navigator 代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
  • Location 代表当前浏览器的地址栏信息,通过Location可以获取地址栏信息,或者操作浏览器跳转页面
  • History 代表浏览器的历史记录,可以通过该对象来操作浏览器的历史记录,由于隐私原因,该对象不能获取到具体的历史记录,只能操作浏览器向前或向后翻页,而且该操作只在当次访问时有效
  • Screen 代表用户的屏幕的信息,通过该对象可以获取到用户的显示器的相关的信息(PC端几乎不用)

这些BOM对象在浏览器中都是作为window对象的属性保存的,可以通过window对象来使用,也可以直接使用

//console.log(navigator);
//console.log(location);
//console.log(history);

Navigator

  • 代表的当前浏览器的信息,通过该对象可以来识别不同的浏览器
  • 由于历史原因,Navigator对象中的大部分属性都已经不能帮助我们识别浏览器了,一般只会使用userAgent来判断浏览器的信息

userAgent是一个字符串,这个字符串中包含有用来描述浏览器信息的内容,不同的浏览器会有不同的userAgent

  • 火狐的userAgent
    Mozilla/5.0 (Windows NT 6.1; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0

  • Chrome的userAgent
    Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.82 Safari/537.36

  • IE8
    Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)

  • IE9
    Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)

  • IE10
    Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E)

  • IE11
    Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; .NET4.0C; .NET4.0E; rv:11.0) like Gecko

在IE11中已经将微软和IE相关的标识都已经去除了,所以已经不能通过UserAgent来识别一个浏览器是否是IE了

怎么找到IE11?
	var ua = navigator.userAgent;
	
	console.log(ua);
	
	if(/firefox/i.test(ua)){
		alert("你是火狐!!!");
	}else if(/chrome/i.test(ua)){
		alert("你是Chrome");
	}else if(/msie/i.test(ua)){
		alert("你是IE浏览器~~~");
	}else if("ActiveXObject" in window){
		alert("你是IE11,枪毙了你~~~");
	}
	//直接使用else if(ActiveXObject)被微软动了手脚,已经找不到IE11了,必须用in
	//亲测,由于Edge更换内核,现在查Edge会提示Chrome

History

History对象可以用来操作浏览器向前或向后翻页

  • length属性,可以获取到当成访问的链接数量

      //alert(history.length);
    
  • back() 可以用来回退到上一个页面,作用和浏览器的回退按钮一样

      //history.back();
    
  • forward() 可以跳转下一个页面,作用和浏览器的前进按钮一样

      //history.forward();
    
  • go() 可以用来跳转到指定的页面,它需要一个整数作为参数

    • 1:表示向前跳转一个页面 相当于forward()
    • 2:表示向前跳转两个页面
    • -1:表示向后跳转一个页面
    • -2:表示向后跳转两个页面

Location

该对象中封装了浏览器的地址栏的信息

  • 如果直接打印location,则可以获取到地址栏的信息(当前页面的完整路径)

      //alert(location);
    
  • 如果直接将location属性修改为一个完整的路径,或相对路径,则页面会自动跳转到该路径,并且会生成相应的历史记录

      //location = "http://www.baidu.com";
      //location = "01.BOM.html";
    
  • assign() 用来跳转到其他的页面,作用和直接修改location一样

      //location.assign("http://www.baidu.com");
    
  • reload() 用于重新加载当前页面,作用和刷新按钮一样,如果在方法中传递一个true,作为参数,则会强制清空缓存刷新页面(据说现在可以直接清空缓存刷新页面,不需要true;下次加个false试试是否清空缓存)

所谓“强制清空缓存刷新页面”,举个例子,此时在表单中输入了数据还没提交,如果刷新后数据保留,就是未清空缓存。

//location.reload(true);
  • replace() 可以使用一个新的页面替换当前页面,调用完毕也会跳转页面,不会生成历史记录,不能使用回退按钮回退

      location.replace("01.BOM.html");
    

定时器

定时调用

setInterval() 定时调用,可以将一个函数,每隔一段时间执行一次

参数:

  1. 回调函数,该函数会每隔一段时间被调用一次
  2. 每次调用间隔的时间,单位是毫秒

返回值:返回一个Number类型的数据,它用来作为定时器的唯一标识

clearInterval()可以用来关闭一个定时器,方法中需要一个定时器的标识作为参数,这样将关闭标识对应的定时器
可以接收任意参数,如果参数是一个有效的定时器的标识,则停止对应的定时器,否则什么也不做

window.onload = function(){
	//获取count
	var count = document.getElementById("count");
	var num = 1;
	var timer = setInterval(function(){	
		count.innerHTML = num++;
		if(num == 11){
			//关闭定时器
			clearInterval(timer);
		}
	},1000);
};

延时调用

  • 延时调用一个函数不马上执行,而是隔一段时间以后在执行,而且只会执行一次
  • 延时调用和定时调用的区别,定时调用会执行多次,而延时调用只会执行一次
  • 二者是可以互相代替的,在开发中可以根据自己需要去选择
			var timer = setTimeout(function(){
			//3s后会弹出“hello”
				alert("hello");
			},3000);
			
			//使用clearTimeout()来关闭一个延时调用
			//clearTimeout(timer);

1.4

类的操作

通过style属性来修改元素的样式,每修改一个样式,浏览器就需要重新渲染一次页面,这样的执行的性能是比较差,而且这种形式当要修改多个样式时,也不方便

可以通过修改元素的class属性来间接的修改样式,这样只需要修改一次,即可同时修改多个样式,浏览器只需要重新渲染页面一次,性能比较好,并且可以使样式和行为进一步分离

//定义一个函数,用来向一个元素中添加指定的class属性值
	/*
	 * 参数:
	 * 	obj 要添加class属性的元素
	 *  cn 要添加的class值
	 */
	function addClass(obj , cn){
		//检查obj中是否含有cn
		if(!hasClass(obj , cn)){
			obj.className += " "+cn;
		}
	}
	
	/*
	 * 判断一个元素中是否含有指定的class属性值
	 * 	如果有该class,则返回true,没有则返回false
	 */
	function hasClass(obj , cn){
		
		//判断obj中有没有cn class
		//创建一个正则表达式
		//var reg = /\bb2\b/;
		var reg = new RegExp("\\b"+cn+"\\b");
		//因为动态传入,所以必须用构造函数建立正则表达式
		return reg.test(obj.className);
	}
	
	/*
	 * 删除一个元素中的指定的class属性
	 */
	function removeClass(obj , cn){
		//创建一个正则表达式
		var reg = new RegExp("\\b"+cn+"\\b");
		//删除class(用空字符替代原先的类名)
		obj.className = obj.className.replace(reg , "");
		
	}
	
	/*
	 * toggleClass可以用来切换一个类(推荐)
	 * 	如果元素中具有该类,则删除
	 * 	如果元素中没有该类,则添加
	 */
	function toggleClass(obj , cn){
		
		//判断obj中是否含有cn
		if(hasClass(obj , cn)){
			//有,则删除
			removeClass(obj , cn);
		}else{
			//没有,则添加
			addClass(obj , cn);
		}
	}

1.5

JSON

概念

JSON:JavaScript Object Notation JS对象表示法

  • JSON是一个特殊格式的字符串,这个字符串可以被任意的语言所识别,并且可以转换为任意语言中的对象,在开发中主要用来数据的交互
  • JSON和JS对象的格式一样,只不过JSON字符串中的属性名必须加双引号,而且由于JSON是字符串,最外侧需要引号引起来

JSON分类:对象 {},数组 []

JSON中允许的值:

  1. 字符串
  2. 数值
  3. 布尔值
  4. null(不可以是undefined)
  5. 对象(除函数对象)
  6. 数组
	//以下三者都是格式正确的JSON
	var arr = '[1,2,3,"hello",true]';
	
	var obj2 = '{"arr":[1,2,3]}';
	
	var arr2 ='[{"name":"孙悟空","age":18,"gender":"男"},{"name":"孙悟空","age":18,"gender":"男"}]';

转换

将JSON字符串转换为JS中的对象:
JS中,为我们提供了一个工具类,就叫JSON,它可以将一个JSON转换为JS对象,也可以将一个JS对象转换为JSON

json --> js对象

JSON.parse()

  • 可以将JSON字符串转换为js对象
  • 需要一个JSON字符串作为参数,会将该字符串转换为JS对象并返回
	var arr = '[1,2,3,"hello",true]';
	var json = '{"name":"孙悟空","age":18,"gender":"男"}';
	var o = JSON.parse(json);
	var o2 = JSON.parse(arr);

js对象 --> json

JSON.stringify()

  • 可以将一个JS对象转换为JSON字符串
  • 需要一个js对象作为参数,会返回一个JSON字符串
	var obj3 = {name:"猪八戒" , age:28 , gender:"男"};
	var str = JSON.stringify(obj3);

JSON对象在IE7及以下的浏览器中不支持,所以在这些浏览器中调用时会报错

eval()

该函数可以用来执行一段字符串形式的JS代码,并将执行结果返回

  • 如果使用eval()执行的字符串中含有{},它会将{}当成是代码块,如果不希望将其当成代码块解析,则需要在字符串前后各加一个()
  • eval()的功能很强大,可以直接执行一个字符串中的js代码,但是在开发中尽量不要使用,因为它的执行性能比较差,还具有安全隐患
	var str = '{"name":"孙悟空","age":18,"gender":"男"}';
	var obj = eval("("+str+")");

JS基础历时一个半月,终于看完了视频,接下来先巩固基础知识,做demo和网站的练习,然后学习JS高级。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值