18-8-1

Posted fzz9

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了18-8-1相关的知识,希望对你有一定的参考价值。

一、鼠标拖拽元素相关

  首先鼠标拖拽事件是由几个事件组成的,比如:鼠标右键按住某个元素进行拖动,释放鼠标时拖拽事件结束。这其中就需要三个事件来加以控制:

  • 鼠标右键:其实就是鼠标按下事件mousedown,然后我们根据event.button属性来判断是按下了左键(0)、中箭(1)还是右键(2)。
  • 鼠标移动:就是mousemove事件
  • 鼠标释放:即鼠标抬起事件mouseup

  明确需要处理的事件之后我们要明确我们需要在事件中做些什么,拖拽元素移动就是改变元素的“坐标”,这里修改坐标的方式有很多种,不同的元素有不同的处理方法,但是本质都是使用js来进行操作。

  所以我们需要在事件触发时记录需要变动的值,比如鼠标右键时当前元素的坐标值(js读即可),鼠标拖拽时其实是鼠标按下+鼠标移动两个事件同时触发,所以我们需要一个状态符来记录是否按下鼠标(在mousedown中设为true),然后当按下状态ture时再执行鼠标移动事件,鼠标移动时我们需要同时让元素移动,有不同的处理方法,但一点我们必须要读取当前鼠标的坐标,同样有好多种,之前我使用的是event.clientX和event.clientY属性,但发现效果并不好,换成offsetX和offsetY之后拖拽变得更为准确。记住,别忘了鼠标抬起事件,鼠标抬起时我们让按下状态符设为false,以及其他调整的属性“恢复原样”,这样当鼠标抬起时就不会再触发拖拽效果。

  另外,使用event.preventDefault()方法可以阻止事件的初始默认行为。

  比如,在浏览器中单击右键后会出现菜单栏,这中浏览器默认行为我们并不需要,我们就可以使用preventDefault()方法来阻止默认事件的触发,但我们需要知道右键菜单是哪个事件触发的,虽然很像mousedown+mouseup组合,但并不是,其实是contextmenu事件。

  实例

  • <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head runat="server">
    <meta charset="utf-8">
    <title></title>
    <script type="text/javascript">
    var mouseX, mouseY;
    var objX, objY;
    var isDowm = false; //是否按下鼠标
    function mouseDown(obj, e) {
        obj.style.cursor = "move";//手势
        objX = div1.style.left;//div距离
        objY = div1.style.top;
        mouseX = e.clientX;//鼠标坐标
        mouseY = e.clientY;
        isDowm = true;
    }
    function mouseMove(e) {
        var div = document.getElementById("div1");
        var x = e.clientX;//鼠标位置
        var y = e.clientY;
        if (isDowm) {
            div.style.left = parseInt(objX) + parseInt(x) - parseInt(mouseX) + "px";
            div.style.top = parseInt(objY) + parseInt(y) - parseInt(mouseY) + "px";
            document.getElementById("span1").innerHTML = "x:" + div.style.top + " " + "y:" + div.style.left;
        }
    }
    function mouseUp(e) {
        if (isDowm) {
            var x = e.clientX;
            var y = e.clientY;
            var div = document.getElementById("div1");
            div.style.left = (parseInt(x) - parseInt(mouseX) + parseInt(objX)) + "px";
            div.style.top = (parseInt(y) - parseInt(mouseY) + parseInt(objY)) + "px";
            document.getElementById("span2").innerHTML = "x:" + div.style.top + " " + "y:" + div.style.left;
            mouseX = x;
            rewmouseY = y;
            div1.style.cursor = "default";
            isDowm = false;
        }
    }
    function menu(event){
            event.preventDefault();
        }
    </script>
    </head>
    <body>
        <span id="span1"></span></br>
        <span id="span2"></span></br>
        <div id="div1" style="background-color: Green; border: 1px solid red; height: 300px;
        top: 100px; left: 100px; width: 300px; position: absolute;" 
        onmousedown="mouseDown(this,event)"
        onmousemove="mouseMove(event)"
        onmouseup="mouseUp(event)"
        oncontextmenu="menu(event)">
        </div>
    </body>
    </html> 

