1.事件驱动

js控制页面的行为是由事件驱动的。
    
    什么是事件?(怎么发生的)
    事件就是js侦测到用户的操作或是页面上的一些行为
 
    事件源(发生在谁身上)
    引发事件的元素
 
    事件处理程序(发生了什么事)
    对事件处理的程序或函数
 
    事件对象(用来记录发生事件时的相关信息)

 只有在事件发生的时候,才会产生事件对象,无法手动创建,并且事件对象只能在处理函数内部访问,处理函数允许结束后该对象自动销毁
 

2. 事件的分类:

    鼠标事件:
        onclick        单击
        ondblclick     双击
        onmousedown    按下
        onmouseup      抬起
        onmousemove    移动
        onmouseover    放上去        onmouseenter    进入
        onmouseout     离开          onmouseleave    离开
 
        onmousewheel   滚轮事件
 
        onmouseenter和onmouseleave不支持事件冒泡
        
    表单事件:
        onsubmit       提交
        onfocus        获得焦点
        onblur         失去焦点
        onchange       改变文本区域的内容
 
    页面事件:
        onload         加载完成
。。。
在W3C标准中:事件可以写在行内,但是因为结构和行为要分离,所以我们一半情况下用JS的方法来绑定事件,只有在极少数情况下,才将事件写在行内。
    行内事件又叫:HTML事件处理程序
 

3.事件对象的概念和作用

    1.事件有对象!叫事件对象(event)
    2.事件对象是浏览器给的
    3.事件对象不叫不出来
 
    什么是event事件对象?
    用来记录一些事件发生时的相关信息的对象,每次事件发生的时候,会在函数或方法内部产生一个事件对象,这个事件对象就是event。
 
    特征:
        1.只有当事件发生的时候才会产生,只能在处理函数内部访问
        2.处理函数运行结束后自动销毁

获取方式(兼容问题)

document.onclick = function(eve){
var e = eve || window.event;
console.log(e);
}
注意:event需要逐层传递,不要疏忽外部的function

自定义右键菜单

下面是自定义右键菜单的案例:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style type="text/css">
body {
font-size: 16px;
font-family: "KaiTi";
}
ul {
list-style: none;
margin:0;
padding: 0;
}
a {
text-decoration: none;
color: #333;
}
.contextmenu {
width: 200px;
border: 1px solid #999;
box-shadow: 3px 3px 3px #ccc;
background-color: #fff;
position: absolute;
top: 10px;
left: 10px;
display: none;
}
.contextmenu li {
height: 38px;
line-height: 38px;
}
.contextmenu li a {
display: block;
padding:0 20px;
}
.contextmenu li a:hover {
background-color: #ccc;
color: white;
font-weight: bold;
}
</style>
</head>
<body>
<div class="contextmenu" id="context">
<ul>
<li><a href="javascript:;">复制</a></li>
<li><a href="javascript:;">粘贴</a></li>
<li><a href="javascript:;">剪切</a></li>
<li><a href="javascript:;">获取种子</a></li>
<li><a href="javascript:;">迅雷下载</a></li>
</ul>
</div>
</body>
<script>
// 先来获取菜单列表,然后让其在鼠标右击的时候显示出来
document.oncontextmenu = function (ob) { // ob 表示event事件 // 兼容event事件
var e = ob || window.event; // 首先获取菜单
var context = document.getElementById('context');
// 让菜单显示出来
context.style.display = "block"; // 让菜单跟随鼠标位置而移动
// 需要使用鼠标的坐标,让鼠标的坐标位置为菜单的左上角0,0
var x = e.clientX;
var y = e.clientY; // 获取窗口的宽度和高度(在浏览器中的可用窗口宽度和高度,当调整窗口大小的时候,获取的值也会变)
var w = window.innerWidth;
var h = window.innerHeight;
console.log("窗口宽度为:"+w,"窗口的高度为:"+h); // 将获得的值赋值给菜单的右键菜单,从而实现让右键菜单会出现在鼠标的位置上
// context.style.left = x + 'px';
// context.style.top = y + 'px';
// 重新调整宽度和高度
context.style.left =Math.min(w - 202,x) + 'px';
context.style.top = Math.min(h - 230,y) + 'px'; // 通过return false关闭系统默认菜单
return false;
}
// 当鼠标单击之后,希望关闭右键菜单
document.onclick = function () {
var contextmenu = document.getElementById('context');
// 让菜单在单击之后消失
contextmenu.style.display = 'none';
}
</script>
</html>

