【JavaScript从入门到精通】第四课初探JavaScript魅力-04

第四课初探JavaScript魅力-04

style与className

以前咱们已经讲过,style用于在JS里控制元素的样式,经过style能够选中元素的各类css属性。此外,咱们也提到过,JS用className控制元素的class。这二者之间,是否会产生什么矛盾吗?css

咱们使用一段简单的代码做为示例:html

<html>
  <head>
    <meta charset="utf-8">
    <title>无标题文档</title>
    <style>
      #div1 {width:200px; height:200px; border:1px solid black;}
      .box {background:red;}
    </style>
    <script>
      function toRed()
      {
        var oDiv=document.getElementById('div1');
        oDiv.style.background='red';
      }
    </script>
  </head>
  <body>
    <input type="button" value="变红" onclick="toRed()" />
    <div id="div1"></div>
  </body>
</html>

这段代码的做用没必要多说,点击变红按钮后,div1块的背景颜色会变为红色。如今咱们打开浏览器的控制台(F12),选中Div1,观察点击先后的变化:前端

 

 

能够看到,JS对div1的样式其实是经过行间样式的方法进行控制的。实际上,经过JS的style方法加入的样式都是经过行间样式来控制的,并且经过style也只能读取到元素的行间样式。数组

咱们来看看style和class之间的关系。要阐明这二者之间的关系,首先须要弄清楚css里的样式优先级。在css里,样式的优先级表明了css优先执行的代码。样式优先级的顺序以下(从高到低):浏览器

  1. 行间样式
  2. ID
  3. class
  4. 标签
  5. 通配符

行间样式具备最高的优先级。如今咱们来看这个一个例子:函数

<html>
	<head>
		<meta charset="utf-8">
		<title>无标题文档</title>
		<style>
			#div1 {width:200px; height:200px; border:1px solid black;}
			.box {background:red;}
		</style>
		<script>
			function toRed()
			{
				var oDiv=document.getElementById('div1');

				oDiv.className='box';
			}
			function toGreen()
			{
				var oDiv=document.getElementById('div1');

				oDiv.style.background='green';
			}
		</script>
	</head>

	<body>
		<input type="button" value="变红" onclick="toRed()" />
		<input type="button" value="变绿" onclick="toGreen()" />
		<div id="div1"></div>
	</body>
</html>

执行结果以下:post

 

上述代码先执行toRed函数再执行toGreen函数,程序能够正常运行;但若是先执行toGreen函数再执行toRed函数,toRed函数会失效。缘由在于点击toGreen函数后,background为green属性的css添加到了行间,而点击toRed函数,虽然也能给元素添加含有background为red属性的class,但由于行间样式优先级比class高,因此优先执行行间样式的代码。咱们能够获得以下结论:对于同一元素的同一属性,若是修改了其style,以后再修改其className不会再有效果。所以咱们建议,对于同一个元素,在操做上保持一致性,要么只操做它的style,要么只操做它的className。htm

 

提取行间事件与匿名函数

 

咱们以前使用的onclick="toGreen()"这一类写法就被叫作行间事件。然而,在咱们实际工做的时候,一个页面一般是由多我的完成,若是将事件写在行间有可能会出现编辑的时候事件被删掉的状况。并且,当须要给大量元素增添功能相同的事件时,使用行间事件显得太过麻烦和重复。若元素的数量不固定,使用行间事件更是对代码无从下手。而采用提取行间事件的方法,能够很好地解决这些问题。blog

说到提取行间事件,咱们首先得提到如何用JS给元素添加事件。能够看到,行间事件onclick的写法让onclick显得很像一个属性,那么是否能够经过操纵属性的方法将行间事件写到函数里呢?固然是能够的,咱们将以前例子的一些代码进行修改:事件

var oBtn=document.getElementById('btn1');
function abc(){
	alert('a');
}
oBtn.onclick=abc;

效果和使用行间事件没有任何区别。这就是最简单的提取行间事件的方法。

在写网页代码的时候,若是代码量过大或者函数过多,取函数名是一件很是头疼的事情。在JS里,提供了一种匿名函数的形式,这种写法不用给函数取名,而函数体须要放在调用函数的地方。咱们能够将上面的代码改为以下形式:

var oBtn=document.getElementById('btn1');
oBtn.onclick=function ()		//匿名函数
{
	alert('a');
};

