DOM事件编程

事件驱动编程:
所谓事件驱动,简单地说就是你点什么按钮(即产生什么事件),电脑执行什么操作(即调用什么函数).当然事件不仅限于用户的操作. 当对象处于某种状态时,可以发出一个消息通知,然后对这个消息感兴趣的程序就可以执行。

事件驱动编程中的几个核心对象:
1):事件源:谁发出事件通知,发出消息;也就是事件主体(通常指元素和标签);
2):事件名称:发出什么样的通知的名称,比如鼠标到我头上了,我被别人点了一下;
3):事件响应函数:谁对这个这个事件感兴趣,当这个事件发生时要执行什么样的操作;
4):事件对象:一般来说,当事件发生时,会产生一个描述该事件的具体对象,包括具体的参数等一起发给响应函数,好让他们通过事件对象来了解事件更加详细的信息。
很美丽动人的事故(事件):
有一天,在街上发现一个美女,小明伸出手在美女的脸蛋点击了一下,美女回头给了一巴掌,很痛!
  事件源:      美女.
  事件名称:    点击.
  事件响应:    给了小明一巴掌.
  事件对象:    时间,地点,人物,事情....
--------------------------------------------------------------------
示例:

<p style="color: red" id="p1">Hello world!</p>//事件源
function shout(e){//响应函数,监听函数
alert(e.clientX);//e事件对象
}
document.getElementById("p1").onclick=shout;//在事件源上绑定事件响应函数

JavaScript处理事件的基本机制:
  1):对DOM元素绑定事件处理函数;
  2):监听用户的操作;
  3):当用户在相应的DOM元素上进行与绑定事件对应的操作时,事件处理函数做出响应;
  4):将处理结果更新到 HTML 文档。

如何给HTML中的元素(事件源),绑定事件(有三种方式):
方式1:
  直接在元素上设置onXxx属性.(xxx表示事件名称).

 <p onclick="调用响应函数">P标签1</p>

  使用JS内置的函数:

<p onclick="alert(123);">P标签1</p>

  使用用户自定义的函数:

    <p onclick="sayHello(this);">P标签1</p>
function sayHello(current){
//alert(current);//当前事件源对象
alert("123");
}

方式1:很简单也很直观,但是同一种的事件只能绑定一次.
方式2:
在元素对象上直接设置onXxx事件属性,再给事件属性设置响应的函数.

<p id="p2">P标签2</p>
window.onload = function(){
//方式二:在元素对象上设置onXxx属性,再给该属性设置响应函数(使用多)
//获取元素对象
var pEl = document.getElementById("p");
pEl.onclick = function(){
alert("我是方式二");
};
}

对应同一种事件,后绑定的事件响应函数会覆盖之前该事件绑定的响应函数.

方式3:
使用方法来完成对元素的监听.
IE浏览器:
  [Object].attachEvent(“name_of_event_handler”, fnHandler);
  name_of_event_handler>>事件操作前,必须加"on"!!!
  多次添加监听后,触发顺序: 先添加,后执行
  [Object].detachEvent(“name_of_event_handler”, fnHandler);
  fnHandler : 移除时,传入的"事件响应函数",必须和添加时,传入的是同一个(通过相同标识符引用的那一个函数)
  匿名函数,每次创建的都不同
W3C浏览器:
  [Object].addEventListener(“name_of_event”, fnHandler);
  name_of_event>>直接使用事件(操作)名称
  多次添加监听后,触发顺序: 先添加,先执行
  IE浏览器从IE9开始,也支持.
  [Object].removeEventListener(“name_of_event”, fnHandler);
  fnHandler : 移除时,传入的"事件响应函数",必须和添加时,传入的是同一个(通过相同标识符引用的那一个函数)
  匿名函数,每次创建的都不同

