美文网首页
关于DOM整理

关于DOM整理

作者: squidbrother | 来源:发表于2021-06-08 18:49 被阅读0次
  1. canvas的刮刮卡
  • 奖品图是canvas的背景图,
  • 绘制一个纯色Mark
  • 通过ctx.globalCompositeOperation="destination-out"设置合成规则,
  • 再对canvas绑定鼠标事件,绘制线段,完成
  1. 事件绑定 解绑 IE8以下需要使用element["on" + type] = handler形式
//添加事件
function addHandler(element,type,handler) {
    var isIE8 = !+"\v1";
    if(element.addEventListener){
        //检测是否为DOM2级方法
        element.addEventListener(type,handler,{ passive: false });
    }else if(element.attachEvent){
        //检测是否为IE级方法
        if(!isIE8){
            //--IE9+
            element.attachEvent("on" + type, function () {
                //通过call或者apply解决IE下this指向问题
                handler.apply(element);
            });
        }else{
            //--IE8↓
            element["on" + type] = handler;
        };
    }else {
        //检测是否为DOM0级方法
        element["on" + type] = handler;
    }
}
//移除事件
function removeHandler(element,type,handler){
    var isIE8 = !+"\v1";
    if(element.removeEventListener){
        element.removeEventListener(type,handler,{ passive: false });
    }else if(element.detachEvent){
        if(!isIE8){
            //--IE9+
            element.detachEvent("on" + type, function () {
                handler.apply(element);
            });
        }else{
            //--IE8↓
            element["on" + type] = null;
        };
    }else {
        element["on" + type] = null;
    }
}
  1. 阻止浏览器事件相关
  • 阻止事件冒泡
//js方式阻止冒泡 -- 兼容
if(ev.stopPropagation){
    ev.stopPropagation();
}else{
    ev.cancelBubble=true;
};

MDN提示说明:
弃用event.cancelBubble,推荐使用event.stopPropagation()
IE8及以下使用 event.cancelBubble (主流浏览器也支持),但官方说明其已弃用这个非标准的写法,并在某个时间停止支持
IE9+ 以及主流浏览器 使用stopPropagation

  • 阻止默认行为
//js方式阻止默认行为 -- 兼容
if(typeof ev.cancelable !== 'boolean' || ev.cancelable){
    ev.preventDefault();
}else{
    return false;
};

MDN提示说明:
event.preventDefault阻止默认行为,需要浏览器IE9+
return false; 即阻止默认行为,也阻止冒泡行为; 支持IE3+

  1. 元素鼠标滚动 -- isIEFn 与 IEVersion 参照 BOM整理
// 滚动函数
function scrollFn(scrolltype){
    if(scrolltype=='down'){
        //放大+
    }else{
        //缩小-
    };
}

//IE 版本号不为-1
if(isIEFn() && IEVersion()!=-1){
    // console.log('IE!!!!!!!')
    //IE -- 正数:向上滚动,负数:向下滚动
    obj.onmousewheel = function(ev){
        var oEv = ev || window.event;
        
        //滚动方向
        if(oEv.wheelDelta>0){
            scrollTypeStr = 'up';
        }else if(oEv.wheelDelta<0){
            scrollTypeStr = 'down';
        };
        scrollFn && scrollFn(scrollTypeStr);
        
        //阻止冒泡
        oEv.cancelBubble && (ev.cancelBubble = true);
        oEv.stopPropagation && oEv.stopPropagation();
        oEv.preventDefault && oEv.preventDefault();
    };
}else{
    // Webkit 和 IE一定支持"mousewheel" :低版本firefox
    var support = document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll";
        //主流浏览器 DOMMouseScroll -- 正数:向下滚动,负数:向上滚动

        if( support == "DOMMouseScroll" ) {
          // console.log('支持DOMMouseScroll的firefox');
          obj.addEventListener('DOMMouseScroll',function(ev){
        var oEv = ev || window.event;

        //滚动方向
        if(oEv.detail>0){
            scrollTypeStr = 'down';
        }else if(oEv.detail<0){
            scrollTypeStr = 'up';
        };
        scrollFn && scrollFn(scrollTypeStr);
        
        //阻止冒泡
        oEv.cancelBubble && (ev.cancelBubble = true);
        oEv.stopPropagation && oEv.stopPropagation();
        oEv.preventDefault && oEv.preventDefault();
        },false);
        }else if(support=='mousewheel'){
             // console.log('支持mousewheel的chrome');
             obj.onmousewheel = function(ev){
        var oEv = ev || window.event;
        
        //滚动方向
        if(oEv.wheelDelta>0){
            scrollTypeStr = 'up';
        }else if(oEv.wheelDelta<0){
            scrollTypeStr = 'down';
        };
        scrollFn && scrollFn(scrollTypeStr);
        
        //阻止冒泡
        oEv.cancelBubble && (ev.cancelBubble = true);
        oEv.stopPropagation && oEv.stopPropagation();
        oEv.preventDefault && oEv.preventDefault();
        };
        };          
};
  • 注:
    Microsoft Edge 会支持window.addEventListener,所以还是需要用浏览器信息来判断终端


    DOMMouseScroll 浏览器兼容性
  • 补充: MDN关于鼠标滚轮的判断