实际工做中,大部分的事件都是经过这种匿名函数的方式完成的,这样很是方便,不会出现忘记函数名的状况。

 

window.onload事件

 

JS代码在浏览器执行的时候,有一个特色:每读一行,执行一行。在咱们上面的例子中,咱们将script标签放在了body里,程序能够正常执行。但若是你试着将script标签放在head标签里,你会发现程序报错。缘由在于,当浏览器读到oBtn.onclick这一行时,后面body的代码尚未被加载进来,所以实际上你是在给一个不存在的按钮添加onclick事件,天然就会出错了。如何解决这个问题呢?

这个问题能够用window.onload事件解决。这个事件表明的含义是,当页面加载完成的时候发生。咱们在前面的代码外套加window.onload:

window.onload=function (){
	var oBtn=document.getElementById('btn1');
	oBtn.onclick=function ()
	{
	    alert('a');
	}
};

添加以后,window.onload内包裹的函数只在页面加载结束后执行,所以函数执行的时候btn1已结被加载了进来,这样程序就不会出错了。

 

行为,样式,结构三者分离

 

在前端领域来讲,行为,样式,结构三者分别对应着JavaScript,css和HTML,而将行为,样式,结构三者分离,简单来讲,就是避免添加行间样式和行间事件。咱们以前采用提取行间事件的方法将写成函数就是这个目的,在从此的代码编写中,也建议你们尽可能遵照这个原则。

 

获取一组元素

 

咱们以前提到,若是页面须要给大量元素添加事件,使用咱们以前的写法会让代码显得很是繁杂重复。使用getElementsByTagName方法获取元素能够避免这一点。和getElementById方法不一样的是,getElementById一次只能获取一个元素(由于id在HTML里不可重复),而getElementsByTagName一次能够获取一组元素。

为了说明这个问题,咱们再举一个小例子:

<html>    
<head>
<meta charset="utf-8">
<title>无标题文档</title>
<style>
div {width:200px; height:200px; float:left; border:1px solid black; margin:10px;}
</style>
<script>
window.onload=function ()
{
var aDiv=document.getElementsByTagName('div');
alert(aDiv.length);
};
</script>
</head>
<body>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</body>
</html>

咱们经过getElementsByTagName得到了全部标签名为div的元素,而此时aDiv再也不是一个元素而是一个数组。数组的简单概念能够理解为一堆元素的集合。数组有一个最简单的属性:length,表明了数组长度(元素个数),所以上面的例子中最后会弹出div块的个数。所以结果以下:

 

一样的,若是咱们想修改这些div的样式,是否能够直接利用getElementsByTagName获取后直接修改呢?:

var aDiv = getElementsByTagName('div');
aDiv.style.background = 'red';

这样的写法是会出错的。缘由在于在JS里,一次只能对一个元素的属性进行设置,而aDiv是一个数组,内含多个元素,没法对其进行直接操做。为了对数组进行操做,咱们须要了解如何得到数组内的单个元素。咱们若是将上面的代码进行这样的修改:

var aDiv = getElementsByTagName('div');
aDiv[0].style.background='red';

能够看到,第一个div块变为了红色。aDiv[0]中的0被称为下标,表明数组中元素的位数,须要注意的是下标统一是从0开始,aDiv[0]表明了aDiv数组中的第一个元素。

var aDiv = getElementsByTagName('div');
aDiv[0].style.background='red';
aDiv[1].style.background='red';
aDiv[2].style.background='red';
aDiv[3].style.background='red';

这样就能把4个div块的颜色都进行改变,但设置元素样式的代码依旧很是繁琐,若是存在100个这样的div,是否就须要将这样的代码写100次?其实是不须要的,为了可以把这些相似的代码合并掉,咱们须要用到循环。

 

循环

 

说到循环,咱们先来回忆一下咱们学过的if语句。还记得if语句的格式以下:

if(条件){
  语句1
}
else{
  语句2
}

对于if语句来讲,若是条件是成立的,会执行一次语句1,不然执行一次语句2。然而,若是咱们想屡次执行语句1呢?采用循环的方式即可以让一个语句进行屡次执行。 第一种循环(while循环)的语句格式以下:

while(条件){
   语句
}

对于while循环来讲,只要条件成立,语句会一直执行,直到条件再也不成立。咱们用例子说明:

var i = 0;               //初始化
while (i < 5) {       //条件
  alert(i);             //语句
	i = i + 1     //自增
}

i=i+1的意思是将i的值加1再返回给自身,也就是说,循环每执行一次,i的大小就增长1。执行的结果以下:

 

当第一次执行完毕后,i的值变为了1,依然比5小,因此继续执行,这样再反复四次后,i的值变为了5,5=5,条件再也不成立,因此跳出了循环。对于一个循环,一般须要包含四个部分:初始化,条件,语句,自增。值得一提的是,表示自增的时候,咱们一般用i++来代i=i+1这种比较复杂的写法。

在不少状况下,使用while循环是一个比较麻烦的选择,所以咱们有了第二种更方便的循环语句:for循环。for循环的语句格式以下:

for(初始化;条件;自增){
  语句
}

和while循环同样,for循环也包含这四个部分,只不过格式上更为简便。上面的代码能够改成:

for(var i = 0; i < 5;i ++){
	alert(i);
}

那么,回到咱们的getElementsByTagName方法上来。经过循环的方式,咱们能够很轻松的将代码进行简化:

var aDiv = getElementsByTagName('div');
for(i = 0;i < 4;i ++){
  //i->0,1,2,3
  aDiv[i].style.background='red';
}

这里还存在最后一个小问题,若是个人div个数发生了改变(例如邮箱,每一个人邮箱里面的邮件个数都是不一样的),而我在函数用i<4将div块的个数定为4个,那么会产生HTML和JS代码不一致的状况,每次执行都须要修改JS。实际上,这个例子里的div个数,就是aDiv这个数组的长度,所以咱们可使用用length属性来解决这个问题。

var aDiv = getElementsByTagName('div');
for(i = 0;i < aDiv.length;i ++){
  //i->0,1,2,3
  aDiv[i].style.background='red';
}

这样不管html代码如何修改div块的个数JS也能够自动适应了。

 

全选、反选、不选

 

全选、反选、不选是网页常常会用到的功能,它们分别是怎么实现的呢?

咱们给网页添加button和多个checkbox,但愿经过button来控制checkbox的选中状况。根据咱们前面所学的知识,咱们应该采起以下思路:经过getElementById选中button,而后给button添加onclick事件,而后经过getElementsByTagName选中input标签来操做checkbox。这里有一个小小的问题,由于checkbox和button属性的标签都是input,因此若是经过input标签来进行元素选择,会同时选中checkbox和button,产生一些问题。

这里能够采用一个小技巧解决这个问题。咱们将全部checkbox放入一个id为div1的标签中,而后在JS采用以下写法:

var oDiv = document.getElementById('div1');
var aCh = oDiv.getElementById('input');

也就是说,getElementById前不必定是document,在本例中先选中了div1,再从div1中选中input,这样就避免了选中button的状况。

在HTML中,控制checkbox选中状况的属性为checked,同理在JS里,能够经过操纵checked属性来改变checkbox的选中状况(选中时checked属性为true,未选中时为false)。true/false在JS里被称为布尔值,具体概念之后再讲。

具体代码以下:

<html>
	<head>
		<meta charset="utf-8">
		<title>无标题文档</title>
		<script>
		window.onload=function ()
		{
			var oBtn1=document.getElementById('btn1');
			var oBtn2=document.getElementById('btn2');
			var oBtn3=document.getElementById('btn3');
			var oDiv=document.getElementById('div1');
			var aCh=oDiv.getElementsByTagName('input');

			oBtn1.onclick=function ()
			{
				for(var i=0;i<aCh.length;i++)
				{
					aCh[i].checked=true;
				}
			};

			oBtn2.onclick=function ()
			{
				for(var i=0;i<aCh.length;i++)
				{
					aCh[i].checked=false;
				}
			};

			oBtn3.onclick=function ()
			{
				for(var i=0;i<aCh.length;i++)
				{
					if(aCh[i].checked==true)
					{
						aCh[i].checked=false;
					}
					else
					{
						aCh[i].checked=true;
					}
				}
			};
		};
		</script>
	</head>

	<body>
		<input id="btn1" type="button" value="全选" /><br>
		<input id="btn2" type="button" value="不选" /><br>
		<input id="btn3" type="button" value="反选" /><br>
		<div id="div1">
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		    <input type="checkbox" /><br>
		</div>
	</body>
</html>

执行结果以下:

相关文章
相关标签/搜索