二、鼠标坐标问题

  上面也说到鼠标坐标为题,有时候clientX并不如offsetX准确。一般获取鼠标坐标的属性有:

  • 相对于屏幕的screenX和screenY
  • 相对于浏览器窗口的clientX和clientY
  • 相对于事件源的offsetX和offsetY

  到这里应该明白了。

三、目前存在的问题

  • 正在做的测试:svgEditor
    技术分享图片
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8">
        <title>SVG编辑器</title>
        <style>
            body{
                overflow:-Scroll;
                overflow-y:hidden;
                overflow-x:hidden;
            }
            #toolbox {
                position: absolute;
                top: 0;
                bottom: 0;
                left: 0;
                width: 250px;
                border-right: 1px solid #CCC;
            }
            #toolbox h2 {
                margin: 0;
                padding: 0;
                background: #EEE;
                font-size: 16px;
                height: 24px;
                line-height: 24px;
                padding: 5px 10px;
            }
            #toolbox form {
                padding: 10px;
            }
            #canvas {
                position: absolute;
                left: 260px;
                top: 10px;
                bottom: 10px;
                right: 260px;
                border-radius: 5px;
            }
            label {
                display: inline-block;
                width: 80px;
                text-align: right;
            }
            #attrbox {
                position: absolute;
                top: 0;
                bottom: 0;
                right: 0;
                width: 250px;
                border-left: 1px solid #CCC;
            }
            #attrbox h2 {
                margin: 0;
                padding: 0;
                background: #EEE;
                font-size: 16px;
                height: 24px;
                line-height: 24px;
                padding: 5px 10px;
            }
            #attrbox form {
                padding: 10px;
            }
            .initShape{
                fill:#fff0;
                stroke:black;
                stroke-width:2px;
                opacity:1;
            }
            .selected{
                fill:#fff0;
                stroke:red;
                stroke-width:2px;
                opacity:1;
            }
        </style>
    </head>
    <body>
        <div id="toolbox">
            <h2>创建图形</h2>
            <form id="create-shape">
                <button type="button" create="rect">Rect</button>
                <button type="button" create="circle">Circle</button>
                <button type="button" create="ellipse">Ellipse</button>
                <button type="button" create="line">Line</button>
            </form>
        </div>
    
        <svg id="canvas" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0,0,900,3000">
            <defs>
                <!--网格-->
                <pattern id="grid" x="0" y="0" width="10" height="10" patternUnits="userSpaceOnUse">
                    <path d="m0,0h10v10" style="stroke: #0003;fill: none"></path>
                </pattern>
            </defs>
            <!--网格背景:之前设置了固定值,发现修改viewBox时不能及时自动刷新界面,改为百分比解决了这个问题.但是新的问题出现了就是拖动时无法自动将边界覆盖-->
            <rect id="canvas_background" fill="url(#grid)" width="100%" height="100%"></rect>
            <!--参考坐标-->
            <path d="M450,0V2000M0,330H2000" style="stroke: #5d595980;stroke-width:0.5px;" />
            <g id="drawing"></g>
        </svg>
    
        <div id="attrbox">
            <h2>属性列表</h2>
            <form id="shape-attrs">
                单击选中图形
            </form>
            <h2>外观和变换</h2>
            <form id="look-and-transform">
                <p>
                    <label style="display: inline;">填充</label>
                    <input id="fill" type="color" value="#f21e0e" />
                </p>
                <p>
                    <label style="display: inline;">描边</label>
                    <input id="stroke" type="color" value="#67a51a" />
                    <input id="strokeWidth" type="range" min="1" max="20" value="2" />
                </p>
                <p>
                    <label>translateX</label>
                    <input id="translateX" type="range" min="-400" max="400" value="0" />
    
                    <label>translateY</label>
                    <input id="translateY" type="range" min="-400" max="400" value="0" />
    
                    <label>rotate</label>
                    <input id="rotate" type="range" min="-180" max="180" value="0" />
    
                    <label>scale</label>
                    <input id="scale" type="range" min="-1" max="2" step="0.01" value="0.5" />
                </p>
            </form>
        </div>
        <script type="text/javascript">
            var canvasSVG = document.getElementById("canvas");
            var bg =document.getElementById("canvas_background");
            //鼠标滚动事件(only firefox)
            document.addEventListener(DOMMouseScroll,function(event){
                var viewboxValue = canvasSVG.getAttribute("viewBox").split(",");//[x,y,w,h]
                var viewbox_minx = parseInt(viewboxValue[0]);
                var viewbox_miny = parseInt(viewboxValue[1]);
                var viewbox_width = parseInt(viewboxValue[2]);
                var viewbox_height = parseInt(viewboxValue[3]);
                viewbox_width += event.detail*10;
                viewbox_height += event.detail*10;
                viewboxValue[0] = viewbox_minx;
                viewboxValue[1] = viewbox_miny;
                viewboxValue[2] = viewbox_width;
                viewboxValue[3] = viewbox_height;
                if(viewboxValue[2] < 50)
                    viewboxValue[2] = 50;
                if(viewboxValue[2] > 4000)
                    viewboxValue[2] = 4000;
                if(viewboxValue[3] < 2150)
                    viewboxValue[3] = 2150;
                if(viewboxValue[3] > 3310)
                    viewboxValue[3] = 3310;
                canvasSVG.setAttribute("viewBox",viewboxValue.join(","));
                event.preventDefault();
            });
            //鼠标按下事件:记录按下时的鼠标位置和按下状态,再记录需要改变的值
            var mousedownX = 0,mousedownY = 0;
            //var objectX,bojectY = 0;
            var isMouseDown = false;
            var viewboxValue = new Array(4);
            var viewbox_minx=0,viewbox_miny=0,viewbox_width=0,viewbox_height= 0
            bg.addEventListener("mousedown",function(event){
                if(event.button==2){
                    canvasSVG.style.cursor = "grabbing";//手势
                    isMouseDown = true;
                    mousedownX = event.offsetX;
                    mousedownY = event.offsetY;
                    viewboxValue = canvasSVG.getAttribute("viewBox").split(",");//[x,y,w,h]
                    viewbox_minx = parseInt(viewboxValue[0]);
                    viewbox_miny = parseInt(viewboxValue[1]);
                    viewbox_width = parseInt(viewboxValue[2]);
                    viewbox_height = parseInt(viewboxValue[3]);
                    event.preventDefault();
    
                    //鼠标移动事件:用移动时的坐标减去鼠标按下时的坐标便是位移坐标
                    var moveX=0,moveY = 0;
                    bg.addEventListener("mousemove",function(event){
                        if(isMouseDown){
                            mousemoveX = event.offsetX;
                            mousemoveY = event.offsetY;
                            moveX = mousemoveX - mousedownX;
                            moveY = mousemoveY - mousedownY;
                            viewbox_minx -= moveX;
                            viewbox_miny -= moveY;
                            viewboxValue[0] = viewbox_minx;
                            viewboxValue[1] = viewbox_miny;
    
                            canvasSVG.setAttribute("viewBox",viewboxValue.join(","));
                            event.preventDefault();
                            //鼠标抬起事件:一般是恢复之前的状态
                            bg.addEventListener("mouseup",function(event){
                                if(event.button==2){
                                    canvasSVG.style.cursor = "default";
                                    isMouseDown = false;
                                    event.preventDefault();
                                }
                           });
                            //鼠标右击事件:这里有一个问题,根据是否移动来决定是否组织右键默认行为
                            bg.addEventListener("contextmenu",function(event){
                                if(moveX==0&&moveY==0)
                                    return true;
                                else{
                                    event.preventDefault();
                                }
                            });
                        }
                    });
                }
           });
        </script>
        <script type="text/javascript">
            var createShape = document.getElementById("create-shape");
            var drawingGroup = document.getElementById("drawing");
            var SVG_NS = http://www.w3.org/2000/svg;
    
            createShape.addEventListener("click",function(event){
                if(event.target.textContent.length > 10) return false;
                var elementType = event.target.getAttribute("create");
                drawingGroup.appendChild(initShape(elementType));
            });
    
            function initShape(elementType){
                var shape = document.createElementNS(SVG_NS, elementType);
                if(elementType == "rect"){
                    shape.setAttribute("x",50);
                    shape.setAttribute("y",80);
                    shape.setAttribute("width","100px");
                    shape.setAttribute("height","100px");
                    shape.setAttribute("class","initShape");
                    return shape;
                }else if(elementType == "circle"){
                    shape.setAttribute("cx",100);
                    shape.setAttribute("cy",100);
                    shape.setAttribute("r","50px");
                    shape.setAttribute("class","initShape");
                    return shape;
                }else if(elementType == "ellipse"){
                    shape.setAttribute("cx",100);
                    shape.setAttribute("cy",100);
                    shape.setAttribute("rx","80px");
                    shape.setAttribute("ry","50px");
                    shape.setAttribute("class","initShape");
                    return shape;
                }else{
                    return null;
                }
    
            }
        </script>
        <script type="text/javascript">
            //var isSelected = false;//选中状态
            //图形单击事件
            drawingGroup.addEventListener("click",function(event){
                
    
            });
            //图形鼠标滑过事件
            drawingGroup.addEventListener("mouseover",function(event){
                event.target.setAttribute("class","selected");
            });
            //鼠标移开事件
            drawingGroup.addEventListener("mouseout",function(event){
                event.target.setAttribute("class","initShape");
            });
    
            //鼠标长按事件:变成可拖动手势并记录要改变的值,这里要改变x,y值或cx,cy
            drawingGroup.addEventListener("mousedown",function(event){
                var g_mousedownX = 0,g_mousedownY = 0;
                var g_elementX = 0,g_elementY = 0;
                var g_isMouseDown = false;
                if(event.button==0){
                    drawingGroup.style.cursor = "move";//手势
                    g_mousedownX = event.offsetX;
                    g_mousedownY = event.offsetY;
                    var xname = "x";
                    var yname = "y";
                    if(event.target.tagName != "rect"){
                        xname = "cx";
                        yname = "cy";
                    }
                    g_elementX = parseInt(event.target.getAttribute(xname));
                    g_elementY = parseInt(event.target.getAttribute(yname));
                    g_isMouseDown = true;
    
                    var g_moveX = 0,g_moveX=0;
                    event.target.addEventListener("mousemove",function(event){
                        if(g_isMouseDown&&drawingGroup.style.cursor == "move"){
                            var g_mousemoveX = event.offsetX;
                            var g_mousemoveY = event.offsetY;
                            g_moveX = g_mousemoveX-g_mousedownX;
                            g_moveY = g_mousemoveY-g_mousedownY;
                            
                            g_elementX += g_moveX;
                            g_elementY += g_moveY;
                            var xname = "x";
                            var yname = "y";
                            if(event.target.tagName != "rect"){
                                xname = "cx";
                                yname = "cy";
                            }
                            event.target.setAttribute(xname,parseInt(g_elementX));
                            event.target.setAttribute(yname,parseInt(g_elementY));
                            //鼠标抬起事件:恢复
                            canvasSVG.addEventListener("mouseup",function(event){
                                drawingGroup.style.cursor = "default";
                                g_isMouseDown = false;
                                g_moveX = 0;
                                g_moveX=0;
                                event.preventDefault();
                           });
                        }
                    });
                }
            });
    
            
        </script>
    </body>
    </html>
    View Code
  • 改变viewBox的minx和miny后页面“不平铺”。
    技术分享图片
  • 该代码在chrome不兼容。

以上是关于18-8-1的主要内容,如果未能解决你的问题,请参考以下文章

谷歌浏览器调试jsp 引入代码片段,如何调试代码片段中的js

片段和活动之间的核心区别是啥?哪些代码可以写成片段?

VSCode自定义代码片段——.vue文件的模板

VSCode自定义代码片段6——CSS选择器

VSCode自定义代码片段——声明函数

VSCode自定义代码片段8——声明函数