事件
是前端语言,互联网体验的核心功能。
添加和移除事件处理
<h1>window事件</h1>
<div style='width:100px;height:100px;position:absolute;left:100px;top:100px;background-color:red' onclick='alert("a")'></div>
<script type = "text/javascript">
//句柄的绑定方式 div.onclick 这种方式等同于行间写 onclick='alert("a")'
var div = document.getElementsByTagName('div')[0];
//覆盖行间事件处理
div.onclick = function(){
alert('b');
};
//添加一个事件处理函数,不影响原有的处理函数,可并存。
div.addEventListener('click',function(){
alert('c');
},false);
//同一个处理函数,只执行一次,不管添加多少次。--> this指向div
div.addEventListener('click',test,false);
div.addEventListener('click',test,false);
div.addEventListener('click',test,false);
function test(){ alert('d') }
//IE方法,同一处理函数可执行多次。--> this指向winsow
//div.attachEvent('onclick',test);
//div.attachEvent('onclick',test);
//封装通用的事件处理函数 addEvent
function addEvent(elem,type,handle){
if(elem.addEventListener){
elem.addEventListener(type,handle,false)
}else if(elem.attachEvent){
elem.attachEvent('on' + type,function(){
handle.call(elem);
});
}else{
elem['on' + type] = handle;
}
}
//解除事件处理函数
// div.onclick = null;
// div.removeEventListener('click',test,false);
// div.detachEvent('onclick',test);
</script>
WebSocket示例
<h1>WebSocket示例</h1>
<div></div>
<button>send</button>
<button>close</button>
<script type = "text/javascript">
//http://www.blue-zero.com/WebSocket/
var div = document.getElementsByTagName('div')[0];
var btn1 = document.getElementsByTagName('button')[0];
var btn2 = document.getElementsByTagName('button')[1];
// 初始化一个 WebSocket 对象
var target = "ws://123.207.167.163:9010/ajaxchattest";
var ws = new WebSocket(target);
// var ws = new WebSocket("ws://121.40.165.18:8800");
// 建立 web socket 连接成功触发事件
ws.onopen = function () {
// 使用 send() 方法发送数据
addMessage("连接已打开...");
};
// 接收服务端数据时触发事件
ws.onmessage = function (evt) {
var received_msg = evt.data;
addMessage("数据已接收...");
addMessage(received_msg);
};
// 断开 web socket 连接成功触发事件
ws.onclose = function () {
addMessage("连接已关闭...");
};
btn1.onclick = function (){
//表示连接状态,可以是以下值:
//0 - 表示连接尚未建立。
//1 - 表示连接已建立,可以进行通信。
//2 - 表示连接正在进行关闭。
//3 - 表示连接已经关闭或者连接不能打开。
if(ws.readyState == 1){
ws.send("测试websocket");
}
else{
alert('连接已关闭,不能发送消息...');
}
}
btn2.onclick = function (){
alert('关闭websocket...');
ws.close(1000,'手动关闭...');
}
function addMessage(msg){
div.innerHTML += (msg + "<br>")
}
</script>
事件的冒泡和捕获
事件冒泡:结构上(非视觉上)嵌套关系的元素,会存在事件冒泡功能,即同一事件,自子元素冒泡向父元素(自底向上)。
事件捕获:结构上(非视觉上)嵌套关系的元素,会存在事件捕获功能,即同一事件,自父元素捕获至子元素(自顶向下)。
一个对象的一个事件处理,只能追寻一种事件处理模型,即有冒泡不捕获,有捕获不冒泡。
只有Google浏览器实现了事件捕获,IE没有捕获事件。
触发顺序,先捕获,后冒泡。
focus,blur,change,submit,reset,select 等事件不冒泡。
<h1>window事件</h1>
<h3>点击最里层的div时(代码结构上的最里层),外面两层div也响应了点击事件。这个现象就叫冒泡或捕获。冒泡自里向外执行,捕获自外向内。先执行对象的事件然后执行捕获模型,再执行冒泡模型</h3>
<span>代码编辑器多选编辑功能:先选择要编辑的文本,然后点击 ctrl+D 选择相同的文本,然后可以一起修改。</span>
<a href="https://www.baidu.com">百度</a>----<a href="javascript:void(false)">取消默认事件</a>
<div style='width:300px;height:300px;position:absolute;left:100px;top:250px;background-color:red'>
<div style ="width:200px;height:200px;position:absolute;left:300px;background-color:green">
<div style="width:100px;height:100px;position:absolute;left:200px;background-color:blue"></div>
</div>
</div>
<script type = "text/javascript">
var div1 = document.getElementsByTagName("div")[0];
var div2 = document.getElementsByTagName('div')[1];
var div3 = document.getElementsByTagName('div')[2];
//取消 a 标签的默认事件
var a = document.getElementsByTagName('a')[0];
a.onclick = function(){
return false;
}
//行间事件默认为冒泡模式 div.onclick = fn;
//addEventListener 第三个参数 false 冒泡模型,true 捕获模型。
//捕获
div1.addEventListener('click',function(){
console.log('div1');
},true);
div2.addEventListener('click',function(){
console.log('div2');
},true);
div3.addEventListener('click',function(){
console.log('div3');
},true);
//冒泡
div1.addEventListener('click',function(e){
// e.stopPropagation();//取消冒泡模型
// e.cancelBubble = true;//取消冒泡模型(IE)
console.log('div1_PoPo');
},false);
div2.addEventListener('click',function(e){
console.log('div2_PoPo');
},false);
div3.addEventListener('click',function(e){
console.log('div3_PoPo');
},false);
document.oncontextmenu = function(e){
console.log('doc rclick');
//获取事件源对象,chrome通过事件处理函数的参数形式传入,ie 保存在全局window.event中
var obj = e || window.event;
console.log(obj.target);//fireFox
console.log(obj.srcElement);//IE
e.preventDefault();//阻止浏览器默认事件(这里取消了弹出右键菜单) w3c
event.returnValue = false;//阻止浏览器默认事件(这里取消了弹出右键菜单) ie
return false;//阻止浏览器默认事件(这里取消了弹出右键菜单),用于行间事件
}
</script>
拖动小方块实现
<h1>拖动小方块</h1>
<div style ='width:1000px;height:100px;position:absolute;background-color:green'>
<div style='width:50px;height:50px;position:absolute;background-color:red'></div>
</div>
<script>
var div = document.getElementsByTagName('div')[1];
function drag(elem){
elem.onmousedown = function(ev){
//频繁用到变量可声明到外部,提高些性能。
var x = this.offsetLeft,
y = this.offsetTop;
document.onmousemove = function(e){
var event = e || window.event;
console.log('--------------------------')
//e.offsetX 鼠标点距离触发事件的元素的左边距离
console.log('鼠标点距离触发事件的元素的左边距离:',event.offsetX)
//e.clientX 鼠标点距离窗口的左边距离
console.log('鼠标点距离窗口的左边距离:',event.clientX);
//e.pageX 鼠标点距离窗口的左边距离 + 横向滚动条的滚动距离
console.log('鼠标点距离窗口的左边距离 + 横向滚动条的滚动距离:',e.pageX,' ',window.scrollX);
//e.screenX 鼠标点距离屏幕的左边距离
console.log('鼠标点距离屏幕的左边距离:',e.screenX);
elem.style.left = (x + event.clientX - ev.clientX) + 'px';
elem.style.top = (y + event.clientY - ev.clientY) + 'px';
}
}
elem.onmouseup = function(e){
document.onmousemove = null;
}
}
drag(div);
</script>
事件委托实现
<h1>window事件委托</h1>
<h2>利用冒泡模型和获取事件源对象,实现了用ul事件处理程序处理li的点击事件。这种方式就是事件委托。</h2>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
<script type = "text/javascript">
var ul = document.getElementsByTagName('ul')[0];
ul.onclick = function(e){
var obj = e || window.event;
var target = obj.target || obj.srcElement;
console.log(obj.target);
}
</script>
事件分类
鼠标事件
click、contextmenu、mouse开头的事件。
用消息属性button来区分鼠标的按键,0、1、2.
DOM3标准:click事件只监听左键,只能通过mousedown和mouseup来判断鼠标键。
解决mousedown和click的冲突
键盘事件
keydown、keyup、kepress
按住键盘时 keydown、keyup连续触发,抬起时触发keyup。
移动端 touchstart、touchmove、touchend
keydown可以响应任意键盘按键,区分不了字符的大小写、keypress响应字符类键盘按键。
keypress返回ASCII码,可转换成相应的字符。
文本类操作事件
input、change、focus、blur
窗体操作事件
scroll、load
load事件在网页全部加载完(包含需要下载的图片)才触发。用户体验不好,效率低。
练习
- 二阶菜单栏
- 贪吃蛇
- 扫雷