// detect available wheel event
support = "onwheel" in document.createElement("div") ? "wheel" : // 各个厂商的高版本浏览器都支持"wheel"
              document.onmousewheel !== undefined ? "mousewheel" : // Webkit 和 IE一定支持"mousewheel"
              "DOMMouseScroll"; // 低版本firefox

4-2. 弃用mousewheel与DOMMouseScroll,使用最新的wheel

function zoom(event) {
  event.preventDefault();
  scale += event.deltaY * -0.01;
  // Restrict scale
  scale = Math.min(Math.max(.125, scale), 4);
  // Apply scale transform
  el.style.transform = 'scale('+scale+')';
  el.innerHTML = 'scale('+scale+')';
}
let scale = 1;
const el = document.querySelector('div');
el.onwheel = zoom;
  1. 选择器
    IE8部分支持,IE9+全面支持
  • document.querySelector 匹配指定CSS选择器的一个元素
  • document.querySelectorAll 匹配指定CSS选择器的所有元素
  1. 关于拖拽的两种实现方式书写
  • 方式1 一般书写,针对同一个DOM元素坐标反复计算
function addDrag(obj){
    obj.onmousedown = function(ev){
        var oEv = ev || window.event;
        var disX = oEv.clientX - obj.offsetLeft;
        var disY = oEv.clientY - obj.offsetTop;
        document.onmousemove = function(ev){
            var oEv = ev || window.event;
            var movedX = oEv.clientX - disX;
            var movedY = oEv.clientY - disY;
            obj.style.left = movedX + 'px';
            obj.style.top = movedY + 'px';
        };
        document.onmouseup = function(ev){
            document.onmousemove = null;
            document.onmouseup = null;
        };
        return false;
    }
};
  • 方式2 通用样式(坐标,角度)书写,针对要修改的样式,设置一个DOM元素初始值,之后修改不断更新这个初始值
function addDrag(obj){
    var movedX = obj.offsetLeft;
    var movedY = obj.offsetTop;
    obj.onmousedown = function(ev){
        var oEv = ev || window.event;
        var disX = oEv.clientX - movedX;
        var disY = oEv.clientY - movedY;
        document.onmousemove = function(ev){
            var oEv = ev || window.event;
            movedX = oEv.clientX - disX;
            movedY = oEv.clientY - disY;
            obj.style.left = movedX + 'px';
            obj.style.top = movedY + 'px';
        };
        document.onmouseup = function(ev){
            document.onmousemove = null;
            document.onmouseup = null;
        };
        return false;
    }
};
  • 针对某个元素进行3D拖拽,就是使用上面方式2
function can3Dsee(obj){
        //针对修改样式的初始值,可以从DOM元素获取,如果修改left,top,那么初始值就是offsetLeft,offsetTop
    var rotateX = 0,rotateY = 0;
    document.onmousedown = function(ev){
        var oEv = ev || window.event;
        var disX = oEv.clientX - rotateX;
        var disY = oEv.clientY - rotateY;
        document.onmousemove = function(ev){
            var oEv = ev || window.event;
            rotateX = oEv.clientX - disX;
            rotateY = oEv.clientY - disY;
            obj.style.WebkitTransform = 'perspective(800px) rotateX('+(-rotateY)+'deg) rotateY('+rotateX+'deg)';
            obj.style.MozTransform = 'perspective(800px) rotateX('+(-rotateY)+'deg) rotateY('+rotateX+'deg)';
            obj.style.transform = 'perspective(800px) rotateX('+(-rotateY)+'deg) rotateY('+rotateX+'deg)';
        }
        document.onmouseup = function(){
            document.onmousemove = null;
            document.onmouseup = null;
        }
        return false;   
    }       
}

6-2. 关于项目中多图片拖拽的一些问题总结

  • 移动端多个元素同时拖动,创建一个透明层阻止元素干扰,只允许一个元素为拖动状态,且创建一个全局z-index变量用于累积层级,使得新拖拽的元素永远是最新的
  • 移动端时候,通过手指数量,来判断是拖拽还是旋转(放大缩小)
  • 移动端一根手指操作DOM元素时候,如何判断拖拽还是跳转,可以通过点击与移动时两个触碰点的时间间隔,以及两次触碰点的距离,可以有理由相信,只有两个触碰点足够近且两次点击时间间隔足够短,才认定为跳转行为,而非拖拽
  • 关于常规布局中,DOM元素脱离文档流,不影响文档流排版变化的问题:
    可以对每一个拖拽元素,做一个父子嵌套层级,父级用于文档流排版,子元素用于脱离文档流的拖拽使用;
    至于如何脱离文档流,获取元素距离屏幕left,top(包括滚动条)值,再对象设置position:absolute以及left,top赋值
  • 关于多个拖拽元素重置坐标点的问题,拖拽后给DOM元素一个属性,作为修改坐标点标记,另外每个元素脱离文档流时候,记录一下坐标信息,用于定位
  1. 通过JS创建3D圆柱以及圆锥
