2016-08-24 1 views
0

mousedown 이벤트의 요소에 추가하는 mousemove 이벤트가 있습니다. 그런 다음 mouseup 이벤트에서 제거합니다. I는 상기 오프셋을 차감 해봤처음 클릭에 상대적으로 요소 끌기

dragImage(e) { 
    const width = this.getStyle(e.target, 'width').split('p')[0]; 
    const height = this.getStyle(e.target, 'height').split('p')[0]; 
    const X = e.pageX - (window.innerWidth/2 - window.innerHeight/2) || e.touches[0].clientX; 
    const Y = e.pageY || e.touches[0].clientY; 
    const stopTop = Y - (height/2) > 0; 
    const stopBottom = Y + (height/2) < this.getStyle(e.target.parentNode, 'height').split('p')[0]; 
    const stopLeft = X - (width/2) > 0; 
    const stopRight = X + (width/2) < this.getStyle(e.target.parentNode, 'width').split('p')[0]; 
    const stopTop = Y - (height/2) > 0; 
    const stopBottom = Y + (height/2) < this.getStyle(e.target.parentNode, 'height').split('p')[0]; 
    const stopLeft = X - (width/2) > 0; 
    const stopRight = X + (width/2) < this.getStyle(e.target.parentNode, 'width').split('p')[0]; 


    // check if element is within vertical bounds 
    if (stopTop) { 
     this.image.style.bottom = ''; 
     this.image.style.top = '0px'; 
    } else if (stopBottom) { 
     this.image.style.top = ''; 
     this.image.style.bottom = '0px'; 
    } else { 
     this.image.style.bottom = ''; 
     this.image.style.top = `${Y}px`; 
    } 

    // check if element is within horizontal bounds 
    if (stopLeft) { 
     this.image.style.right = ''; 
     this.image.style.left = '0px'; 
    } else if (stopRight) { 
     this.image.style.left = ''; 
     this.image.style.right = '0px'; 
    } else { 
     this.image.style.right = ''; 
     this.image.style.left = `${X}px`; 
    } 

    return false; 
} 

: mouseMove 및 이벤트

가 나는 영상을 가운데 폭과 X와 Y의 높이의 반을 감산하고있어,이 기능을 소성있어 요소가 pageXpageY이고 중간에 도착하지만 다른 X/Y 값이 모두 벗어나기 때문에 드래그되는 요소가 깜박이므로 값은 900, 500, 900, 500 등이 될 수 있습니다.

변화하는 가치를 일으키고 나는 일들을 지나치게 복제합니까? 내가하려는 것은 포인터를 중심으로 이미지를 드래그하고 경계 내에서 유지하는 것입니다.

감사합니다.

E - 설명을 위해 더 많은 코드를 추가 :이 이벤트를 추가하고 다음과 같은 기능을 제거

if (this.isMobile) { 
     this.image.addEventListener('touchstart', e => this.enableDrag(e)); 
     this.image.addEventListener('touchend', e => this.disableDrag(e)); 
     this.image.addEventListener('touchcancel',() => this.disableDrag()); 
     } else { 
     this.image.addEventListener('mousedown', e => this.enableDrag(e)); 
     this.image.addEventListener('mouseup', e => this.disableDrag(e)); 
     this.image.addEventListener('mouseleave',() => this.disableDrag()); 
     this.image.addEventListener('click', e => e.cancelBubble = true); 
     } 

, 수 : 내가 생성자에서 mousedown, mouseup에와하는 MouseLeave 이벤트의 첫 번째 세트를 추가

끌기 :

enableDrag(e) { 
     e = e || window.event; 
     e.cancelBubble = true; 
     e.preventDefault(); 

     if (this.isMobile) { 
     this.image.addEventListener('touchmove', this.dragEvent); 
     } else { 
     this.image.addEventListener('mousemove', this.dragEvent); 
     } 
    } 

disableDrag() { 
     if (this.isMobile) { 
     this.image.removeEventListener('touchmove', this.dragEvent); 
     } else { 
     this.image.removeEventListener('mousemove', this.dragEvent); 
     } 
    } 
+0

문제를 복제하기 위해 JSFiddle 다른 코드를 제공 할 수 있습니까? 데모를 보지 않고도 달성하려는 것을 시각화하는 것은 어렵습니다. – skyline3000

+0

@ skyline3000 그것은 상당히 큰 프로젝트의 일부이며 다른 많은 코드를 통합했습니다. 더 많은 코드를 포함하도록 내 대답을 편집하겠습니다. – JmJ

+0

드래그하면서 커서를 중심으로 이미지를 가운데에 놓으려고합니까? X가 계산에서 높이를 사용하는 이유는 무엇입니까? 그게 나에게 이상한 것처럼 보입니다. – syazdani

답변

1

이를 바탕으로 : "변화하는 값의 원인이 될 수 있고, 내가 일을과 복잡함을하고 어떻게 내가 할 노력하고 모든는 심상을 끌어입니다 GE는 포인터 주위를 중심으로하지 않고, 경계 내에서 유지 ", 나는 세 가지 제안을 할 것 :.

  1. 당신의 경계 조건이 너무 복잡 단지 topleft 속성을 설정하고 잊어 대한 bottomright
  2. 위의 내용을 기반으로, 사용자가 드래그를 시작한 위치에서 드래그를 오프셋하고 싶다고 생각합니다. 이 경우 mousedown 이벤트에서 계산 한 다음 여기에서 사용해야합니다.
  3. 나는 잠시 동안의 DOM을 조작 JS 코드를하지 않은,하지만 다시 하루에, getBoundingClientRect합니다 (DOM의 직선이 아닌 쿼리)
을 사용하는 DOM 객체의 위치/치수를 얻기의 선호하는 방법이었다 계정에이 촬영

, 당신과 같은 코드를 단순화 할 수 있습니다 :

dragImage(e) { 
    var imageBoundaries = this.image.getBoundingClientRect(); 
    var containerWidth = this.getStyle(e.target.parentNode, 'width').split('p')[0]; 
    var containerHeight = this.getStyle(e.target.parentNode, 'height').split('p')[0]; 

    const X = (e.pageX || e.touches[0].clientX) - offsetX; /* where offsetX is defined as where the user initially clicked on the image in the mousedown event */ 
    const Y = (e.pageY || e.touches[0].clientY) - offsetY; /* ditto */ 

    if X <= 0 { 
     // hit the left boundary 
     X = 0 
    } else if X + imageBoundaries.width >= containerWidth { 
     // hit the right boundary 
     X = containerWidth - imageBoundaries.width 
    } 

    if Y <= 0 { 
     // hit the top boundary 
     Y = 0 
    } else if Y + imageBoundaries.height >= containerHeight { 
     // hit the bottom boundary 
     Y = containerHeight - imageBoundaries.height 
    } 


    this.image.style.left = `${X}px`; 
    this.image.style.top = `${Y}px`; 

    return false; 
} 

이 윈도우의 경계에 이미지를 고정합니다 (당신은 항상 전체 이미지를 표시 할 가정). 이미지가 뷰포트에서 조금 움직이게하려는 경우 if 조건을 사용하여 조작 할 수 있습니다.

마지막으로 드래그 앤 드롭은 악명이 높아지기 쉽지 않으며 일반적으로 제 3 자에게이 기능을 제공합니다. Dragula과 같은 것은 내가 본 드래그 앤 드롭의 가장 일반적인 경우를 설정하는 신의 소리입니다. 물론, 이것이 학습을위한 것이라면, 자신의 롤 :

관련 문제