window.onload = function(){
//方式三:设置监听事件
var divEle = document.getElementById("div1");
//W3C浏览器
// divEle.addEventListener("click", function(){
// alert("方式三");
// });
//IE浏览器
// divEle.attachEvent("onclick", function(){
// alert("IE浏览器");
// });
//通用
addListener(divEle, "click", function(){
alert("通用方式");
});
}; //定义一个通用的函数:可以为指定的元素设置指定的事件以及响应操作(解决浏览器兼容问题)
function addListener(ele, type, callBack){
if(ele.attachEvent){
//IE
ele.attachEvent("on"+type,callBack);
}else{
//W3C
ele.addEventListener(type,callBack);
}
}

事件其他相关的信息:

事件对象中的属性:

打字游戏简单设计:

打字游戏步骤:
1.准备一个游戏界面,提供开始游戏按钮
  禁用按钮,在页面加载完毕,即时启用"开始游戏"按钮
2.对开始按钮,添加点击事件
  2.1) 定时随机生成字符,并显示到页面中
    2.1.1> 创建<lable>元素,并设置随机字符
    <label style="position:absolute;top:30px;left:10px;background-color:red;width:20px;text-align:center;font-weight:bold;">I</label>
    2.1.2> 把<lable>元素添加到body元素中
  2.2) 让页面中的字符周期性向下移动
  2.3) 对键盘输入内容,监听,对比输入内容,和游戏界面字母内容,一致则消除

示例代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
<script type="text/javascript" src="index.js"></script>
</head>
<body>
<input id="startBtn" type="button" value="开始游戏" disabled style="background-color: orange;">
<!--<label style="position: absolute;top: 30px;left: 20px;width: 30px;
background-color: orange;text-align: center;font-weight: bold;">M</label> -->
</body>
</html>
function startGame(){
//1:禁用[开始游戏]按钮
this.disabled = true; //2:周期性的生成<label>元素,在<label>元素中带有随机A~Z字符
setInterval(function(){
//1):创建带有随机字符的<label>元素
var labelEl = createLabel();
//2):把创建的<label>元素添加到文档中显示
document.body.appendChild(labelEl);
//3):把<label>元素添加到labelArray数组中
labelArray.push(labelEl);
}, 500); //3:让<label>元素,往下移动
setInterval(function(){
//浏览器高度
var windowHeight = document.documentElement.clientHeight - 30;
p(windowHeight);
for (var index = 0; index < labelArray.length; index++) {
//获取每一个<label>元素
var labelEl = labelArray[index];
//修改<label>元素距离浏览器顶端的位置
var oldHeight = parseInt(labelEl.style.top);
if(oldHeight < windowHeight){
var height = oldHeight + 10;
labelEl.style.top = height+"px";
}else{
//从界面上移除
labelEl.parentNode.removeChild(labelEl);
//从数组中移除
labelArray.splice(index, 1);
}
}
}, 100); //4:给当前文档注册键盘按下的事件
document.onkeydown = function(event){
//当前按下键的ASICC码
var keyCode = event.keyCode;
//获取当前ASICC码对应的字符
var charCode = String.fromCharCode(keyCode);
//判断当前页面是否存在对应的字符,若存在,则删除
for (var index = 0; index < labelArray.length; index++) {
var labelEl = labelArray[index];
if(labelEl.innerHTML == charCode){
//从界面上移除
labelEl.parentNode.removeChild(labelEl);
//从数组中移除
labelArray.splice(index, 1);
break;
}
}
}
} //创建带有随机A~Z字符的<label>元素
function createLabel(){
//1:生成65~91之间的随机数
var charCode = parseInt(Math.random() * 26) + 65;
//2:生成A~Z之间的随机字符
var ch = String.fromCharCode(charCode);
//3:创建<label>元素,并设置属性样式和文本内容,最后再返回<label>元素
//<label style="position: absolute;top: 30px;left: 20px;width: 30px;
//background-color: orange;text-align: center;font-weight: bold;">M</label>
var labelEl = document.createElement("label");
//设置属性样式
labelEl.style.position="absolute";
labelEl.style.top="40px";
labelEl.style.width="30px";
labelEl.style.backgroundColor="orange";
labelEl.style.textAlign="center";
labelEl.style.fontWeight="bold";
//随机生成距离浏览器左端的位置
//浏览器宽度
var windowWidth = document.documentElement.clientWidth - 30;
//p(windowWidth);
var width = 20 + Math.random() * windowWidth;
labelEl.style.left=width+"px"; //设置文本内容
labelEl.innerHTML = ch;
//返回
return labelEl;
} //==================
function p(data){
console.debug(data);
}

