zoukankan      html  css  js  c++  java
  • Javascript 之 事件

    事件流(描述的是从页面中接受事件的顺序)

    1、IE 的事件冒泡流:即事件最开始由最具体的元素(文档中嵌套层次最深的那个点)接收,然后逐级向上传播至最不具体的那个节点(文档)。

    2、Netscape 的事件捕获流:与 IE 的冒泡流截然相反,由不太具体的节点应该更早接收到事件,而最具体的节点最后接收到事件。

    事件处理程序

    1、HTML 事件处理程序,缺点: HTML 和 JS 代码紧密的耦合在一起了,修改时须多处修改,不方便

    <button onclick="alert('Hello world!')">点击我</button>

    =============================== 或者 ============================

    <button onclick="hello();">点击我</button>
    function hello () {
      alert("Hello world!");
    }

    2、DOM0 级事件处理程序,是一个比较传统的方式:把一个函数赋值给一个事件的处理程序属性,是用的比较多的方法。优点:简单、跨浏览器

    <button id="btn">点击我</button>
    var btn = document.getElementById("btn");
    btn.onclick = function () {
      alert("Hello world!");
    }

    ====================== 或者 ======================

    btn.onclick = hello();
    function hello () {
      alert("Hello world!");
    }

    btn.onclick = null;  // 取消元素绑定的 click 事件

    3、DOM2 级事件处理程序。

       addEventListener 是添加事件绑定, removeEventListener 是取消事件绑定。

      都接收三个参数:要处理的事件名、作为事件处理程序的函数、布尔值(true 表示在捕获阶段调用事件处理程序, false 表示在冒泡阶段端用事件处理程序,默认为 fasle)

    <button id="btn">点击我</button>

    var btn = document.getElementById("btn");
    btn.addEventListener("click", function(){
      alert("Hello world!");
    }, false)

    ====================== 或者 ==========================

    btn.addEventListener("click", hello, false);
    function hello () {
      alert("Hello world!");
    }

    btn.removeEventListener("click", hello, false);  // 删除元素的事件绑定。
    注意:通过什么方式添加的事件,就要通过什么方式删除事件

    4、IE 事件处理程序。添加事件处理程序是 attachEvent(),删除事件处理程序是 detachEvent,接收两个相同的参数:事件处理程序的名称、事件处理程序的函数

      与 addEventListener 相比,没有第三个参数,因为 IE8 以及更早的浏览器版本只支持事件冒泡流

    <button id="btn">点击我</button>

    var btn = document.getElementById("btn");
    btn.attachEvent("onclick", function () {  // 在 IE 下的事件需要加前缀 on
      alert("Hello world!");
    })

    ================== 或者 =================
    btn.attachEvent("onclick", hello);
    function hello () {
      alert("Hello world");
    }

    btn.detachEvent("onclick", hello);   // 删除事件绑定程序

    5、跨浏览器的事件处理程序,能力测试

    var eventUtil = {
      // 添加事件
      addEvent: function (ele, type, fn) {  // ele:元素  type:事件类型名称  fn:事件处理程序函数
        if (ele.addEventListener) {  // 判断浏览器时候支持 addEventListener   
          ele.addEventListener(type, fn, false);
        } else if (ele.attachEvent) {  // 判断浏览器是否支持 IE 的 attachEvent
          ele.attachEvent(type, fn);
        } else {  // 通用的 DOM0 级方法
          ele["on" + type] = fn;
        }
      },
      // 删除事件
      removEvent: function (ele, type, false) {
        if (ele.removeEventListener) {
          ele.removeEventListener(type, fn, false);
        } else if (ele.detachEvent) {
          ele.detachEvent(type, fn);
        } else {
          ele["on" + type] = null;
        }    
      },
      // 获取 event
      getEvent: function (event) {
        return event?event:window.event;
      },
      // 获取事件目标元素
      getEventElement: function (event) {
        return event.target || event.srcElement;
      },
      // 阻止事件默认行为
      preventDefault: function (event) {
        if (event.preventDefault) {
          event.preventDefault();
        } else {
          event.returnValue = false;
        }
      },
      // 阻止事件冒泡
      stopPropagation: function (event) {
        if (event.stopPropagation) {
          event.stopPropation();
        } else {
          event.cancelBubble = true;
        }
      }
    }

    <button id="btn"></button>
    var btn = document.getElementById("btn");
    // 添加
    event.addEvent(btn, "click", function () {
      alert("Hello world!");
    });
    // 删除
    event.removeEvent(btn, "click", function () {
      alert("Hello world!");
    })

    ==================== 或者 ======================
    event.addEvent(btn, "click", hello);
    event.removeEvent(btn, "click", hello);
    function hello () {
      alert("Hello world")!
    }

    用例:
    <a href="www.baidu.com" id="link"></a>
    var link = document.getElementById("link");
    eventUtil.addEvent(link, "click", funciton (e) {
      e = eventUtil.getEvent(e);  // 获取 event 对象
      alert(eventUtil.getEventElement(e).nodeName);  // 获取事件目标元素
      eventUtil.preventDefault(e);  // 阻止事件默认行为
      eventUtil.stopPropagation(e);  // 阻止事件冒泡
    })

    事件对象(在触发 DOM 上的事件时都会产生一个对象,叫 event 对象)

    1、DOM 中的事件对象

    event.type  // 事件类型
    event.target  // 事件目标
    event.target.nodeName  // 事件目标的节点名称
    event.target.nodeType  // 事件目标的节点类型
    event.target.selectedIndex  // 事件目标 select 标签选中的索引值,也就是选中了哪一个 option 标签
    event.keyCode  // 此属性用于得到键盘对应的键码值
    event.stopPropagation()  // 这个方法用于阻止事件冒泡
    event.preventDefault()  // 这个方法用于阻止事件的默认行为

    2、IE 中的事件对象

    event.type  // 事件类型
    event.srcElement  // 事件目标
    event.cancelBubble  // 阻止事件冒泡 event.cancelBubble = true; 取消阻止事件冒泡 event.cancelBubble = false;
    event.returnValue  // 阻止事件的默认行为,默认值是 true 表示不阻止事件的默认行为, event.returnValue = false 可以设置阻止事件的默认行为


    IE8 或者更低的浏览器
    function ev (evetn) {
      event = event || window.event;
      var targetD = event.target || event.srcElement;
    }

     事件类型

    鼠标事件都是在浏览器窗口中的特定位置上发生的,这个位置信息保存在事件的 clientX 和 clientY 属性中,所有浏览器都支持这两个属性,它们的值表示事件发生时鼠标指针在视口中的水平和垂直坐标,不包括页面滚动的距离

    event.clientX  // 鼠标指针在视口中的水平位置
    event.clientY  // 鼠标指针在视口中的垂直位置
    mousedown  // 在用户按下鼠标任意键时触发
    mousemove  // 当鼠标指针在元素内部移动时重复地触发
    mouseup  // 当用户释放鼠标按钮时触发
    keydown  // 当用户按下键盘上的任意键时触发,而且如果按住不放的话,会重复触发此事件
    keypress  // 当用户按下键盘上的字符键时触发,而且如果按住不放的发,会重复触发此事件
    keyup  // 当用户释放键盘上的任意键时触发

    element.offsetLeft  // 元素距离视口左边的距离
    element.offsetTop  // 元素距离视口上边的距离
    document.documentElement.clientWidth || document.body.clientWidth  // 窗口的宽度
    document.documentElement.clientHeight || document.body.clientHeight  // 窗口的高度

    取消默认行为

    <a href="http://www.baidu.com" id="link">百度</a>
    var link = document.getElementById('link');
    link.addEventListener('click', function (e) {
      e.preventDefault();  // 取消 a 链接的默认跳转
      console.log('clicked!');
    })

    阻止事件冒泡

    <div id="dom">
      <a id="link" href="http://www.baidu.com">激活</a>
      <a href="http://www.qq.com">取消</a>
    </div>
    var link = document.getElementById('link');
    link.addEventListener('click', function (e) {
      e.preventDefault();
      e.stopPropagation();  // 阻止内层 a 的事件冒泡到父元素 div 上
      alert('激活');
    })
    var dom = document.getElementById('dom');
    dom.addEventListener('click', function (e) {
      var target = e.target;
      e.preventDefault();
      if (target.nodeName === 'A') {
        alert('取消');
      }
    })

    事件代理

    <div id="dom">
      <a href="http://www.baidu.com">百度</a>
      <a href="http://www.qq.com">腾讯</a>
    </div>
    var dom = document.getElementById('dom');
    dom.addEventListener('click', function (e) {
      e.preventDefault();
      var target = e.target;  // 代理的重点,在获取 e.target 对象
      if (target.nodeName === 'A') {
        alert(target.innerHTML);
      }
    })

    代理的好处: 1、代码简介; 2、减少浏览器内存占用
    具体应用: 对于一个无限下拉加载图片的页面,如何给每个图片绑定事件,就是使用事件代理。给父元素绑定事件,通过冒泡机制,获取点击目标的 nodeName 是否是 img,再执行相应的函数

    通用事件绑定

    <div id="dom">
      <a id="link" href="http://www.baidu.com">百度</a>
      <a href="http://www.baidu.com">百度</a>
    </div>
    var dom = document.getElementById('dom');
    bindEvent(dom, 'click', 'a', function (e) {
      e.preventDefault();
      console.log(this.innerHTML);
    })
    var link = document.getElementById('link');
    bindEvent(link, 'click', function (e) {
      e.preventDefault();
      e.stopPropagation();
      console.log(this.innerHTML);
    })

    function bindEvent (elem, type, selector, fn) {
      if (fn == null) {
        fn = selector;
        selector = null;
      }
      elem.addEventListener(type, function (e) {
        var target;
        if (selector) {
          // 使用代理
          target = e.target;
          if (target.matches(selector)) {  // 在点击目标的元素中,是否存在 selector 选择器,有返回true,无返回false
            fn.call(target, e);  // 用 call 方法调用,把 target 当 this
          }
        } else {
          // 不使用代理
          fn(e);
        }
      })
    }

    var result = element.matches(selectorString);  // selectorString 是一个 css 选择器字符串
  • 相关阅读:
    if else配对问题
    未完
    c,c++,java格式总结
    c++笔记
    Vaadin
    J2msi 自己制作的把exe打成安装包简易GUI程序(第二版 带DLL注册)
    scala手动编译运行
    jframe去掉窗体
    jdk1.7
    vbox共享文件 挂载
  • 原文地址:https://www.cnblogs.com/joffe/p/7675228.html
Copyright © 2011-2022 走看看