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>
- 改变viewBox的minx和miny后页面“不平铺”。
- 该代码在chrome不兼容。
以上是关于18-8-1的主要内容,如果未能解决你的问题,请参考以下文章