如果在HTML页面中直接嵌入JavaScript代码,我们需要使用 <script>标签,<script>和 </script>会告诉 JavaScript 在何处开始和结束。
<script>和 </script>之间的代码行包含了 JavaScript:
<script>
alert("My First JavaScript")
</script>
在HTML页面的任何位置(head部分 body部分 body的后面 较好)都可以插入script标签。
你有可能会在 <script>标签中看到使用 type="text/javascript",但是现在已经不必这样做了。JavaScript现在已经是所有现代浏览器以及 HTML5 中的默认脚本语言。
我们来看一个具体的示例
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script>
document.write("<h1>This is a heading</h1>")
document.write("<p>This is a paragraph</p>")
</script>
</body>
</html>
上述代码就是在在HTML页面中直接嵌入js代码。
接着我们来看看js代码的第二种用法:通过链接外部的JavaScript文件。
有时JavaScript代码过多的话,我们可以将代码单独放在JavaScript文件中然后链接起来。
我们链接外部JavaScript文件可以有以下步骤
1、首先我们建立一个JavaScript文件,扩展名是.js
2、然后将要编写的js代码写到Js文件中,并保存文件。
3、使用script标签将JavaScript文件链接到HTML文件中
<script type="text/javascript" src="JavaScript文件名和路径"></script>
需要注意一点的是,在一个已经引入外部js文件的script标签中,不能在它的开始标签和结束标签中写Js命令了。
我们来看一个具体的示例
我们先建一个js文件sample.js
然后写入js代码
document.write("<p>This is a paragraph</p>")
最后使用script标签将JavaScript文件链接到HTML文件中
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<script type="text/javascript" src="sample.js"></script>
</body>
</html>
以上就是js代码使用的两种方法
Javascript中事件处理事件处理分为三个阶段:捕获 - 处理 - 起泡。
以点击按钮为例:
捕获阶段:由外层到内层,首先调用给Window注册的click捕获阶段监听方法,然后document、body、一层层的父节点,一直到按钮本身。
处理阶段:调用按钮本身的click监听方法。
起泡阶段:从按钮开始,从内层到外层,依次调用各级父节点的起泡阶段监听方法,直到Window。
但是,对于IE8及更低版本IE,不支持捕获阶段,因此捕获阶段的事件监听目前尚不通用。
通常的事件处理方法形式为:
[javascript] view plain copy
function eventHandler(e) {
e = e || window.event
var target = e.target || e.srcElement
... ...
}
e为事件对象,当事件触发时,作为参数传进来,但对于IE8及更低版本IE不适用,只能通过全局的event变量访问,好在不会出现同时处理两个事件的情况。
如何注册事件监听方法?
(1)直接写在HTML里,DOM元素的属性里。
[javascript] view plain copy
<button id="btn" onclick="alert(123)">CLICK</button>
<button id="btn2" onclick="eventHandler()">CLICK2</button>
(2)在Javascript中,赋值给相应的DOM元素。
[javascript] view plain copy
document.getElementById('btn2').onclick = eventHandler
(3)addEventListener
[javascript] view plain copy
document.getElementById('btn2').addEventListener('click', eventHandler, false)
这里第三个参数是标识何时触发eventHandler,false表示在事件起泡阶段触发,true表示在事件捕获阶段触发。因为在IE8即更低版本不支持事件捕获,因此不经常使用true。
可以给同一个控件调用多次此注册方法,注册多个handler。
removeEventListener与之对应。
在IE8及更低版本IE中,使用attachMent代替。
[javascript] view plain copy
document.getElementById('btn2').attachEvent('onclick', eventHandler)
此时,浏览器仅支持事件起泡,不支持事件捕获,因此无第三个参数。
detachEvent与之对应。
阻止浏览器默认操作
对于通过第一种、第二种方法注册的监听方法,返回值如果为false,就阻止进一步的浏览器默认操作。以超链接为例:
[javascript] view plain copy
<a href="http://www.baidu.com" onclick="alert(1)return false">LINK</a>
点击了这个LINK后,因为返回值为false,因此不会跳转到百度首页(默认操作)。
对于通过第三种方法注册的监听方法,返回值无效,可以通过event.preventDefault()来阻止浏览器的默认操作。对于IE8即更低版本IE,不支持preventDefault方法,只能通过event.returnValue=false来实现。因此,阻止浏览器默认操作的通用写法为:
[javascript] view plain copy
if(e.preventDefault) {
e.preventDefault()
} else {
e.returnValue = false// IE8-
}
阻止事件起泡
[javascript] view plain copy
if(e.stopPropagation) {
e.stopPropagation()
} else {
e.cancelBubble = true
}
事件处理程序的方式了:1. 设置HTML标签属性为事件处理程序
文档元素的事件处理程序属性,其名字由“on”后面跟着事件名组成,例如:onclick、onmouseover。当然了,这种形式只能为DOM元素注册事件处理程序。实例:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/htmlcharset=utf-8"/>
<title>test</title>
<style type="text/css">
#div1{width: 300pxheight: 300pxbackground: redoverflow:hidden}
#div2{margin:50px autowidth: 200pxheight: 200pxbackground: greenoverflow:hidden}
#div3{margin:50px autowidth: 100pxheight: 100pxbackground: blue}
</style>
</head>
<body>
<div id="div1" onClick="console.log('div1')">div1
<div id="div2" oNClick="console.log('div2')">div2
<div id="div3" onclick="console.log('div3')" onclick="console.log('div3333')">div3
</div>
</div>
</div>
<script type="text/javascript">
</script>
</body>
</html>
结果(鼠标点击div3区域后):
从结果中可以看出:
①因为HTML里面不区分大小写,所以这里事件处理程序属性名大写、小写、大小混写均可,属性值就是相应事件处理程序的JavaScript代码;
②若给同一元素写多个onclick事件处理属性,浏览器只执行第一个onclick里面的代码,后面的会被忽略;
③这种形式是在事件冒泡过程中注册事件处理程序的;
2.设置JavaScript对象属性为事件处理程序
可以通过设置某一事件目标的事件处理程序属性来为其注册相应的事件处理程序。事件处理程序属性名字由“on”后面跟着事件名组成,例如:onclick、onmouseover。实例:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/htmlcharset=utf-8"/>
<title>test</title>
<style type="text/css">
#div1{width: 300pxheight: 300pxbackground: redoverflow:hidden}
#div2{margin:50px autowidth: 200pxheight: 200pxbackground: greenoverflow:hidden}
#div3{margin:50px autowidth: 100pxheight: 100pxbackground: blue}
</style>
</head>
<body>
<div id="div1">div1
<div id="div2">div2
<div id="div3">div3
</div>
</div>
</div>
<script type="text/javascript">
var div1 = document.getElementById('div1')
var div2 = document.getElementById('div2')
var div3 = document.getElementById('div3')
div1.onclick = function(){
console.log('div1')
}
div2.onclick = function(){
console.log('div2')
}
div3.onclick = function(){
console.log('div3')
}
div1.onclick = function(){
console.log('div11111')
}
div1.onClick = function(){
console.log('DIV11111')
}
</script>
</body>
</html>
结果(鼠标点击div3区域后):
从结果中可以看出:
①因为JavaScript是严格区分大小写的,所以,这种形式下属性名只能按规定小写;
②若给同一元素对象写多个onclick事件处理属性,后面写的会覆盖前面的(ps:这就是在修改一个对象属性的值,属性的值是唯一确定的);
③这种形式也是在事件冒泡过程中注册事件处理程序的;
3.addEventListener()
前两种方式出现在Web初期,众多浏览器都有实现。而addEventListener()方法是标准事件模型中定义的。任何能成为事件目标的对象——这些对象包括Window对象、Document对象和所有文档元素等——都定义了一个名叫addEventListener()的方法,使用这个方法可以为事件目标注册事件处理程序。addEventListener()接受三个参数:第一个参数是要注册处理程序的事件类型,其值是字符串,但并不包括前缀“on”;第二个参数是指当指定类型的事件发生时应该调用的函数;第三个参数是布尔值,其可以忽略(某些旧的浏览器上不能忽略这个参数),默认值为false。这种情况是在事件冒泡过程中注册事件处理程序。当其为true时,就是在事件捕获过程中注册事件处理程序。实例:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/htmlcharset=utf-8"/>
<title>test</title>
<style type="text/css">
#div1{width: 300pxheight: 300pxbackground: redoverflow:hidden}
#div2{margin:50px autowidth: 200pxheight: 200pxbackground: greenoverflow:hidden}
#div3{margin:50px autowidth: 100pxheight: 100pxbackground: blue}
</style>
</head>
<body>
<div id="div1">div1
<div id="div2">div2
<div id="div3">div3
</div>
</div>
</div>
<script type="text/javascript">
var div1 = document.getElementById('div1')
var div2 = document.getElementById('div2')
var div3 = document.getElementById('div3')
div1.addEventListener('click', function(){ console.log('div1-bubble')}, false)
div2.addEventListener('click', function(){ console.log('div2-bubble')}, false)
div3.addEventListener('click', function(){ console.log('div3-bubble')}, false)
div3.addEventListener('click', function(){ console.log('div3-bubble222')}, false)
div1.addEventListener('click', function(){ console.log('div1-capturing')}, true)
div2.addEventListener('click', function(){ console.log('div2-capturing')}, true)
div3.addEventListener('click', function(){ console.log('div3-capturing')}, true)
</script>
</body>
</html>
结果(鼠标点击div3区域后):
从结果中可以看出:
①addEventListener()第三个参数的作用正如上面所说;
②通过addEventListener()方法给同一对象注册多个同类型的事件,并不会发生忽略或覆盖,而是会按顺序依次执行;
相对addEventListener()的是removeEventListener()方法,它同样有三个参数,前两个参数自然跟addEventListener()的意义一样,而第三个参数也只需跟相应的addEventListener()的第三个参数保持一致即可,同样可以省略,默认值为false。它表示从对象中删除某个事件处理函数。实例:
div1.addEventListener('click', div1BubbleFun, false)
div1.removeEventListener('click', div1BubbleFun, false)
function div1BubbleFun(){
console.log('div1-bubble')
}
4.attachEvent()
但是,IE8以及其之前版本的浏览器并不支持addEventListener()和removeEventListener()。相应的,IE定义了类似的方法attachEvent()和detachEvent()。因为IE8以及其之前版本浏览器也不支持事件捕获,所以attachEvent()并不能注册捕获过程中的事件处理函数,因此attachEvent()和detachEvent()要求只有两个参数:事件类型和事件处理函数。而且,它们的第一个参数使用了带“on”前缀的事件处理程序属性名。实例:
var div1 = document.getElementById('div1')
div1.attachEvent('onclick', div1BubbleFun)
function div1BubbleFun(){
console.log('div1-bubble')
}
相应的,从对象上删除事件处理程序函数使用detachEvent()。例如:
div1.detachEvent('onclick', div1BubbleFun)
到此为止,我们已经说了浏览器中事件传播机制以及各种注册事件处理程序的方法。下面我们就再说说事件处理程序调用时的一些问题吧!
二.事件处理程序的调用
1.事件处理程序的参数:正如前面所说,通常事件对象作为参数传递给事件处理函数,但IE8以及其之前版本的浏览器中全局变量event才是事件对象。所以,我们在写相关代码时应该注意兼容性问题。实例(给页面上id为div1的元素添加点击事件,当点击该元素时在控制台输出事件类型和被点击元素本身):
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/htmlcharset=utf-8"/>
<title>test</title>
<style type="text/css">
#div1{width: 300pxheight: 300pxbackground: redoverflow: hidden}
</style>
</head>
<body>
<div id="div1">div1</div>
<script type="text/javascript">
var div1 = document.getElementById('div1')
if(div1.addEventListener){
div1.addEventListener('click', div1Fun, false)
}else if(div1.attachEvent){
div1.attachEvent('onclick', div1Fun)
}
function div1Fun(event){
event = event || window.event
var target = event.target || event.srcElement
console.log(event.type)
console.log(target)
}
</script>
</body>
</html>
2.事件处理程序的运行环境:关于事件处理程序的运行环境,也就是在事件处理程序中调用上下文(this值)的指向问题,可以看下面四个实例。
实例一:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/htmlcharset=utf-8"/>
<title>test</title>
<style type="text/css">
#div1{width: 300pxheight: 300pxbackground: redoverflow: hidden}
</style>
</head>
<body>
<div id="div1" onclick="console.log('html:')console.log(this)">div1</div>
<script type="text/javascript">
</script>
</body>
</html>
结果一:
从结果可以看出:
①第一种方法事件处理程序中this指向这个元素本身;
实例二:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/htmlcharset=utf-8"/>
<title>test</title>
<style type="text/css">
#div1{width: 300pxheight: 300pxbackground: redoverflow: hidden}
</style>
</head>
<body>
<div id="div1" onclick="console.log('html:')console.log(this)">div1</div>
<script type="text/javascript">
var div1 = document.getElementById('div1')
div1.onclick = function(){
console.log('div1.onclick:')
console.log(this)
}
</script>
</body>
</html>
结果二:
从结果可以看出:
①第二种方法事件处理程序中this也指向这个元素本身;
②存在第二种方法时,它会覆盖第一种方法注册的事件处理程序;
实例三:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/htmlcharset=utf-8"/>
<title>test</title>
<style type="text/css">
#div1{width: 300pxheight: 300pxbackground: redoverflow: hidden}
</style>
</head>
<body>
<div id="div1" onclick="console.log('html:')console.log(this)">div1</div>
<script type="text/javascript">
var div1 = document.getElementById('div1')
div1.onclick = function(){
console.log('div1.onclick:')
console.log(this)
}
div1.addEventListener('click', function(){
console.log('div1.addEventListener:')
console.log(this)
}, false)
</script>
</body>
</html>
结果三:
从结果可以看出:
①第三种方法事件处理程序中this也指向这个元素本身;
②第三种方法并不会覆盖第一种或第二种方法注册的事件处理程序;
实例四:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/htmlcharset=utf-8"/>
<title>test</title>
<style type="text/css">
#div1{width: 300pxheight: 300pxbackground: redoverflow: hidden}
</style>
</head>
<body>
<div id="div1" onclick="console.log('html:')console.log(this)">div1</div>
<script type="text/javascript">
var div1 = document.getElementById('div1')
div1.onclick = function(){
console.log('div1.onclick:')
console.log(this)
}
div1.attachEvent('onclick', function(){
console.log('div1.attachEvent:')
console.log(this === window)
})
</script>
</body>
</html>
结果四:
从结果可以看出:
①第四种方法事件处理程序中this指向全局对象Window;
②第四种方法也不会覆盖第一种或第二种方法注册的事件处理程序;
3.事件处理程序的调用顺序:多个事件处理程序调用规则如下:
①通过HTML属性注册的处理程序和通过设置对象属性的处理程序一直优先调用;
②使用addEventListener()注册的处理程序按照它们的注册顺序依次调用;
③使用attachEvent()注册的处理程序可能按照任何顺序调用,所以代码不应该依赖于调用顺序;