这里再补充几个css的知识点,下面会用到css
设置元素的最小宽度。
举例说明,好比设置一个百分比的宽度,那么元素的宽度的像素值是会随着页面大小而变化的。若是设置一个最小的像素宽度,那么当变化到最小值以后,不会继续变小。在下面的例子中,会出现滚动条,保证元素的宽度:html
<body> <div style="height: 80px;width: 100%;background-color: blue;min-width: 800px;"></div> <!--下面的状况是:原本正好能放一排的,可是狂赌不够后放不下了--> <div style="height: 80px;width: 20%;background-color: yellow;float: left"></div> <div style="height: 80px;width: 80%;background-color: red;float: right;min-width: 600px;"></div> </body>
另外,min-width 的值能够是像素,也能够是百分比。前端
这个属性是为元素添加一个圆角边框。值能够是像素,也能够是百分比。
若是把值设为50%,再保证高和宽同样,就能作出一个圆形的边框,放在img标签中,就能作出一个圆形的头像:html5
<img src="1.jpg" style="border-radius: 50%;height: 80px;width: 80px;" />
以前已经讲过:hover,这里要补充的是,不但能够改变本身标签的属性,也能够经过选择器的语法来改变其余标签的属性:python
<head> <meta charset="UTF-8"> <title>Title</title> <style> .father{ height: 100px; background-color: yellow; } .son{ height: 50%; } .father:hover{ color: red; } .father:hover .special{ background-color: blue; color: white; } </style> </head> <body> <div class="father"> <div class="son special">字体背景都变色</div> <div class="son">字体变色</div> </div> </body>
还没完,若是咱们改变的是display属性,那么不须要js,仅用css也能够实现鼠标悬停展开菜单的功能:数组
<head> <meta charset="UTF-8"> <title>Title</title> <style> .item .header{ height: 35px; background-color: blue; color: white; line-height: 35px; } .item .content{ display: none; } .item:hover .content{ display: block; } </style> </head> <body> <div class="item"> <div class="header">菜单</div> <div class="content"> <div>内容一</div> <div>内容二</div> <div>内容三</div> </div> </div> </body>
通常布局的时候,先把页面分红头部(pg-header)、中间(pg-content)、底部(pg-footer)三个部分。主要的内容周集中在中间。如今应该已经掌握了一种形式的布局,就是商城页面。以前没有把布局的问题单独拿出来说,这节之后台管理页面举例,讲解布局的问题和实现。浏览器
以前学习和做业都是以商城为例子。布局大概是这个样子的:都是从上到下布局,给页面设置一个宽度,而后全部内容都是居中显示。闭包
<head> <meta charset="UTF-8"> <title>Title</title> <style> body{ margin: 0; } .w{ width: 1000px; margin: 0 auto; } .pg-header, .pg-footer{ height: 48px; line-height: 48px; background-color: black; color: white; } .left{ float: left; } .right{ float: right; } .content1{ height: 100px; width: 160px; background-color: gold; } .content2{ width: 840px; background-color: yellow; } .goods{ height: 200px; width: 200px; border: 1px solid black; margin: 4px; } </style> </head> <body> <div class="pg-header"> <div class="w"> <div style=""> 这里放头部的内容 </div> </div> </div> <div class="pg-content"> <div class="w"> <div class="content1 left">这里放中间的内容</div> <div class="content2 right"> <div class="goods left">商品信息</div> <div class="goods left">商品信息</div> <div class="goods left">商品信息</div> <div class="goods left">商品信息</div> <div class="goods left">商品信息</div> <div class="goods left">商品信息</div> <div class="goods left">商品信息</div> <div class="goods left">商品信息</div> </div> <div style="clear: both"></div> </div> </div> <div class="pg-footer"> <div class="w"> <div> 这里放底部的内容 </div> </div> </div> </body>
常见的后台管理页面的布局,一样有头部、中继、底部。可是菜单通常显示在中间的最左侧(即固定在左边),而中间的右侧则是显示的主要内容:app
<head> <meta charset="UTF-8"> <title>Title</title> <style> body{ margin: 0; } .pg-header{ height: 48px; background-color: red; } .pg-content .menu{ position: fixed; top: 48px; left: 0; bottom: 30px; width: 200px; background-color: blue; color: white; } .pg-content .content{ position: fixed; top: 48px; right: 0; bottom: 30px; left: 200px; background-color: yellow; overflow: auto; } .pg-footer{ position: fixed; height: 30px; right: 0; left: 0; bottom: 0; background-color: purple; } </style> </head> <body> <div class="pg-header"></div> <div class="pg-content"> <div class="menu">这里是菜单</div> <div class="content"> <script> for (var i=0; i<100; i++){ document.writeln("<p>test</p>") } </script> </div> </div> <div class="pg-footer"></div> </body>
通常内容会比较多,每每一屏显示不完。这里就填入了不少内容,为了能够看到全部的内容,须要设置overflow属性,能够用滚轮翻页。
这里只是抛砖引玉,不建议这么实现。如今来看看后面absolute的实现方法。ide
仍是上面的样子,差很少的代码,此次用absolute来实现。不设置relative,这里会将元素定位在屏幕的某个位置和fixed同样,可是滚动滚动屏幕的时候,元素会跟着上下移动。具体代码以下:
<head> <meta charset="UTF-8"> <title>Title</title> <style> body{ margin: 0; } .pg-header{ height: 48px; background-color: red; } .pg-content .menu{ position: absolute; top: 48px; left: 0; width: 200px; background-color: blue; color: white; } .pg-content .content{ position: absolute; top: 48px; right: 0; left: 200px; background-color: yellow; /*overflow: auto;*/ /*bottom: 0;*/ } </style> </head> <body> <div class="pg-header"></div> <div class="pg-content"> <div class="menu"> <script> for (var i=0; i<10; i++){ document.writeln("<p>菜单</p>") } </script> </div> <div class="content"> <script> for (var i=0; i<100; i++){ document.writeln("<p>test</p>") } </script> </div> </div> </body>
这个样式和上面的略有不一样,头部和左侧会跟随滚轮移动。这里没写底部,而且暂时很差作能跟随滚轮移动的底部。
变化新样式:在 <style>
标签里,.pg-content .content
的样式里有两句被注释了,去掉注释后,就是设置overflow。效果是和上面同样的固定头部和左侧的样式了。
注意:能够再设置一个 min-width 属性,最小宽度。在你缩小窗口的时候,当动态调整的宽度小于这个属性时,元素的宽度就不会继续变小了,而是会出现滚动条。这能够有效的保证你的页面布局不会由于窗口大小的变化而混乱。
以前的头部没有任何内容,简单的在头部的左边放一个LOGO,这个没什么难度。而后再在右边放一个头像,头像使用圆形,而后鼠标悬停图片上会展开菜单。圆形图片和css实现鼠标悬停展开,在开头的css补充内容里能够参考:
<head> <meta charset="UTF-8"> <title>Title</title> <style> body{ margin: 0; } .pg-header{ height: 48px; line-height: 48px; background-color: red; } .pg-header img{ height: 48px; } .pg-header .logo{ width: 200px; float: left; } .pg-header .user{ float: right; background-color: pink; padding: 5px; margin-right: 62px; } .pg-header .user:hover .user_list{ display: block; } .pg-header .user .profile_pic>img{ height: 40px; width: 40px; border-radius: 50%; } .pg-header .user .user_list{ z-index: 20; position: absolute; top: 48px; right: 30px; background-color: orange; width: 120px; text-align: center; display: none; } .pg-header .user .user_list>a{ display: block; } .pg-header .user .user_list>a:hover{ background-color: blue; color: white; } </style> </head> <body> <div class="pg-header"> <div class="logo"> <a style="margin: 0 auto"> <img src="1.jpg" /> </a> </div> <!--设置user的div往右飘,上面的logo要往左飘,这样2个才能在一行--> <div class="user"> <a class="profile_pic"> <!--把头像设置成了圆形图片--> <img src="2.jpg"> </a> <!--user_list设置了相对定位,和下面的pg-content重叠,要设置z-index--> <div class="user_list"> <!--a标签要设置成块级标签,让它换行--> <a>个人收藏</a> <a>注销</a> </div> </div> </div> </body>
上面是头部的全部内容,能够和前面的页面内容拼接在一块儿,就是整个页面了。
若是要在页面中使用图标,推荐去 Font Awesome 找。这个是中文网: http://www.fontawesome.com.cn/
.1 先去官网下载font-awesome压缩包
.2 解压文件夹,把 font-awesome 的整个文件夹复制到你的项目中:
.3 在 <head>
处加载 font-awesome.min.css 以下:
<link rel="stylesheet" href="font-awesome-4.7.0/css/font-awesome.min.css">
用 <i>
标签包裹起来,把图标用到你网站的任何地方:
<head> <meta charset="UTF-8"> <title>Title</title> <link rel="stylesheet" href="font-awesome-4.7.0/css/font-awesome.min.css"> </head> <body> <ul class="fa-ul"> <li><i class="fa-li fa fa-check-square"></i>使用列表类图标</li> <li><i class="fa-li fa fa-check-square"></i>轻松的替换</li> <li><i class="fa-li fa fa-spinner fa-spin"></i>无序列表</li> <li><i class="fa-li fa fa-square"></i>中的默认图标</li> </ul> <i class="fa fa-refresh fa-spin fa-3x fa-fw"></i> <div> <i class="fa fa-envelope-o fa-fw" aria-hidden="true"></i> <input class="form-control" type="text" placeholder="您的邮箱地址"> </div> <div> <i class="fa fa-key fa-fw" aria-hidden="true"></i> <input class="form-control" type="password" placeholder="请输入密码"> </div> </body>
要用图标的话,就上网站去找,而后把代码复制下来就好。上面还有更多使用案例。
这是另一种条件语句:
switch(n) { case 1: 执行代码块 1 break; case 2: 执行代码块 2 break; default: 都不配时才执行的代码块 }
break: 每一个 case 最后,请使用 break 来阻止代码自动地向下一个 case 运行。
default:使用 default 关键词来规定匹配不存在时执行的代码。
函数就是在大括号中的代码块,前面使用了关键词 function:
function myFunction(var1,var2) { 这里是要执行的代码 }
就是没有函数名的函数,普通函数去掉函数名就是匿名函数了。只能被调用一次,好比定时器(setInterval),第一个参数是要执行的代码,就可使用匿名函数。
function (var1,var2) { 这里是要执行的代码 }
自执行函数是用小括号将匿名函数包起来,而后加小括号(传参)当即执行。由于函数无名字,实现了做用域的绝对隔离和函数名的冲突问题。基本形式以下:
(function (var1,var2) { 这里是要执行的代码 })(var1,var2);
普通的函数,定义完以后暂时不执行,以后经过函数名加小括号调用执行。自执行函数,定义完以后紧接着是一个小括号,立刻调用执行。
语法以下:
JSON.stringify(obj)
:序列化,将对象的状态转换为字符串JSON.parse(str)
:反序列化> JSON.stringify([1,2,3,4,5]) // 序列化 < "[1,2,3,4,5]" > JSON.parse("[1,2,3,4,5]") // 反序列化 < [object Array]: [1, 2, 3, 4, 5] >
转义urlencodeURI()
:把字符串做为 URI 进行编码decodeURI()
:对 encodeURI() 函数编码过的 URI 进行解码encodeURIComponent()
:把字符串做为 URI 组件进行编码decodeURIComponent()
:对 encodeURIComponent() 函数编码的 URI 进行解码
> url = "https://www.baidu.com/s?wd=前端" < "https://www.baidu.com/s?wd=前端" > url2 = encodeURI(url) < "https://www.baidu.com/s?wd=%E5%89%8D%E7%AB%AF" > decodeURI(url2) < "https://www.baidu.com/s?wd=前端" > url3 = encodeURIComponent(url) < "https%3A%2F%2Fwww.baidu.com%2Fs%3Fwd%3D%E5%89%8D%E7%AB%AF" > decodeURIComponent(url3) < "https://www.baidu.com/s?wd=前端"
用上面的四个方法就行了,下面两个知道一下。escape()
:对字符串进行编码,这样就能够在全部的计算机上读取该字符串unescape()
:对经过 escape() 编码的字符串进行解码
注意:全部的方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( )
eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。语法:
eval(string)
参数是字符串形式的表达式或代码,而且能够有返回值。
python中也是以函数做为做用域。
在其余语言里,有的以代码块做为做用域。其实js也能够,经过使用let。
结合下面的第三条一块儿理解。
这个要在函数里套用函数的状况下会产生这个问题
<script> var name = 'Adam'; function func() { var name = 'Bob'; function inner() { var name = 'Cara'; alert(name) } return inner } var ret = func(); ret() </script>
上面的函数,执行的结果是Cara;若是把Cara注释掉,结果是Bob;若是把Bob再注释掉,则结果是Adam。这就是做用域链。并且因为做用域是调用以前建立的,因此和在哪里调用这个函数没有关系。虽然是在最外部调用的函数,可是做用域依然是定义它时的位置,即做用域是 inner 内部。
直接看例子说明:
<script> function func() { alert(name); var name = 'Adam'; } func() </script>
name的值是调用以后才赋值的,因此alert并不能取到后面的值。可是在alert以前name变量就已经建立好了,至关于在alert以前有一句 var name;
。虽然按顺序看定义变量是也是在alert后面,然而其实是在执行代码以前就完成了全部变量的声明。一个未赋值的变量的值是 undefined ,运行的结果就是这个值。若是注释掉赋值语句,直接取一个不存在的变量,结果会报错(通常浏览器应该会捕获这个错误,可是至少结果是不同的)。
js没有类,js能够用函数做类,定义一个类和定义一个函数同样。
<script> // 定义类,其实这个就是构造函数 function Foo(name) { this.name = name } var obj = new Foo('Barry'); // 建立对象 var obj2 = new Foo('Oliver'); // 建立另外一个对象 alert(obj.name); // 取对象的属性 </script>
关于this,在构造函数中的this指向新建立的对象自己。
类有属性还有方法,属性有了,还要方法。既然Foo是构造函数,显然不能再Foo里定义类的方法。这里要引入原型,方法定义在原型里,Foo.prototype 是 Foo 的原型:
<script> // 定义类,其实这个是构造函数 function Foo(name) { this.name = name } // 定义方法的方式,里面是字典的形式,貌似能够在里面定义多个方法 Foo.prototype = { 'sayName': function () { alert(this.name) } }; var obj = new Foo('Barry'); // 建立对象 obj.sayName(); // 调用对象的方法 </script>
把这里的概念和以前学习过的python的面向对象的概念比较一下:
作一个input的输入框,默认在框内先填上提示内容。当用户选择了input框后,状况框内的文本,让用户输入。
这里要用到2个新的事件,onfocus 和 onblur。这里的事件不能用onclick,由于用户有多种方式能够选定输入框,好比鼠标点击,还有用Tab切换等等。要响应这类事件,使用 onfocus 。相反,若是用户选定后离开,则触发事件 onblur。
onfocus 事件 :在得到焦点时触发
onblur 事件 :在失去焦点时触发
<body> <div> <label for="keyword">关键字:</label> <input id="keyword" type="text" value="请输入关键字" onfocus="Focus()" onblur="Blur()"> </div> <script> // 得到焦点时,确认里面是不是默认的value;是则清空 function Focus() { var obj = document.getElementById('keyword'); if(obj.value === "请输入关键字"){ obj.value = '' } } // 失去焦点时,确认内容是否为空;是则变回默认的value function Blur() { var obj = document.getElementById('keyword'); if(obj.value.length === 0){ obj.value = "请输入关键字" } } </script> </body>
另外一种实现方法:
在的html5中提供了一个新的属性(placeholder),简单的设置这个属性就能完成上面的效果。前提是客户端的浏览器支持html5。
<body> <div> <label for="keyword">关键字:</label> <input id="keyword" type="text" placeholder="请输入关键字"> </div> </body>
以前已经用过经过修改标签的 class 属性来达到修改样式的效果,直接添加或去除 class 来获取或去除某个 class 的样式。
这里经过DOM获取到对象后,直接修改对象的 style 属性,更加直接。
<body> <span id="i1" style="font-size: 16px;">字体大小</span> <script> alert("点击后修改字体大小"); obj = document.getElementById('i1'); obj.style.fontSize = '48px'; </script> </body>
这里要注意一下style在标签中和js中的写法是不同的。
属性操做,有下面这些方法:obj.setAttribute(key, value)
:设置标签属性obj.getAttribute(key)
:获取标签属性的值obj.hasAttribute(key)
:检查标签是否存在该属性obj.removeAttribute(key)
:去除标签属性obj.attributes()
:获取标签全部的属性
方法一:经过对象来建立:document.createElement()
:建立一个标签对象
> var tag = document.createElement('span') // 建立一个span标签 < undefined > tag.innerText = "建立标签" // 标签的内容 < "建立标签" > tag.className = 'c1' // 设置标签的属性 < "c1" > tag < <span class="c1">建立标签</span>
这里的tag是一个对象。
方法二:经过字符串来建立:
> var tag = '<span class="c1">建立标签</span>' < undefined > tag < "<span class="c1">建立标签</span>"
添加的时候注意内部的引号,你能够错开使用单引号和双引号。另外还可使用(\"),表示字符串内的引号字符。
这里的tag实际只是html代码的字符串。
方法一:基于Element的操做targetElement.insertAdjacentElement(position, element);
:插入标签对象element.insertAdjacentHTML(position, text);
:插入标签字符串
position参数,只有4个值。beforebegin、afterbegin、beforeend、afterend。对应的位置以下所示:
<!-- beforebegin --> <p> <!-- afterbegin --> foo <!-- beforeend --> </p> <!-- afterend -->
代码示例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .c1{ color: red; } </style> </head> <body> <div id="i1"> <p>初始的内容</p> </div> <script> var tag1 = document.createElement('p'); tag1.innerText = "建立的标签1"; tag1.className = 'c1'; var obj = document.getElementById('i1'); obj.insertAdjacentElement("beforeend", tag1); // 插入标签对象 var tag2 = '<p class="c1">建立的标签2</p>'; obj.insertAdjacentHTML("beforeend", tag2); // 插入标签字符串 </script> </body> </html>
方法二:基于Node的操做
其实上面的方法应该够用了,不过这里还有两个方法:var aChild = element.appendChild(aChild);
:在当前对象后面添加,和上面的 beforeend 的效果同样。var insertedNode = parentNode.insertBefore(newNode, referenceNode);
:在父节点的下的 reference 子节点前插入。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> .c1{ color: red; } </style> </head> <body> <div id="i1"> <p>初始的内容</p> </div> <script> var tag1 = document.createElement('p'); tag1.innerText = "建立的P标签1"; tag1.className = 'c1'; var obj = document.getElementById('i1'); obj1 = obj.appendChild(tag1); var tag2 = document.createElement('div'); tag2.innerText = '建立的DIV标签2'; tag2.setAttribute('class', 'c1'); var parentObj = document.getElementById('i1').parentNode; parentObj.insertBefore(tag2, obj); </script> </body> </html>
不必定非得要 input 来提交表单,任何标签经过js触发均可以提交表单。只要获取 form 对象,调用对象的 submit() 方法便可:formObj.submit()
:提交表单
<body> <form action="https://www.baidu.com/s" id="f1"> <input type="text" name="wd" /> <input type="submit" value="搜索" /> <a onclick="submitForm()" style="border: 1px solid">点我也能提交</a> </form> <script> function submitForm() { document.getElementById('f1').submit(); } </script> </body>
在 js 中有三种消息框:警告框、确认框、提示框。
另外还有一个 console.log()
,是向控制台输出信息。警告框以前已经掌握了。
下面是确认框和提示框。
语法:confirm(message)
显示一个消息的确认框。和警告框不一样,有两个按钮,而且有返回值。按确认会返回true,按取消会返回false。
举例以下,分别试试按肯定和取消的效果:
<body> <h1 id="i1">分别试试按肯定和取消</h1> <script> // 这里顺便试试自执行函数 (function () { obj = document.getElementById('i1') var r = confirm("弹出确认框"); if(r === true){ obj.innerText = "你点击了肯定" } else { obj.innerText = "你点击了取消" } })() </script> </body>
语法:prompt("文本","默认值")
弹出一个让用户输入的对话框。第一个变量,会显示在输入框上面做为提示信息。第二个变量会做为输入框内的默认值事先填写好。
<body> <script> (function () { var name = prompt("请输入你的名字", "张三"); if(name.length > 0){ document.write("<p>你好,"+ name) } })() </script> </body>
如今谁还用弹出框作交互呢,用 input 应该根据友好吧。
location.href
:设置或返回完整的 URL。
示例,先用浏览器随便打开一个页面,进入控制台测试:
> location.href // 返回当前的url < "about:blank" > location.href = "http://www.51cto.com" // 设置url,页面会跳转
location.reload()
:从新加载
location对象是包含有关当前 URL 的信息,还有更多属性和方法,这里只分别举例了两个经常使用的。
用两种定时器,一种是循环执行的定时器,一种是只执行一次的定时器:setInterval(code,millisec)
:按照指定的周期(以毫秒计)来调用函数或计算表达式。clearInterval(t)
,取消这个定时器。setTimeout(code,millisec)
:在指定的毫秒数后调用函数或计算表达式。clearTimeout(t)
,取消这个定时器
上面两个方法都有返回值(假设是t),后面的方法就是用于取消这个定时器的,具体看下面的例子:
<body> <h1>定时器测试<span id="i1"></span></h1> <script> // 启动一个定时器,每秒刷新显示内容 var count = 0; t = setInterval(function () { count ++; document.getElementById('i1').innerText = count }, 1000); // 设置另外一个定时器,5秒后清除前面的定时器,并弹框 setTimeout("clearInterval(t); alert('结束')", 5000) </script> </body>
timeout 定时器的应用场景,好比当你点击某个按钮后,会显示一条提示信息,可是信息不用永久显示在哪里,通过一段时间后该条信息会自动消失。这时就要用到这种只执行一次的定时器了:
<body> <div id="i1">点击下面的按钮</div> <div> <input type="button" value="开始" onclick="start()"> <input type="button" value="取消" onclick="stop()"> </div> <script> var t; // 这里先把t声明为全局变量,下面的两个function里都是全局的t // 点击按钮后显示一条提示消息,2秒后变回原来的信息 function start() { obj = document.getElementById('i1'); obj.innerText = "你刚点了开始(2秒后消息消失)"; t = setTimeout(function () { obj.innerText = "点击下面的按钮" }, 2000) } // 点了取消按钮后,清除了计时器,文字就不会变回去了 function stop() { clearTimeout(t); } </script> </body>
这里的事件都以onclick事件举例,事件绑定的方法有下面几种
在标签内写onclick事件。以前都是用这个方法绑定事件的,简单,直观,可是LOW。
在JS写onclick=function(){}函数。推荐用这种方法绑定事件。结构更加清晰,让js代码从html标签中剥离出来。
<body> <p> 在标签内写onclick事件 <input type="button" onclick="func()" value="点我1"> </p> <p> 在JS写onclick=function(){}函数 <input type="button" value="点我2" id="i2"> </p> <script> function func() { alert("点我1") } document.getElementById('i2').onclick = function () { alert("点我2") } </script> </body>
从上面的例子中并看不出有什么优点,假如咱们有不少标签要绑定同一个事件,那么只要在js里写一个for循环就能一次所有完成绑定了:
<body> <input type='button' value='0'/> <input type='button' value='1'/> <script> list_btn = document.getElementsByTagName('input'); // 给全部的button都绑定下面的事件 for(var i=0; i<list_btn.length; i++){ list_btn[i].onclick = function () { // alert(list_btn[i].value); // 这句是错的 // alert(i); // 上面的问题,看看这个i的值 alert(this.value); // 这里的this指的是调用这个函数的对象,其实仍是上面的list_btn[i],可是不能那么写 } } </script> </body>
上面的例子中,若是使用第一个alert的写法,会报错。得用最后的写法,用this来指代当前的对象(即标签)。这里产生问题的缘由是js做用域的问题。
在上面的例子中,若是咱们放开第二个alert语句查看i的值,就会发现,始终是2。由于这里i不是这个函数内的局部变量,而是在函数外部一直在变的,最终的值是2。因此上面的数组要取下标2天然是取不到的。解决方法就是用this,这里谁调用这个函数,这个this就指向谁。
既然是做用域的问题,那么不用this,经过闭包来限制做用域同样也是能够实现的。
<body> <input type='button' value='0'/> <input type='button' value='1'/> <script> list_btn = document.getElementsByTagName('input'); // 给全部的button都绑定下面的事件 for(var i=0; i<list_btn.length; i++){ // 外面再套一层function,作成一个闭包 // 把i的值传递给arg,这里arg的做用域是这里闭包内 (function (arg) { list_btn[i].onclick = function () { alert(list_btn[arg].value); // 如今应该对了 // alert(arg); // 看看这里变量的值 } })(i) } </script> </body>
确定仍是用this简单,通常都用this,这里就展开解释一下做用域的问题。
上面的方法将事件绑定写在js中的方法基本已经够用了,仍有不足。若是须要为一个标签绑定两个onclick事件,以前的方法显然都没法实现。就要用到 addEventListener ,下面只是简单的讲一下实现上面这种需求的实现方法,更深就算了。target.addEventListener(type, listener, useCapture);
:将 type 的事件类型注册到 target 对象上。
type :表示监听事件类型的字符串。这里 click 表示按下并释听任意鼠标按键(没有 onclick)。
listener :在这里写上要触发的函数
useCapture :布尔值,默认false。两个元素都对同一个事件注册了一个处理函数时有两种不一样的事件传播方式,事件冒泡(false)和事件捕获(true)。
先不考虑第三个参数,点击按钮后要触发了两个事件,分别修改 i1 和 i2 的样式:
<body> <h1 id="i1">Test1</h1> <h1 id="i2">Test2</h1> <input id="btn" type="button" value="改变字体颜色"> <script> obj1 = document.getElementById('i1'); obj2 = document.getElementById('i2'); btn = document.getElementById('btn'); btn.addEventListener('click', function () { obj1.style.color = 'red' }); btn.addEventListener('click', function () { obj2.style.color = 'blue' }); </script>
下面是有元素嵌套的状况,这时候第三个参数就有区别了。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style> #main{ background-color: blue; width: 500px; height: 400px; } #content{ background-color: red; width: 300px; height: 200px; } </style> </head> <body> <h1 id="i1">看个人颜色</h1> <div id="main"> <div id="content"></div> </div> <script> var farther = document.getElementById('main'); var son = document.getElementById('content'); var str = document.getElementById('i1'); farther.addEventListener('click', function () { str.style.color = 'blue' }, true); // 就是这里的参数会影响运行的结果,改为false试试 son.addEventListener('click', function () { str.style.color = 'red' }); </script> </body> </html>
当有元素重叠的时候,同时出发一个事件,每一个元素的事件执行会有前后顺序。默认是false,冒泡,先执行内层元素的事件,而后向外传播。上面的例子中设置了true,捕获,先执行外层元素的事件,而后往内传播。当点击重叠区域的时候,每一个事件都响应并执行了,最后执行的是内层的事件,因此最后变成了内层事件设置的颜色。
这周的内容并无做业,要等学了下周的jQuery一块儿搞个做业了。