练习题:

复选框的全选:

示例代码:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>checkbox</title>
<script type="text/javascript" src="checkbox.js"></script>
</head>
<body>
请选择你的爱好:<br/>
<input type="checkbox" onchange="checkChange()" id="checkAll"/>全选/全不选<br/>
<div>
<input type="checkbox" name="hobby"/>打篮球&nbsp;
<input type="checkbox" name="hobby"/>踢足球&nbsp;
<input type="checkbox" name="hobby"/>上网&nbsp;
<input type="checkbox" name="hobby"/>写代码&nbsp;
<input type="checkbox" name="hobby"/>写文档&nbsp;
<input type="checkbox" name="hobby"/>查BUG&nbsp;
</div> <div>
<input type="button" id="btn_checkAll" onclick="checkAll(true)" value="全选"/>
<input type="button" onclick="checkAll(false)" value="全不选"/>
<input type="button" onclick="checkUnAll()" value="反选"/>
</div>
</body>
</html>
//全选和全不选
//check:为true表示全选
//check:为false表示为全不选
function checkAll(check){
//获取所有name为hobby的input标签
var hobbys = document.getElementsByName("hobby");
for (var index = 0; index < hobbys.length; index++) {
//把传递过来的check的类型赋值给每个hobby的checked属性
hobbys[index].checked = check;
}
} //反选
function checkUnAll(){
//获取所有name为hobby的input标签
var hobbys = document.getElementsByName("hobby");
for (var index = 0; index < hobbys.length; index++) {
//把每个hobby的checked属性取反再赋值给自身
hobbys[index].checked = !hobbys[index].checked;
}
} //全选/全不选
function checkChange(){
//获取该全选选择框自身的checked属性,再将该属性赋值给其他name为hobby的input标签
var checkbox = document.getElementById("checkAll");
checkAll(checkbox.checked);
}

列表移动:

示例代码:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户新增</title>
<script type="text/javascript" src="select.js"></script>
</head>
<body>
<table border="1">
<tr>
<td>
<select id="select1" style="width:100px" size="10" multiple="multiple">
<option value="选项1">选项1</option>
<option value="选项2">选项2</option>
<option value="选项3">选项3</option>
<option value="选项4">选项4</option>
<option value="选项5">选项5</option>
<option value="选项6">选项6</option>
<option value="选项7">选项7</option>
<option value="选项8">选项8</option>
<option value="选项9">选项9</option>
</select>
</td>
<td align="center">
<input type="button" onclick="this2other('select1','select2');" value="-->"/><br/>
<input type="button" onclick="thisAll2other('select1','select2');" value="==>"/><br/>
<input type="button" onclick="this2other('select2','select1');" value="<--"/><br/>
<input type="button" onclick="thisAll2other('select2','select1');" value="<=="/>
</td>
<td>
<select id="select2" style="width:100px" size="10" multiple="multiple"></select>
</td>
</tr>
</table>
</body>
</html>
//把某一边选中的选项移动到另一边
function this2other(srcSelect, targetSelect){
//获取两边列表对象
var src = document.getElementById(srcSelect);
var target = document.getElementById(targetSelect);
//获取源列表下所有的子节点
var options = src.getElementsByTagName("option");
for (var index = 0; index < options.length; index++) {
var option = options[index];//得到每一个option标签对象
//判断该标签是否有被选中
if(option.selected){
target.appendChild(option);
index--;
}
}
} //把某一边所有的选项移动到另一边
function thisAll2other(srcSelect, targetSelect){
//获取两边列表对象
var src = document.getElementById(srcSelect);
var target = document.getElementById(targetSelect);
//判断源列表是否存在子节点,若存在则移动到目标列表
while(src.hasChildNodes()){
target.appendChild(src.firstChild);
}
}

用户的添加-删除:

示例代码:

