• JavaScript权威指南--事件处理


    知识要点

    客户端JavaScript程序采用了异步事件驱动变成模型(13.3.2节)。这种风格并不只应用于web编程,所有使用图形用户界面的应用程序都采用它,它们静待某些事件发生,然后响应。

    事件就是web浏览器通知应用程序发生什么事情。它不是JavaScript对象,不会出现在程序源代码中。当然,有些事件相关的对象会出现在源代码中。

    事件类型是一个用来说明发生什么类型事件的字符串。由于只是个字符串,所以也可以叫事件名字。

    事件目标是发生的事件或与之相关的对象。事件必须同时致命类型和目标。例如window上的load事件或<button>元素的click事件。在客户端JavaScript中,Window、Document和Element对象是最常见的事件目标。有些事件是由其他类型的对象触发,例如18章的由XHR对象触发的readystatechange事件。

    事件处理程序或事件监听程序是处理或响应事件的函数。

    事件对象是与特定事件相关且包含有关该事件详细信息的对象事件对象作为参数传递给事件处理程序函数(IE8及以前版本不一样)。所有事件对象都有用来指定事件类型的type属性和指定事件目标的target属性(IE8前的srcElement)。每个事件类型都为其相关事件对象定义一组属性,例如鼠标事件有指针坐标,很多只有type和target,没有更详细的属性。

    事件传播是浏览器决定哪个对象触发其事件处理程序的过程。对于单个对象的特定事件(比如Window对象的load事件),必须是不能传播的。当文档元素发生在某个类型的事件时,会发生冒泡,还有事件捕获(IE8及以前不支持,所以少用)。

    事件处理程序可以通过返回一个适当的值、调用事件对象的某个方法或设置对象的某个属性来阻止默认操作的发生。比如超链接的click事件可以阻止加载新页面。

    1.事件类型

    1.1.传统事件类型

    表单事件

    通过事件处理程序能取消submit和reset事件的默认操作,某些click事件也是如此。focus和blur事件不会冒泡,但其他所有表单事件都可以。ie定义了focusin和focusout事件可以冒泡,它们可以用于替代focus和blur事件。

    无论用户何时输入文字(通过键盘或剪切和粘贴)到textarea和其他文本输入表单元素,除ie外的浏览器都会触发input事件。不像change事件,每次文字插入都会触发input事件,遗憾的是,input事件的事件对象没有指定输入文字的内容(textinput事件将会成为这个事件的有用替代方案。)

    Window事件

    Window是指事件的发生与浏览器本身而非窗口中显示的任何特定文档内容相关,但是,这些事件中有一些会和文档元素上发生的事件同名。

    window对象的onerror属性有点像事件处理程序,当javascript出错时会触发他。但是,它不是真正的事件处理程序,因为它能用不同的参数来调用(14.6节)。

    像<img>元素这样的单个文档元素也能为load和error事件注册处理程序。当外部资源(例如图片)完全加载或发生阻止加载的错误时就会触发它们。某些浏览器也支持也支持abort事件,当图片(或其他网络资源)因为用户停止加载进程而导致失败就会触发它.

    鼠标事件

    传递给鼠标事件处理的事件对象有属性集,它们描述了当事件发生时鼠标的位置和按键状态,也指明了当时是否有任何辅助键按下。clientX和clientY属性指定了鼠标在窗口坐标中的位置,button和which属性指定了按下的鼠标键是哪个。当键盘辅助键按下时,对应的属性altkey、ctrlKey、metaKey和shiftKey会设置为true。而对于click事件,detail属性指定了其是单击、双击还是三击。

    键盘事件

    无论任何文档元素获得键盘焦点都会触发键盘事件,并且他们会冒泡到Document和window对象。如果没有元素获得焦点,可以直接在文档上触发事件。传递给键盘事件处理程序的事件对象有keyCode字段。它指定按下或释放的键是哪个,除了keyCode,键盘事件对象也有altKey,ctrlKey、metaKey和shiftKey,描述键盘辅助建的状态。

    1.2.DOM事件

    新DOM标准通过在事件对象中加入新的key和char属性来简化keydown、keyup和keypress事件,这些属性都是字符串。

    1.3.HTML5事件

    离线web应用还定义了大量其他事件来通知应用:

    2.注册事件处理程序

    有两种基本方式:第一种,给事件目标对象或文档元素设置属性。第二种方式,是将事件处理程序传递给对象或元素的一个方法,每种技术都有两个版本。可以在javascript代码中设置事件处理程序为对象属性,或对于文档元素,可以在html中直接设置相应属性。对于通过方法调用的处理程序注册,有一个标准方法,命名为addEventListener,除IE8及以前版本之外,所有浏览器都支持这个方式,而ie9之前的IE版本支持的是一个叫attachEvent的不同方法。

    2.2.设置HTML标签属性为事件处理程序

    某些事件类型通常直接在浏览器而非任何特定文档元素上触发。在javascipt中,这些事件处理程序在window对象上注册。在html中,会把他们放在body标签上,但浏览器会在window对象上注册它们

    在指定一串JavaScript代码作为HTML事件处理程序属性的值时,浏览器会把代码串转换为类似如下的函数中:

    function(event){
      with(document){
        with(this.form || {}){
          with(this){
            /*这里是编码*/
          }
        }
      }
    }

    3.事件处理程序的调用

    3.1.事件处理程序的参数 

    通常调用事件处理程序时把事件对象作为他们的一个参数(有一个例外)。事件对象的属性提供了有关事件的详细信息,例如,type属性指定了发生的类型。在IE8及以前版本中,通过设置属性注册处理程序,当调用它们时并未传递事件对象,取而代之,需要通过全局对象window.event来获得事件对象

    function handler(event){
    var event=event||window.event;
    }

    向使用attachEvent注册的事件处理程序传递事件对象,但它们也能使用window.event。

    17.2.2节,当通过设置HTML属性注册事件处理程序时,浏览器会把javascript编码转换到一个函数中。非IE浏览器使用event参数来构造函数,而IE在构造函数时没有有要求参数。如果在这样的函数中使用event标识符,那么引用的正是Window.event.在这两种情况下,HTML事件处理程序都能作为event引用事件对象。

    3.2.事件处理程序的运行环境

    当使用addEventListener注册时,调用的处理程序使用事件目标作为它们的this值。但是,对于attachEvent来讲这是不对的:使用attachEvent注册的处理程序作为函数调用,它们的this值是全局对象(window)。可以用如下代码来解决这个问题:

    /*
    *在指定的事件目标上注册用于处理指定类型事件的指定处理程序函数
    *确保处理程序一直作为事件目标的方法调用
    */
    function addEvent(target,type,handler){
      if(target.addEventListener){
     target.addEventListener(type,handler,fasle);
      }
      else{
        target.attachEvent("on"+type,function(event){
          return handler.call(target,event);
          //把处理程序作为事件目标的方法调用,传递事件对象
        })   
      }
    }

    注意使用这个方法注册的事件处理程序不能删除,因为传递给attchEvent的包装函数没有保留下来传递给detachEvent。

    3.3.事件处理程序的作用域 

    它们在其定义时的作用域而非调用时的作用域中执行,并且它们能存取那个作用域中的任何一个本地变量。但是通过HTML属性来注册事件处理程序是一个例外,它们被转换为能存取全局变量的顶级函数而非任何本地变量。但是由于历史原因,它们运行在一个修改后的作用域链中,通过HTML属性定义的事件处理程序能好像本地变量一样使用目标对象,容器<form>对象(如果有)和Document对象的属性。

    HTML属性最不自然的地方包括冗长的代码串和修改会的作用域链允许有用的快捷方式,可以使用tagName替代this.tagName,使用getElementById()替代document.getElementById()。并且,对于<form>中的文档元素,能通过ID引用任何其他的表单元素,例如zicode替代this.form.zipcode。

    另一方面,HTML事件处理程序中修改的作用域链是陷阱之源,因为作用域链中每个对象的属性在全局对象中都有相同名字的属性。例如Document对象定义(很少使用)open()方法,因此HTML事件处理程序想调用Window对象的open方法就必须显示地调用window.open而不是open。表单有类似的问题但破坏性更大,因为表达元素的名字和ID在包含的表单元素上定义属性。例如表单包含一个ID是“location”的元素,那么要是表单的所有HTML事件处理程序想引用window的location对象,就必须使用window.location而不能是location。

    3.4.事件处理程序的返回值

    通过设置对象属性或HTML属性注册事件处理程序的返回值有时是非常有意义的。

    3.7.事件取消

    function cancelHandle(event){
      var event = event || window.event;//用于IE
      /*处理事件的代码*/
      //取消默认行为
      if(event.preventDefault)event.preventDefault();
      if(event.returnValue)event.returnValue = false;
      return false;  //用于处理使用对象属性注册的处理程序
    }

    5.鼠标事件

    7.拖放事件 

    http://www.w3school.com.cn/html5/html_5_draganddrop.asp

  • 相关阅读:
    navicat常用快捷键与SQL基本使用
    【Excel实战】公式应用:如何按照某种类型数量排序
    Typora+Markdown便捷发布blog
    【Vulnhub】DC-2靶机
    【转载】阮一峰网络日志中的JWT入门
    【动态规划】闫氏dp分析
    Markdown Latex数学公式
    【每日一题】两个数组的交集
    【每日一题】前k个高频元素
    HashMap的各种遍历和删除方式总结
  • 原文地址:https://www.cnblogs.com/Chen-XiaoJun/p/6676041.html
Copyright © 2020-2023  润新知