• 事件(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

  • 相关阅读:
    BZOJ 1191 HNOI2006 超级英雄hero
    BZOJ 2442 Usaco2011 Open 修建草坪
    BZOJ 1812 IOI 2005 riv
    OJ 1159 holiday
    BZOJ 1491 NOI 2007 社交网络
    NOIP2014 D1 T3
    BZOJ 2423 HAOI 2010 最长公共子序列
    LCA模板
    NOIP 2015 D1T2信息传递
    数据结构
  • 原文地址:https://www.cnblogs.com/TiestoRay/p/2735711.html
Copyright © 2020-2023  润新知