요약:
최근 프로젝트에서 사진 미리보기 기능을 작업하고 있는데 이때 사용자들은 보기 인터페이스를 초과하는 큰 사진을 업로드하게 됩니다. 마지막으로 너비와 높이가 고정된 위치를 만들기로 결정했으며 사용자는 이미지를 드래그하여 볼 수 있습니다. 그래서 ie5+, 크롬, 파이어폭스, 오페라 등의 브라우저용 드래그 가능한 DOM 요소를 지원하는 플러그인을 작성했습니다.
이 기능을 구현하는 데 필요한 지식은 많지 않습니다.
1. js의 element.style.left
style.left가 반환한 변수는 문자열이고 변수는 변수입니다
js의element.offsetLeft
offsetLeft는 불변 변수인 int 유형을 반환합니다. 즉, 이 변수를 변경해도 레이아웃에 영향을 미치지 않습니다.
2. js의 event.clientX
clientX 이벤트 속성은 이벤트가 트리거될 때 브라우저 페이지(또는 클라이언트 영역)에 대한 마우스 포인터의 수평 좌표를 반환합니다.
3. js의 element.className
스타일을 바꾸는 클래스 방식
위 세 가지 사항은 모두 비교적 친숙한 지식입니다. 제가 말씀드리고 싶은 내용은 다음과 같습니다.
4. js에 개체에 대한 이벤트 모니터링 추가
element.addEventListener("event","fun","boolen");
이벤트: 이벤트를 나타냅니다
fun: 이벤트가 발생한 후 실행되는 함수를 말합니다
프로젝트 주소: https://github.com/baixuexiyang/drag
예:
var drag = new Drag("test", { onStart: function(){ }, onMove: function(){ document.getElementById('position').innerHTML = '距离左边:' + drag.getPositions().left + ';距离顶部:' + drag.getPositions().top; }, onStop: function(){ } });
다른 예에서 발생한 문제를 살펴보겠습니다. 저는 이 문제를 오랫동안 해결하려고 노력했지만 여전히 좋은 해결책을 찾지 못했습니다.
예제를 살펴보겠습니다. (테스트의 편의를 위해 코드를 파일로 작성했습니다.)
드래그.html
<!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> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/> <title>鼠标拖拽</title> <style type="text/css"> <!-- #dragdiv{ background-color:#0A0909; height:200px; width:157px; position:absolute; } .ondrag{ filter:alpha(opacity=200); cursor:move; } .enddrag{ filter:alpha(opacity=100); cursor:default; } #father{ width:600px; height:700px; background:#C63535; } --> </style> </head> <body> <div id="father"> <div id="dragdiv"></div> </div> <script language="JavaScript"> var dragdiv=document.getElementById("dragdiv"); var father=document.getElementById("father"); var offsetx=0; var offsety=0; var draging=false; function beforeDrag(ev){ if (!draging) { draging = true; var l = dragdiv.offsetLeft; var t = dragdiv.offsetTop; offsetx = ev.clientX - l; offsety = ev.clientY - t; } else { dragdiv.className = "enddrag"; dragdiv.removeEventListener("mousemove",onDrag); draging = false; return; } } function endDrag(){ draging=false; dragdiv.className="enddrag"; } function onDrag(ev){ if (!draging) { dragdiv.className = "enddrag"; return; } else { dragdiv.className = "ondrag"; dragdiv.style.left = (ev.clientX - offsetx) + "px"; dragdiv.style.top = (ev.clientY - offsety) + "px"; } } dragdiv.addEventListener("mousedown",beforeDrag,true); dragdiv.addEventListener("mousemove",onDrag,false); dragdiv.addEventListener("mouseup",endDrag,true); </script> </body> </html>
코드는 매우 간단하므로 조금만 주의를 기울여 읽으면 이해할 수 있습니다
첫 번째 드래그가 성공했습니다. 마우스를 누른 채 드래그하세요. 두 번째에도 정상적으로 작동하게 하려면 다른 곳(즉, 드래그가 안되는 부분)을 마우스로 클릭해야 합니다
위 마우스 이벤트
"mousedown"은 마우스를 눌렀을 때 이 이벤트가 트리거됨을 의미합니다(위에서 beforeDrag 함수가 트리거됨)
"mousemove"는 마우스가 움직일 때 이 이벤트가 트리거됨을 의미합니다(위에서 onDrag 함수가 트리거됨)
"mouseup"은 마우스를 눌렀다가 놓을 때 이 이벤트가 트리거됨을 의미합니다. (위에서 endDrag 함수가 실행됩니다)
ps: 온라인에서 확인한 마우스 시간은 "onmousedown"입니다. 작성자가 "onmousedown"을 테스트했는데 이벤트 응답은 없었지만 "mousedowm"은 정상이었습니다
위에 언급된 문제에 대해 addEventListener의 순서 문제와 세 번째 매개변수 true/false의 이벤트 흐름 문제를 고려하여 많은 실험을 시도했지만 여전히 완벽한 해결책을 찾지 못했습니다
"mouseup" 이벤트가 두 번째로 모니터링에 실패하여 포커스를 다시 얻는 것은 정상입니다(다른 곳에서 마우스를 클릭하면 됩니다)