zoukankan      html  css  js  c++  java
  • 事件(Event)知识整理(二)

     事件流

    DOM同时支持两种事件模型:捕获型事件和冒泡型事件
    并且每当某一事件发生时,都会经过捕获阶段->处理阶段->冒泡阶段(有些浏览器不支持捕获)

    捕获阶段是由上层元素到下层元素的顺序依次。而冒泡阶段则正相反。

    如下图

    当事件触发时body会先得到有事件发生的信息,然后依次往下传递,直到到达最详细的元素。这就是事件捕获阶段。
    还记得事件注册方法ele.addEventListener(type,handler,flag)吧,Flag是一个Boolean值,true表示事件捕捉阶段执行,false表示事件冒泡阶段执行。
    接着就是事件冒泡阶段。从下往上 依次执行事件处理函数(当然前提是当前元素为该事件注册了事件句柄)。
    在这个过程中,可以阻止事件的冒泡,即停止向上的传递。
    阻止冒泡有时是很有必要的,例如

    <div onclick=funcA()>
        <button onclick=funcB()>Click</button>
    </div>

    本意是如果点击div中按钮以外的位置时执行funcA,点击button时执行funcB。但是实际点击button时就会先后执行funcB,funcA。
    而如果在button的事件句柄中阻止冒泡的话,div就不会执行事件句柄了。


     拖动事件

    ①相关拖动事件的触发时机 ☟☟
    dragstart:选择当前元素并开始拖动时
    drag:拖动当前元素并移动时
    dragend:结束对当前元素的拖动(可以是将拖动内容放到其他容器中,也可以是中断拖动)
    dragenter: 拖动元素进入当前元素时(区别于dragstart)
    dragover: 拖动元素在当前元素上移动时(区别于drag)
    dragleave: 拖动元素离开当前元素时(区别于dragover)
    drop:有拖动元素被扔进当前元素(当前元素必须是能接受拖动内容的元素,如input:text,textarea...)

    ②可拖动属性
    HTML5中 元素有一个属性draggable(IE10+)。true的时候是可以拖动。false则不可。
    图片和链接元素默认是true,其他则都为false。

    <img src="hello.png" draggable="false" />
    <div draggble="true">Can be dragged</div>

    如果拖动元素A(例如一张图片),当光标移动到一个不可放置的元素B(例如另一张图片)时
    光标会变成无法拖入的样式(圈圈里面加个反斜线),且不会发生drop事件。
    如果重写该元素的dragover和dragenter事件的话,可以改变这种情况。(改变了拖动时光标的样式,并且可以触发drop事件)

    var main = document.getElementById("main");
    main.ondragover = function() {
        event.returnValue = false;//取消默认行为
    }
    main.ondragenter = function() {
        event.returnValue = false;
    }

     ③dataTransfer对象

    在发生上述提及的这些拖动事件时,事件对象都会含有一个储存着拖动的数据的dataTransfer对象。(除此之外的事件是没有这个对象的,例如click,focus)
    dataTransfer对象有两个主要方法getData()和setData();
    显而易见,这分别是用来获取或设置拖动的数据的方法。但是使用过程中需要传入数据类型的参数。
    考虑兼容的话,数据类型目前有两种:"text","URL"。二者的区别只有当拖动内容到另一个浏览器窗口(或新建浏览器的Tab位置)时才会体现出来。
    "text"类型不会被特殊处理。"URL"类型则会被当成网页中的链接。
    dataTransfer对象的用处:根据需要,开发人员可以在dragstart时用setData()改变拖动数据,或者是在drop时,对getData()获得的数据进行校验。例子:

    <input type="text" id="studentID" size=5 maxLength=5/>
    <div id="tabA" schoolId="007"></div>
    <script>
        var stuId = document.getElementById("studentID");
        stuId.ondrop = function(e){
            e = e || window.event;
            var id = e.dataTransfer.getData("text");
            event.returnValue=!/\D/.test(id);
        }
        /***************************************/
        var tabA = document.querySelector("#tabA");
        tabA.ondragstart=function(){
            e = e || window.event;
            var sid=this.getAttribute("schoolId");
            e.dataTransfer.setData("text",+sid);
        }
    </script>

    dataTransfer还有两个决定拖动效果的属性:dropEffect,effectAllowed。


     用原生JS写的事件工具类

    var EventUtil = function() {
        return {
            //获得事件
            getEvent: function(e) {
                return e || window.event;
            }
            //获得事件源
            , getTarget: function(e) {
                return e.target || e.srcElement;
            }
            //添加事件监听
            , addEvent: function(elem, type, fn) {
                if (elem.attachEvent) {
                    elem.attachEvent('on' + type, fn);
                } else if (elem.addEventListener) {
                    elem.addEventListener(type, fn, false);
                }
            }
            //移除事件监听
            , removeEvent: function(elem, type, fn) {
                if (elem.detachEvent) {
                    elem.detachEvent('on' + type, fn);
                } else if (elem.removeEventListener) {
                    elem.removeEventListener(type, fn, false);
                }
            }
            //取消默认行为
            , preventDefault: function(e) {
                if (e.preventDefault) {
                    e.preventDefault();
                } else {
                    e.returnValue = false;
                }
            }
            //取消冒泡
            , stopPropagation: function(e) {
                if (e.stopPropagation) {
                    e.stopPropagation();
                } else {
                    e.cancelBubble = true;
                }
            }
        };
    }

    网页缩放触发resize的问题

    平常我们提起resize事件,会想起拖动浏览器边缘,或者点击最大最小化按钮。

    而实际上还有另一种情况,就是网页被缩放,无论是Ctrl + mousewheel 还是 通过浏览器的工具栏中的按钮。

    缩放的时候,body中其他元素的长宽值不会发生变化,但是页面文档的滚动高度,可视高度会变化(如缩小的时候,看到的内容变小,但是看到的内容量会变大)

    document.body.scrollHeight/document.activeElement.scrollHeight

    document.body.clientHeight

  • 相关阅读:
    利用 img 和 script 发送跨域请求
    tomcat 内存配置
    servlet request.getParamter 有时获取参数为null
    windows本地无法启动sqlserver服务
    mac用virtualbox 装win7联网及分辨率设置
    奇怪的transform bug
    mysql 同时执行多条update语句
    二进制树形算法
    协议栈中使用crc校验函数
    引用布局
  • 原文地址:https://www.cnblogs.com/TiestoRay/p/2735711.html
Copyright © 2011-2022 走看看