focusin与focusout

这两个事件是IE的私有实现,能冒泡,它代表获得焦点或失去焦点的事件。现在只有Firefox不支持focusin,focusout事件。其实另外两个事件focus和blur是用来实现获取焦点和失去焦点的事件,但是由于这两个事件不能冒泡,所以很多浏览器就使用focusin,focusout来代替它,但是火狐不支持这两个事件,所以暂时还不能使用focusin,focusout事件代替focus和blur事件。

那么兼容性写法是怎么样的呢?如下:

if (document.addEventListener) {   //如果是W3C的方式,就用捕获的机制(从父元素到目标元素),来实现冒泡的机制(从目标元素到父元素),这样父元素就能获得目标元素的focus和blur事件了
  el.addEventListener('focus', focusHandler, true);   
  el.addEventListener('blur', blurHandler, true);
} else {
  el.onfocusin = focusHandler;   //IE不支持捕获阶段,但是支持focusin和focusout这两个事件,这两个事件本身就是冒泡的。因此父元素能获得目标元素的focus和blur事件
  el.onfocusout = blurHandler;
}

当然另外一种写法是:

if("onfocusin" in form){

  addEvent(form,"focusin",focusHandler,false);   //第一个参数为绑定的元素,第二个是事件类型,第三个是事件处理函数,第四个是是否捕获阶段,false代表冒泡。

  addEvent(form,"focusout",blurHandler,false);

}

else{

  addEvent(form,"focus",focusHandler,true);   //第一个参数为绑定的元素,第二个是事件类型,第三个是事件处理函数,第四个是是否捕获阶段,true代表捕获。

  addEvent(form,"blur",blurHandler,true);

}

submit事件

在IE6-8下,submit不会冒泡到顶层,它只执行form元素的submit回调,冒泡到form元素,就提交跳转。submit事件跟鼠标事件和键盘事件不一样,它是一种复合事件,既可以通过鼠标事件实现,也可以通过键盘事件实现。

如果我们通过鼠标或者键盘来触发submit事件:在IE9+以及其他标准浏览器会触发form元素以及祖先元素一直到window的submit事件,才会跳转。IE8-,只触发到form元素的submit事件就跳转了。它们都不会触发form元素之内的元素绑定的submit事件的回调方法,因此submit事件的回调方法只能放在form元素中。

怎么来解决这个兼容性问题呢:

我们对submit事件进行处理,如果触发submit事件时,使用的是事件代理,那么就在代理元素上绑定两个事件,click,keypress。如果是键盘事件,根据keyCode是否为13(键盘事件keypress,当keyCode=13时,就代表用户按了enter按键,就代表用户正在触发submit事件,提交数据。这里的enter按键需要是在input元素中触发才行,IE下type=file的input也可以。),如果是点击事件,根据input元素的type属性值是否是submit,image(鼠标click事件,当点击的input是submit或image类型时,就代表用户正在触发submit事件,提交数据)。是的话,就手动模拟冒泡(因为submit事件在IE6-8下只能冒泡到form元素,因此手动模拟)。把submit事件一直模拟冒泡到window对象(这时代理元素就能触发submit事件了)。

如果最后都没有阻止默认行为,就通过el.submit()方法提交数据,进行跳转。el.submit()方法,不会执行submit回调的(也就是说执行el.submit方法会提交数据,进行跳转,但是不会执行submit的事件处理函数),而其他的click,blur,focus这样的DOM方法会同时执行回调和默认行为的。

reset事件跟submit事件一样,解决办法也一样,只是keyCode值不一样或者type的属性值不一样而已。

oninput事件

在做搜索框的智能提示,微博发布区@好友出现列表等功能时,我们需要监听输入框内部的变化。如果使用change事件,只能等失去焦点时才会触发回调,如果使用keydown,keypress,keyup,这几个键盘事件来监听,就监听不了右键的复制,剪贴,粘贴这些操作,这时我们就需要oninput事件了。

oninput事件是W3C提出来的,IE9才支持,但IE9对回退键,粘贴复制操作的监听也失灵,解决办法,用onkeydown解决回退键,oncut和onpaste解决粘贴复制操作(也可以通过onselectionchange事件来解决)。IE6-8下通过onpropertychange事件监听元素一切属性与特性的变化,因此可以通过它模拟oninput事件(事件对象的propertyName属性获取当前变动的属性名)。

兼容写法如下:

if(window.addEventListener){    //IE9+,以及其他标准浏览器

  element.addEventListener("input",callback);

}

else{

  element.attachEvent("onpropertychange",function(e){   //如果是IE6-8,input元素上的任何属性有变化就会触发

    if(e.propertyName === "value"){    //如果是value属性有变化,就会触发回调

      callback();

    }

  })

}

if(IE9){   //解决IE9下,input事件对回退,粘贴复制操作的失灵

  var selectionchange = function(e){

    if(e.type === "focus"){

      document.addEventListener("selectionchange",callback);

    }else{

      document.removeEventListener("selectionchange",callback);

    }

  }

  element.addEventListener("focus",selectionchange);   //input获得焦点就绑定document的selectionchange事件,因此在input中的任何操作都会冒泡到document中

  element.addEventListener("blur",selectionchange);   //input失去焦点,就移除这个绑定事件

}