4.鼠标事件常用属性介绍

    检测按下的鼠标按键:event.button
    返回值为0,左键;返回值为1,中键;返回值为2,右键
 
    检测相对于浏览器的位置:clientX和clientY
    当鼠标事件发生时,鼠标相对于浏览器左上角的位置
    
    检测相对于文档的位置:pageX和pageY
    当鼠标事件发生时,鼠标相对于文档左上角的位置。(IE7/8无)(类似于event.clientX和event.clientY)
 
    检测相对于屏幕的位置:screenX和screenY
    当鼠标事件发生时,鼠标相对于屏幕左上角的位置
 
    检测相对于事件源的位置:offsetX和offsetY
    当鼠标事件发生时,鼠标相对于事件发生元素左上角的位置
 

获取鼠标坐标

通过evnet对象当中的内容,我们可以非常轻易的获取鼠标的坐标。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> </body>
<script>
document.onmousemove = function (env) {
var env = env || window.event;
console.log(env.clientX,env.clientY); // clientX 鼠标x轴坐标,clientY鼠标y轴坐标
}
</script>
</html>
 根据鼠标事件和event对象来完成一个案例:图层拖拽。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>图层拖拽</title>
<style type="text/css">
.box {
width:200px;
height: 200px;
background-color: orange;
border: 2px solid pink;
cursor: pointer;
position: absolute;
left:100px;
top: 20px;
}
</style>
</head>
<body>
<h1>图层拖拽</h1>
<hr>
<div class="box" id="box"></div>
</body>
<script type="text/javascript"> // 获取元素绑定事件
var oBox = document.getElementById("box");
oBox.onmousedown = function (env) {
var env = env || window.event; // 获取一下鼠标在div上的位置
var left = env.clientX - oBox.offsetLeft;
var top = env.clientY - oBox.offsetTop; // 为了方便查看效果,当鼠标点击之后,改变一下颜色
oBox.style.background = "#999"; oBox.onmousemove = function (env) {
var env = env || window.event; var x = env.clientX;
var y = env.clientY;
oBox.style.left = (x - left) + 'px';
oBox.style.top = (y - top) + 'px';
} } oBox.onmouseup = function () {
oBox.style.background = "orange";
oBox.onmousemove = function (){}
} </script>
</html>

5.键盘事件(keyup/keydown/keypress)

    键盘事件:
        onkeydown      键盘按下
        onkeyup        键盘抬起
        onkeypress     按下并抬起数字字母按键
    event.keyCode        返回当前按键的ASCII码
 
        空格    32
        回车    13
        左      37
        上      38
        右      39
        下      40
 
    兼容问题:  var eve = eve || window.event
              var keyC = eve.keyCode || eve.which
 
    案例:通过键盘上下左右,控制页面中的元素位置移动
 
    ctrlKey        判断ctrl是否被按下,按下返回true
    shiftKey       判断shift是否被按下,按下返回true
    altKey         判断alt是否被按下,按下返回true
 
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> </body>
<script>
document.onkeydown = function (env) {
var env = env || window.event;
console.log(env); // KeyboardEvent
}
</script>
</html>

兼容性问题:

IE:

支持keyCode

不支持which和charCode,二者值为 undefined

在Firefox下:

支持keyCode,除功能键外,其他键值始终为 0

支持which和charCode,二者的值相同

在Opera下:

支持keyCode和which,二者的值相同

不支持charCode,值为 undefined

6.器的默认行为

很多时候,我们的浏览器都具备一些默认的行为,这些默认的行为在某些时刻我们需要取消或者屏蔽掉,例如当我们在我们自己的网页中自定义了右键菜单,那么我们就希望屏蔽掉浏览器的右键菜单,所以我们可以如下

document.oncontextmenu = function () {
return false;
}
其他写法及兼容
//阻止浏览器的默认行为
function stopDefault( e ) {
//阻止默认浏览器动作(W3C)
if ( e && e.preventDefault )
e.preventDefault();
//IE中阻止函数器默认动作的方式
else
window.event.returnValue = false;
return false;
}

7.冒泡