/*创建一个3D容器
* obj 目标容器
* option - 面数,面高度,面宽度,X轴旋转角度,XYZ三边偏移量
* hasTexture - 面上是否有背景
* imgSrc - 背景图地址
*/
function makeWall(obj,option,hasTexture,imgSrc){
    var faceLth = option.faceLth;  //1 - 面数 
    var faceW = 0;                 //2 - 面宽度
    var faceH = option.faceH || 0; //3 - 面高度
    // x轴旋转角度
    var rotateX = option.rotateX;
    //[x、y、z]三房向位移
    var translateX = option.translateX || 0;
    var translateY = option.translateY || 0;
    var translateZ = option.translateZ || 0;
    
    var degNum = 360/faceLth;
    for(var i=0; i<faceLth; i++){
        var oDiv = document.createElement('div');
        oDiv.className = 'faceBg';
        /*
        Math.cos(x) 
        这两个函数中的X 都是指的"弧度"而非"角度",弧度的计算公式为: 2*Math.PI/360*角度;
        */
        faceW = 2*translateZ*Math.tan((2*Math.PI/360*degNum)/2);
        oDiv.style.width = faceW + 'px';
        oDiv.style.height = faceH + 'px';       
        
        oDiv.style.WebkitTransform = 'translateX('+translateX+'px) translateY('+translateY+'px) rotateY('+(i*degNum)+'deg) translateZ('+translateZ+'px)  rotateX('+rotateX+'deg)';
        oDiv.style.MozTransform = 'translateX('+translateX+'px) translateY('+translateY+'px) rotateY('+(i*degNum)+'deg) translateZ('+translateZ+'px)  rotateX('+rotateX+'deg)';
        oDiv.style.transform = 'translateX('+translateX+'px) translateY('+translateY+'px) rotateY('+(i*degNum)+'deg) translateZ('+translateZ+'px)  rotateX('+rotateX+'deg)';
        //是否包裹材质背景
        if(hasTexture){
            oDiv.style.backgroundImg = imgSrc;
            oDiv.style.backgroundRepeat = 'no-repeat';
            oDiv.style.backgroundPosition = -i*faceW+'px 0px';
        }
        obj.appendChild(oDiv);
    }
}
//创建一个圆柱侧面 - (面数越多,侧面越光滑)
makeWall(oBox,{'faceLth':50,'faceH':80,'rotateX':0,'translateX':0,'translateY':0,'translateZ':28})
//创建一个圆坠侧面 - (面数越多,越像圆锥)
makeWall(oBox,{'faceLth':50,'faceH':80,'rotateX':45,'translateX':0,'translateY':0,'translateZ':28})
圆柱
伪圆锥.jpg

依次类推,做一个火箭


火箭
  1. IE9以下不支持input表单placeholder
    引用jquery插件 jquery.placeholder.js;
//是否支持placeholder
function placeholderSupport() {
    return 'placeholder' in document.createElement('input');
};

//IE9↓ 不支持placeholder
var searchInput = $('#searchInput');
if(!placeholderSupport()){
    // console.log('不支持placeholder');
    searchInput.placeholder && searchInput.placeholder();
};

未完待续....

相关文章

  • 关于DOM整理

    canvas的刮刮卡 奖品图是canvas的背景图, 绘制一个纯色Mark 通过ctx.globalComposi...

  • 关于DOM的知识整理(2)----DOM扩展

    这个部分主要总结一下对DOM的两个主要的扩展SelectorAPI和HTML5 选择符API querySelec...

  • DOM整理

    DHTML的功能 //DHTML不是新语言,DNTML=HTML+css+JavaScript 动态改变页面元素...

  • 【JavaScript笔记】JavaScript基础_Dom(1

    这里整理了DOM相关内容。 1.DOM DOM, 全称 Document Object Model 文档 对象 模...

  • 关于DOM和事件的几个整理

    DOM的发展历史 Document Object Model的历史可以追溯至1990年代后期微软与Netscape...

  • DOM:API整理

    Node. document节点 Element对象 属性的操作 Text节点和DocumentFragment节...

  • DOM整理2

    文档中的元素都是Element类型的对象 Element类型的对象,通过原型继承自Node.prototype。 ...

  • DOM整理-3

    增加、删除和替换节点 创建元素 document.createElement('元素名'); var table ...

  • DOM知识整理

    1、DOM结构——两个节点之间可能存在哪些关系以及如何在节点之间任意移动。 document.documentEl...

  • DOM事件的工作原理

    导读:本文是teren对DOM事件知识点所做的进一步整理,整理资料主要参考DOM事件简介和饥人谷课件,如果对DOM...

网友评论

      本文标题:关于DOM整理

      本文链接:https://www.haomeiwen.com/subject/njjfzktx.html