JavaScript基础09——事件驱动

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;

}

}

原文地址:https://www.cnblogs.com/wuziqiang/p/12076461.html

时间: 2024-08-01 22:47:02

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

JavaScript基础--事件驱动和访问CSS技术(十)

1.原理: 2.快速入门案例 js中的事件主要分为4种: 案例:监听鼠标点击事件,并能够显示鼠标点击的位置x,y <script language="javascript" type="text/javascript"> function test1(e){ window.alert('x='+e.clientX+'y='+e.clientY); } function test2(e){ window.alert('x='+e.clientX+'y='+

Javascript.01 -- Javascript基础

Javascript基础 1 聊聊Javascript 1.1 Javascript的历史来源 94年网景公司   研发出世界上第一款浏览器. 95年 sun公司   java语言诞生 网景公司和sun合作. Java+script   ===> javascript 1.2 W3c规范 ?结构标准        html ?表现标准   css ?行为标准      js 1.3 JavaScript和ECMAScript的关系 ECMAScript是一种由Ecma国际前身为欧洲计算机制造商协

【JavaScript基础】------有待完善

最近开始学习JavaScript,整理了一些相关的基础知识,日后继续完善~~~ JS注释方式:// 单行注释(Ctrl+/ )/* 段落注释(Ctrl+shift+/ )*/ JavaScript基础JavaScript:基于浏览器 .基于(面向)对象.事件驱动.脚本语言JavaScript的作用:表单验证,减轻服务的压力,添加页面动画效果,动态更改页面内容,Ajax网络请求(Ajax:可以实现页面局部刷新)JavaScript组成部分:ECMAScript(5.1/6).DOM.BOMECMA

Javascript基础篇小结

Javascript基础篇小结 字数9973 阅读3975 评论7 喜欢28 转载请声明出处 博客原文 随手翻阅以前的学习笔记,顺便整理一下放在这里,方便自己复习,也希望你有也有帮助吧 第一课时 入门基础 知识点: 操作系统就是个应用程序 只要是应用程序都要占用物理内存 浏览器本身也是一个应用程序 浏览器本身只懂得解析HTML 调用浏览器这个应用程序的一个功能绘制 1.javascript介绍 JavaScript操作DOM的本质是=获取+触发+改变 目的:就是用来操作内存中的DOM节点 修改D

javascript基础——初识javascript

每一门语言的学习都是从HelloWorld开始的,我今天也遵循这个原则吧!先上一段代码,认识一下javascript <html><head><title>初识javascript</title><script language="javascript" type="text/javascript"><!--alert("Hello World Wide Web!")//-->

JavaScript基础细讲

JavaScript基础细讲 JavaScript语言的前身叫作Livescript.自从Sun公司推出著名的Java语言之后,Netscape公司引进了Sun公司有关Java的程序概念,将自己原有的Livescript 重新进行设计,并改名为JavaScript. JavaScript是一种基于对象和事件驱动并具有安全性能的脚本语言,有了JavaScript,可使网页变得生动.使用它的目的是与HTML超文本标识语言.Java 脚本语言一起实现在一个网页中链接多个对象,与网络客户交互作用,从而可

JavaScript基础--内部类(九)

js的内部类javascript 中本身提供一些,可以直接使用的类,这种类就是内部类,主要有:ObjectArrayMathBooleanStringRegExpDateNumber 1.内部类分类从使用的方式看:分为动态类和静态类(1) 动态类 使用 var对象 = new 动态类() 对象属性|方法 var newdate = new Date(); //显示当前日期 window.alert(newdate.toLocaleString()); (2) 静态类 使用 类名.属性|方法比如:

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

如果以后公司再能让我独立做一套新的完整系统,那么我肯定会为这个系统再写一个前端框架,那么我到底该如何写这个框架呢? 在我以前的博客里我给大家展示了一个我自己写的框架,由于当时时间很紧张,做之前几乎没有完整的思考过我到底该如何去写这个框架,所以事后对于这个框架我有很多遗憾之处,当我重构过一次代码后我就没再做过任何重构操作的工作,因为我根本不想再去给它修修补补了,之所以有这个想法,就是我对我写的那个框架的基础架构不满意. 为什么不满意这个基础架构了?我们先来看看我当时封装框架的方式: (functi

前端之JavaScript基础

前端之JavaScript基础 本节内容 JS概述 JS基础语法 JS循环控制 ECMA对象 BOM对象 DOM对象 1. JS概述 1.1. javascript历史 1992年Nombas开发出C-minus-minus(C-)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.(客户端执行的语言) Netscape(网景)接收Nombas的理念,(Brendan Eich)在其Netscape Navigator 2.0产品中开发出一套livescript的脚本