事件流:事件执行顺序我们叫他事件流。
    事件流中事件冒泡的由来:IE公司认为,如果你面前有个靶子,你的飞镖射中了其中一环,并不仅仅是只对这一环产生了操作,而是对整个靶子都产生了操作。
    所以,当最里面的元素触发了事件的时候,会依次向上触发所有元素的相同事件(从触发事件的元素开始一直向上触发),但是事件冒泡对我们几乎没有任何好处,所以我们需要阻止事件冒泡。
 
    eve.stopPropagation();            
    eve.cancelBubble = true;        //兼容IE
案例:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
div {
padding:40px;
}
#div1 {
background-color: red;
}
#div2 {
background-color: pink;
}
#div3 {
background-color: orange;
}
</style>
</head>
<body>
<div id="div1">
<div id="div2">
<div id="div3"></div>
</div>
</div>
</body>
<script>
var d1 = document.getElementById('div1');
var d2 = document.getElementById('div2');
var d3 = document.getElementById('div3'); function fn1() {
alert(this.id);
} // 绑定事件
d1.onclick = fn1;
d2.onclick = fn1;
d3.onclick = fn1;
</script>
</html>

8.事件监听器(兼容)

    事件触发阶段主要由于事件流:DOM0级事件处理阶段和DOM2级事件处理;
 
    DOM0级事件处理,是一种赋值方式,是被所有浏览器所支持的,简单易懂容易操作;
        元素.onclick = function(){}
 
    DOM2级事件处理是所有DOM节点中的方法,可以重复绑定,但是浏览器兼容存在问题;
 
    非IE下:(这里的事件名不带on),第三个参数表示是在捕获阶段还是冒泡阶段。可以重复绑定事件,执行顺序按照绑定顺序来执行。
 
    oDiv.addEventListener('click',fn,false);
    oDiv.removeEventListener('click',fn ,false);
 
    IE下:
 
    只有冒泡阶段,所以没有第三个参数;(这里的事件名需要加on)
    oDiv.attachEvent();
    oDiv.detachEvent() ;
 
冒泡:从下往上(从里往外)
捕获:从上往下(从外往内)
 
2.封装成两个函数的方式
function addEvent(obj,inci,back){
if(obj.addEventListener){
obj.addEventListener(inci,back);
}else if(obj.attachEvent){
obj.attachEvent("on" + inci,back);
}else{
obj["on"+inci] = back;
}
} function removeEvent(obj,inci,back){
if(obj.removeEventListener){
obj.removeEventListener(inci,back,false);
}else if(obj.detachEvent){
obj.detachEvent("on" + inci,back);
}else{
obj["on"+inci] = null;
}
}

事件委托机制

    通过e.target获取触发事件的事件源

    利用事件冒泡原理,将绑定在多个子元素身上的相同事件,绑定在页面上现存的父元素身上。

        oul.onclick = function(eve){
var e = eve || window.event;
var target = e.target || e.srcElement;
if(target.nodeName == "LI"){
console.log(target.innerHTML);
}
}
优势:
1.节省性能
2.可以给页面上暂时不存在的元素绑定事件
 事件流的三种状态:
    事件冒泡
    事件捕获
    目标阶段
 
 

------------恢复内容结束------------

2.封装成两个函数的方式
    function addEvent(obj,inci,back){
        if(obj.addEventListener){
            obj.addEventListener(inci,back);
        }else if(obj.attachEvent){
            obj.attachEvent("on" + inci,back);
        }else{
            obj["on"+inci] = back;
        }
    }
          
    function removeEvent(obj,inci,back){
        if(obj.removeEventListener){
            obj.removeEventListener(inci,back,false);
        }else if(obj.detachEvent){
            obj.detachEvent("on" + inci,back);
        }else{
            obj["on"+inci] = null;
        }
    }