<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>用户新增</title>
<script type="text/javascript" src="user.js"></script>
</head>
<body>
<form name="userForm">
<center>
用户录入<br/>
用户名:<input id="username" name="username" type="text" size=15/>
E-mail:<input id="email" name="email" type="text" size=15/>
电话:<input id="tel" name="tel" type="text" size=15/>
<input type="button" value="添加" onclick="saveUser();"/>
<input type="button" value="删除所有" onclick="deleteAll();"/>
</center>
</form>
<hr/>
<table border="1" align="center" cellpadding=0 cellspacing=0 width=400>
<thead>
<tr>
<th>用户名</th>
<th>E-mail</th>
<th>电话</th>
<th>操作</th>
</tr>
</thead>
<tbody id="userTbody">
<tr>
<td>乔峰</td>
<td>qiao@163.com</td>
<td>18212345678</td>
<td><a href='#'>删除</a></td>
</tr>
</tbody>
</table> </body>
</html>
//添加一行数据
function saveUser(){
//获取输入框的数据
var username = document.getElementById("username").value;
var email = document.getElementById("email").value;
var tel = document.getElementById("tel").value; //创建html片段,如下
/* <tr>
<td>乔峰</td>
<td>qiao@163.com</td>
<td>18212345678</td>
<td><a href='#'>删除</a></td>
</tr>*/ //创建元素
var tr = document.createElement("tr");
var usernameTd = document.createElement("td");
var emailTd = document.createElement("td");
var telTd = document.createElement("td");
var hrefTd = document.createElement("td"); //给创建的td元素赋值(文本内容)
tr.id = new Date().getTime();
usernameTd.innerHTML = username;
emailTd.innerHTML = email;
telTd.innerHTML = tel;
hrefTd.innerHTML = "<a href='javascript:deleteUser("+tr.id+")'>删除</a>"; //设置层次关系
tr.appendChild(usernameTd);
tr.appendChild(emailTd);
tr.appendChild(telTd);
tr.appendChild(hrefTd);
document.getElementById("userTbody").appendChild(tr);
} //删除所有用户数据
function deleteAll(){
document.getElementById("userTbody").innerHTML = "";
} //删除某个用户数据
function deleteUser(id){
//根据传递的id获取用户对象
var user = document.getElementById(id);
//删除该用户
user.parentNode.removeChild(user);
}

今日小结:

最新文章

  1. Android安全攻防战,反编译与混淆技术完全解析(下)
  2. 关于arcgis engine的工作空间(IWorkspace)和选择集(FeatureSelection)
  3. [MySQL] 按日期进行统计(前一天、本周、某一天)
  4. VMT &amp; DMT
  5. Hibernate检索方式 分类: SSH框架 2015-07-10 22:10 4人阅读 评论(0) 收藏
  6. 【IOS】分享下近一年IOS开发的经验总结
  7. linux 进程间消息队列通讯
  8. 深度探索QT窗口系统(五篇)
  9. ARC时代的内存管理
  10. Linux时间子系统之五:低分辨率定时器的原理和实现
  11. Prometheus监控⼊⻔简介
  12. jquery遇到的问题
  13. IPV6修复工具
  14. [转][solr] - 索引数据删除
  15. 【洛谷】【动态规划+单调队列】P1714 切蛋糕
  16. CentOS安装SVN客户端
  17. 超频真的不难!G3258超频4.5GHz全攻略
  18. form 表单排序
  19. IE9(8)跨域(CORS)解决方案
  20. js中的substr和substring区别

热门文章

  1. css奇技淫巧-色彩渐变与动态渐变
  2. 宏定义define和const的区别
  3. 论文阅读笔记四十七:Generalized Intersection over Union: A Metric and A Loss for Bounding Box Regression(CVPR2019)
  4. UMeditor控制多张图片上传顺序
  5. PHP 报错--Array to string conversion,请用print_r() 来输出数组
  6. Nuxt.js国际化vue-i18n的搭配使用
  7. js属性对象的propertyIsEnumerable方法
  8. Caused by: java.lang.IllegalStateException: RedisConnectionFactory is required
  9. https和http 调用过程中请求头 referrer 获取不到的问题
  10. 记一次线上Zabbix对Redis监控实录