>웹 프론트엔드 >JS 튜토리얼 >자바스크립트 드래그 앤 드롭 프로토타입의 문제점(코드를 한 줄씩 분석하여 드래그 앤 드롭의 원리를 쉽게 이해할 수 있음)_javascript 기술

자바스크립트 드래그 앤 드롭 프로토타입의 문제점(코드를 한 줄씩 분석하여 드래그 앤 드롭의 원리를 쉽게 이해할 수 있음)_javascript 기술

WBOY
WBOY원래의
2016-05-16 16:18:191091검색

오늘은 마지막 드래그 프로토타입의 몇 가지 문제를 해결해 보겠습니다. 아래의 문제점은 무엇입니까?

모두가 문제를 확인할 수 있도록 이전 호의 Javascript 코드를 첨부했습니다.

<script type="text/javascript">
   window.onload = function() {
    var oDiv = document.getElementById("div1");
    var disX = 0;
    var disY = 0;
    oDiv.onmousedown = function(ev) {
     var oEvent = ev || event; 
     disX = oEvent.clientX - oDiv.offsetLeft; 
     disY = oEvent.clientY - oDiv.offsetTop;

     oDiv.onmousemove = function(ev) {
      var oEvent = ev || event;
      oDiv.style.left = oEvent.clientX - disX+'px'; 
      oDiv.style.top = oEvent.clientY - disY+'px';
     };
     oDiv.onmouseup = function() {
      oDiv.onmousemove = null;
      oDiv.onmouseup = null;
     };

    };

   };
  </script>

1. 현재 드래그 중에 마우스를 더 빠르게 움직이면 마우스가 div에서 나오고 이때 div는 마우스를 따라가지 않습니다.

그럼 이런 문제는 왜 발생하는 걸까요?

이유는 실제로 매우 간단합니다. div에 mousemove 이벤트를 추가하면 마우스가 div를 벗어나면 이때는 더 이상 mousemove가 실행되지 않습니다.

해결책: 이벤트가 문서에 로드됩니다. 무슨 일이 있어도 마우스가 여전히 페이지에 있기 때문에 무슨 일이 있어도 mousemove가 실행될 것입니다. 이렇게 하면 문제 없이 빠르게 이동할 수 있습니다.

그런 다음 그에 따라 코드를 수정합니다.

<script type="text/javascript">
   window.onload = function() {
    var oDiv = document.getElementById("div1");
    var disX = 0;
    var disY = 0;
    oDiv.onmousedown = function(ev) {
     var oEvent = ev || event; 
     disX = oEvent.clientX - oDiv.offsetLeft; 
     disY = oEvent.clientY - oDiv.offsetTop;
    // 事件加载document 上
     document.onmousemove = function(ev) {
      var oEvent = ev || event;
      oDiv.style.left = oEvent.clientX - disX+'px';
      oDiv.style.top = oEvent.clientY - disY+'px';
     };
     oDiv.onmouseup = function() {
      document.onmousemove = null;
      oDiv.onmouseup = null; 
     };

    };

   };
  </script>

그러면 이 문제는 해결될 수 있습니다.

2. 이제 문제가 있는지 살펴보겠습니다. 빠르게 드래그하는 문제는 해결되었지만 마우스를 이 위치로 이동하면

이제 div에 마우스가 없는 것을 확실히 볼 수 있습니다. 이때 마우스를 떼면 다시 돌아온 후에도 계속 움직이는 것을 볼 수 있습니다. 이것은 또 다른 버그입니다!

사실 이 문제도 위와 똑같습니다. 그래서 해결책은 매우 간단합니다. 문서에 mouseup을 추가해 보겠습니다.

document.onmouseup = function() { 
      document.onmousemove = null; 
      document.onmouseup = null; 
     };

이렇게 해서 지금 막 위치로 이동하면 이전 버그는 나오지 않고 빠르게 이동하면 문제가 없을 것입니다. 모든 것이 정상입니다.

3. 브라우저 호환성 문제를 살펴보겠습니다

실제로 Firefox 하위 버전에서는 이런 문제가 있습니다
. 처음 드래그하면 어떻게 나타나는지 맞네요. 한 번 드래그한 후 누르고 있으면 뒤에 이런 그림자가 생기는 것을 알 수 있습니다. 무슨 일이야?