跟事件相关的操作已经全部讲完了,如果想做兼容性的操作,还是有点复杂的,大家认真看吧。

下面的课程将会讲到异步处理,敬请期待。

加油!

第二十八课:focusin与focusout,submit,oninput事件的修复的更多相关文章

  1. NeHe OpenGL教程 第二十八课:贝塞尔曲面

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  2. Python学习第二十八课——Django(templates)

    templates 讲后台得到的数据渲染到页面上:话不多说,先看具体代码. urls: from django.conf.urls import url from django.contrib imp ...

  3. Python学习第二十八课——Django(urls)

    Django框架中的urls配置: 首先通过pycharm创建一个Django项目: 例如要写blog的功能:则在digango_lesson中的urls代码如下: """ ...

  4. 潭州课堂25班:Ph201805201 django 项目 第二十八课 新闻elasticsearch搜索前后功台能实现 (课堂笔记)

    后端功能实现 文件,类,字段,命名不要改动, 在apps/news/search_indexes.py中创建如下类:(名称固定为search_indexes.py) # -*-# -*- coding ...

  5. python第二十八课——编码小常识

    2.内存和硬盘: 内存:计算机硬件组成部分之一,它是一个容器,用来存储数据:处理数据速度快, 存储数据量小:断电死机数据会丢失,短暂性存储数据 硬盘:计算机硬件组成部分之一,它是一个容器,用来存储数据 ...

  6. Spring入门第二十八课

    事务的传播行为 当事务方法被另一个事务方法调用时,必须指定事务应该如何传播,例如:方法可能继续在现有事务中运行,也可能开启一个新的事务,并在自己的事务中运行. 事务的传播行为可以由传播属性指定.Spr ...

  7. NeHe OpenGL教程 第三十八课:资源文件

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  8. NeHe OpenGL教程 第十八课:二次几何体

    转自[翻译]NeHe OpenGL 教程 前言 声明,此 NeHe OpenGL教程系列文章由51博客yarin翻译(2010-08-19),本博客为转载并稍加整理与修改.对NeHe的OpenGL管线 ...

  9. centos LAMP第二部分apache配置 下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转 配置apache的访问日志 配置静态文件缓存 配置防盗链 访问控制 apache rewrite 配置开机启动apache tcpdump 第二十节课

    centos    LAMP第二部分apache配置  下载discuz!配置第一个虚拟主机 安装Discuz! 用户认证 配置域名跳转  配置apache的访问日志  配置静态文件缓存  配置防盗链 ...

随机推荐

  1. 用Qemu模拟vexpress-a9 (三)--- 实现用u-boot引导Linux内核

    环境介绍 Win7 64 + Vmware 11 + ubuntu14.04 32 u-boot 版本:u-boot-2015-04 Linux kernel版本:linux-3.16.y busyb ...

  2. Openwrt LuCI模块练习详细步骤

    前言 又到了成胖子^_^每周一博的时间了.最近在学习openwrt luci方面的知识,为了贯穿整个知识体系,练习题目为: 通过页面配置周期性地往/tmp/addtest文件写入内容和时间戳 1.在w ...

  3. redis unwatch discard

    UNWATCH UNWATCH 取消 WATCH 命令对所有 key 的监视. 如果在执行 WATCH 命令之后, EXEC 命令或 DISCARD 命令先被执行了的话,那么就不需要再执行UNWATC ...

  4. [译]OpenStack Object Storage Monitoring

    注:翻译的不完整,主要是有些地方翻译后反而妨碍理解,有些不知道怎么翻,anyway,需要时拿来用用也是可行的,顺便共享啦.欢迎提意见. 一个OpenStack Object Storage(OSOS) ...

  5. 【Android 基础】Android中全屏或者取消标题栏

    先介绍去掉标题栏的方法: 第一种:也一般入门的时候经常使用的一种方法 requestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏 注意这句一定要写在se ...

  6. 安装StarUML 及使用时序图(Sequence Diagram)和用例图(use case diagram)

    时序图 用例图

  7. View (三) 视图绘制流程完全解析

    相 信每个Android程序员都知道,我们每天的开发工作当中都在不停地跟View打交道,Android中的任何一个布局.任何一个控件其实都是直接或间 接继承自View的,如TextView.Butto ...

  8. KVM虚拟机CPU说明

    废话不多说了,下面对kvm虚拟机的CPU说明做一梳理:NUMA技术介绍NUMA是一种解决多CPU共同工作的技术方案,我们先回顾下多CPU共同工作的技术架构历史.多CPU共同工作主要有三种架构,分别是S ...

  9. Eclipse发布地址不同引发的问题

    eclipse发布到workspace metadata时,进不去http://localhost:8888页面.但是,它可以启动JAZZ和“公司的一个工程”. 而 eclipse发布到tomcat ...

  10. vuejs过滤器

    结合管道符 | {{messageOne | capitalize}} capitalize 首字母大写 {{messageOne | uppercase}} uppercase 大写字母 {{mes ...