JavaScript基础09——事件驱动的更多相关文章

  1. JavaScript基础入门09

    目录 JavaScript 基础入门09 Event 自定义右键菜单 获取鼠标按键 获取鼠标坐标 获取键盘按键 页面中位置的获取 浏览器的默认行为 冒泡 什么是冒泡 小练习 JavaScript 基础 ...

  2. JavaScript基础知识(一)

    一.JavaScript基础 1.JavaScript用法: HTML 中的脚本必须位于 <script> 与 </script> 标签之间. 脚本可被放置在 HTML 页面的 ...

  3. 前端之JavaScript基础

    前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript历史 1992年Nombas开发出C ...

  4. 一个简单的、面向对象的javascript基础框架

    如果以后公司再能让我独立做一套新的完整系统,那么我肯定会为这个系统再写一个前端框架,那么我到底该如何写这个框架呢? 在我以前的博客里我给大家展示了一个我自己写的框架,由于当时时间很紧张,做之前几乎没有 ...

  5. JavaScript基础插曲—元素样式,正则表达式,全局模式,提取数组

    JavaScript基础学习 学习js的基础很重要,可以让自己有更多的技能.我相信这个以后就会用到. Eg:点击选择框,在div中显示出选择的数量 window.onload = function() ...

  6. 第三篇:web之前端之JavaScript基础

    前端之JavaScript基础   前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript ...

  7. 初识 Javascript.01 -- Javascript基础|输出方式、变量、变量命名规范、数据类型、

    Javascript基础 1 聊聊Javascript 1.1 Javascript的历史来源 94年网景公司   研发出世界上第一款浏览器. 95年 sun公司   java语言诞生 网景公司和su ...

  8. JavaScript基础(.....持续待更)

    javascript热身 一.你知道,为什么JavaScript非常值得我们学习吗? 1. 所有主流浏览器都支持JavaScript. 2. 目前,全世界大部分网页都使用JavaScript. 3. ...

  9. JavaScript基础:DOM操作详解

    本文最初发表于博客园,并在GitHub上持续更新前端的系列文章.欢迎在GitHub上关注我,一起入门和进阶前端. 以下是正文. 前言 JavaScript的组成 JavaScript基础分为三个部分: ...

随机推荐

  1. pgsql_pg的数据类型

    PostgreSQL 提供了丰富的数据类型.用户可以使用 CREATE TYPE 命令在数据库中创建新的数据类型.PostgreSQL 的数据类型被分为四种,分别是基本数据类型.复合数据类型.域和伪类 ...

  2. Django文件上传【单个/多个图片上传】

    准备工作 python:3.6.8 django:2.2.1 新建django项目 确定项目名称.使用的虚拟环境[当然这个也可以后期修改].app的名称 创建成功,选择在新的窗口中打开 图片上传 修改 ...

  3. SpringBoot第二十篇:初识ActiveMQ

    本文是作者之前写的关于 ActiveMQ 的一篇文章.此处为了保证该系列文章的完整性,故此处重新引入. 一.消息中间件的介绍 介绍 消息队列 是指利用 高效可靠 的 消息传递机制 进行与平台无关的 数 ...

  4. 修改Yarn的全局安装和缓存位置

    在CMD命令行中执行 #1.改变 yarn 全局安装位置 yarn config set global-folder "你的磁盘路径" #2.然后你会在你的用户目录找到 `.yar ...

  5. python之函数filter、reduce

    ---恢复内容开始--- 一.filter函数 filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表. 该接收两个参数,第一个为函数,第二个为序列,对序列中每个元 ...

  6. Rabbit MQ 学习参考

    网上的教程虽然多,但是提供demo的比较少,或者没有详细的说明,因此,本人就照着网上的教程做了几个demo,并把代码托管在码云,供有需要的参考. 项目地址:https://gitee.com/dhcl ...

  7. 基于 HTML5 WebGL 的 3D 智慧隧道漫游巡检

    前言 这次为大家展示的是通过 HT for Web 灵活的图型化编辑工具打造的智慧隧道监控系统.通过 HTML5 技术实现了桌面和移动端的跨平台性,同时现实了可视化运维. 这次主要跟大家分享里面的漫游 ...

  8. yml 字典列表

    观察: --- # 一位职工记录 name: Example Developer job: Developer skill: Elite employed: True foods: - Apple - ...

  9. [转] Performance — 前端性能监控利器

    timing (PerformanceTiming) 从输入url到用户可以使用页面的全过程时间统计,会返回一个PerformanceTiming对象,单位均为毫秒 按触发顺序排列所有属性:(更详细标 ...

  10. IC卡、ID卡、M1卡、射频卡的区别是什么(射频卡是种通信技术)

    IC卡.ID卡.M1卡.射频卡都是我们常见的一种智能卡,但是很多的顾客还是不清楚IC卡.ID卡.M1卡.射频卡的区别是什么,下面我们一起来看看吧. 所谓的IC卡就是集成电路卡,是继磁卡之后出现的又一种 ...