사실 우리가 드래그하고 있는 것은 빈 div입니다. Firefox에는 버그가 있으므로 div에 콘텐츠를 추가하면 어떻게 될까요?

이제 다시는 문제가 없다는 것을 알게 될 것입니다.

따라서 Firefox 버그는 빈 div에만 나타납니다.

해결책:

실제로는 매우 간단합니다. onmousedown에서 브라우저 기본 이벤트가 false를 반환하는 것을 방지하면 됩니다. onmousedown에 추가하는 이유는 무엇입니까?

마우스를 눌렀을 때 드래그가 시작되는 이벤트가 무엇인지 생각해 볼 수 있죠. 따라서 onmousedown에 로드해야 합니다.

사실 저는 Firefox 버그를 차단하기 위해 return false를 추가했습니다.

아무리 드래그해도 문제가 없습니다.

첨부된 코드는 다음과 같습니다.

<script type="text/javascript">
   window.onload = function() {
    var oDiv = document.getElementById("div1");
    var disX = 0;
    var disY = 0;
    oDiv.onmousedown = function(ev) {
     var oEvent = ev || event;
     disX = oEvent.clientX - oDiv.offsetLeft;
     disY = oEvent.clientY - oDiv.offsetTop;
     // 事件加载document 上
     document.onmousemove = function(ev) {
      var oEvent = ev || event;
      oDiv.style.left = oEvent.clientX - disX+'px';
      oDiv.style.top = oEvent.clientY - disY+'px';
     };
     document.onmouseup = function() {
      document.onmousemove = null;
      document.onmouseup = null;
     };

     return false;

    };

   };
  </script>

이제 프로그램은 완성되었지만 사용자 경험에는 여전히 몇 가지 문제가 있습니다.

예를 들어 사용자가 이 div를 브라우저 밖으로 드래그할 수 있는데 어떻게 해결해야 할까요?

그럼 판단을 추가해보겠습니다. 왼쪽으로 나가면 아주 간단해요

그러면 0과 정확히 같으며 왼쪽에서 나갈 수 없습니다. 그러면 위의 내용도 마찬가지입니다.

그럼 오른쪽으로 나가지 못하는 상황을 방지하려면 어떻게 해야 할까요? ? 그림을 그리면 명확해질 것입니다. 실제로 페이지의 보이는 너비에서 div의 너비를 빼면 이를 계산할 수 있습니다.

이것이 소위 최대값입니다. 이동 거리가 이 최대값을 초과하면 이 최대값과 같게 됩니다. 그러면 아래도 마찬가지다.

전체 코드는 첨부되어 있습니다:

<script type="text/javascript">
       // 拖拽空div 低版本的火狐有bug
      window.onload = function() {
        var oDiv = document.getElementById("div1");var disX = 0;
        var disY = 0;
        oDiv.onmousedown = function(ev) {
          var oEvent = ev || event;
          disX = oEvent.clientX - oDiv.offsetLeft;
          disY = oEvent.clientY - oDiv.offsetTop;

          document.onmousemove = function(ev) {
            var oEvent = ev || event;
            // 存储div当前的位置
            var oDivLeft = oEvent.clientX - disX;
            var oDivTop = oEvent.clientY - disY;


            // 从左边拖出去了
            if (oDivLeft < 0) {
              oDivLeft = 0;
            } else if (oDivLeft > document.documentElement.clientWidth - oDiv.offsetWidth) {
              oDivLeft = document.documentElement.clientWidth - oDiv.offsetWidth;
            }

            if (oDivTop < 0) {
              oDivTop = 0;
            } else if (oDivTop > document.documentElement.clientHeight - oDiv.offsetHeight) {
              oDivTop = document.documentElement.clientHeight - oDiv.offsetHeight;
            }

            oDiv.style.left = oDivLeft + 'px';
            oDiv.style.top = oDivTop + 'px';
          };

          document.onmouseup = function() {
            document.onmousemove = null;
            document.onmouseup = null;
          };
          return false; // 阻止默认事件,解决火狐的bug
        };
      };
    </script>

이제 드래그 앤 드롭이 비교적 완료되었습니다. 오(∩_∩)오

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.