드래그 가능한 요소 요소 드래그 기능 구현 code_javascript 기술

WBOY
풀어 주다: 2016-05-16 18:08:58
원래의
1165명이 탐색했습니다.

물론, js 라이브러리의 소스 코드를 연구할 수도 있고, 휠을 직접 만들어서 시험해 볼 수도 있습니다. 그 과정은 꽤 흥미롭습니다... 다음으로, 페이지 요소의 드래그 앤 드롭 기능을 구현하겠습니다
이제 구현을 시작해 보겠습니다. 드래그 객체를 초기화하는 데 사용되는 메소드는 다음과 같습니다.
function DragObject(cfg)
객체를 사용하여 cfg를 전달합니다. 이는 Extjs

코드 복사 코드는 다음과 같습니다.

var dragObj = new DragObject({
el: 'exampleB ',
attachEl: 'exampleBHandle',
lowerBound: new Position(0, 0), //position은 x 속성이 있는 점을 나타냅니다. 및 y에 대해서는 아래에서 자세히 설명합니다
upperBound: new Position(500 , 500),
startCallback: ..., // 드래그할 때 트리거되는 콜백은 여기에서 생략됩니다.
moveCallback: ... , // 드래그하는 동안 발생하는 콜백
endCallback: .., // 드래그하는 동안 발생하는 콜백 종료
attachLater: ... // 드래그 이벤트 모니터링을 즉시 시작할지 여부
});
구성 매개변수의 el은 특정 요소의 ID가 직접 DOM 개체일 수도 있습니다. 예제에서는 요소를 드래그하여 끌 수 있습니다. 둘 다 Position 객체입니다. 이 객체의 캡슐화와 관련하여 아래 함수를 분석할 것입니다. 걱정하지 마세요. 입력이 없으면 startCallback, moveCallback에 제한이 없습니다. , endCallback 은 모두 콜백 함수이고, attachmentLater 는 true 또는 false 입니다. 잘 이해가 안 되시면 확인해 보세요. 다음 분석을 해보면 금방 이해되실 거라 생각합니다...
Position을 작성해 보겠습니다. 코드는 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.
function Position(x, y ) {
this.X = x;
thix.Y = y;
}
Position .prototype = {
생성자: 위치,
add: function(val) {
var newPos = new Position(this.X, this.Y);
if (val) {
newPos.X = val.X; }
return newPos; new Position(this.X, this.Y);
if (val) {
newPos.X -= val.>return newPos; : function(val) {
var newPos = new Position(this.X, this.Y);
if (val) {
newPos.X = this.X > X : this.X;
newPos.Y = this.Y > val.Y ? val.Y : this.Y 🎜>}
return newPos; (val) {
var newPos = new Position(this.X, this.Y);
if (val) {
newPos.X = this.X < val.X : this.X; newPos.Y = this.Y < val.Y ? val.Y : this.Y
return newPos;
return newPos; 🎜>bound : function(lower, upper) {
var newPos = this.max(lower);
return newPos.min(upper);
check : function() {
var newPos = new Position(this.X, this.Y);
if (isNaN(newPos.X))
newPos.X = 0
if (isNaN(newPos.Y))
newPos.Y = 0;
return newPos;
if(typeof el == 'string')
el = document.getElementById(el)
if(!el) return;
el.style.left = this.X 'px' ;
el.style.top = this.Y 'px'
}
}; 두 가지 값(x, y 좌표)을 저장하는 간단한 좌표점 패키지입니다. min 및 max 함수는 계산된 새 좌표점을 반환하기 위해 add 및 subtract 메소드를 통해 다른 좌표점에 대한 계산 및 연산을 수행할 수 있습니다. 이름에서 알 수 있듯이 다른 좌표점과 비교하여 더 작은 합계를 반환하는 데 사용됩니다. education.bound 메서드의 값은 제한된 범위 내의 좌표점을 반환하는 데 사용됩니다. x 및 y 속성은 숫자 유형이고, 그렇지 않으면 0으로 설정됩니다. 최종 적용 방법은 x 및 y 속성을 style.left 및 top 요소에 적용하는 것입니다. 그런 다음 나머지 코드를 대부분 꺼내서 살펴보았습니다. 비트 단위로:




코드 복사


코드는 다음과 같습니다.

함수 DragObject(cfg) {
var el = cfg.el,
attachEl = cfg.attachEl,
lowerBound = cfg.lowerBound,
upperBound = cfg.upperBound,
startCallback = cfg.startCallback,
moveCallback = cfg.moveCallback,
endCallback = cfg.endCallback,
attachLater = cfg.attachLater;
if(typeof el == 'string')
el = document.getElementById(el);
if(!el) return;
if(lowerBound != 정의되지 않음 && upperBound != 정의되지 않음) {
var tempPos = lowerBound.min(upperBound);
upperBound = lowerBound.max(upperBound);
lowerBound = tempPos;
}
varcursorStartPos,
elementStartPos,
끌기 = false,
듣기 = false,
disposed = false;
function dragStart(eventObj) {
if(드래깅 || !listening || 처리됨) return;
드래그 = true;
if(startCallback)
startCallback(eventObj, el);
cursorStartPos = 절대CursorPosition(eventObj);
elementStartPos = new Position(parseInt(getStyle(el, 'left')),parseInt(getStyle(el, 'top')));
elementStartPos = elementStartPos.check();
hookEvent(document, 'mousemove', dragGo);
hookEvent(document, 'mouseup', dragStopHook);
return cancelEvent(eventObj);
}
function dragGo(e) {
if(!draging || disposed) return;
var newPos =absoluteCursorPosition(e);
newPos = newPos.add(elementStartPos)
.subtract(cursorStartPos)
.bound(lowerBound, upperBound);
newPos.apply(el);
if(moveCallback)
moveCallback(newPos, el);
cancelEvent(e)를 반환합니다.
}
function dragStopHook(e) {
dragStop();
cancelEvent(e)를 반환합니다.
}
function dragStop() {
if(!draging || disposed) return;
unhookEvent(document, 'mousemove', dragGo);
unhookEvent(document, 'mouseup', dragStopHook);
cursorStartPos = null;
elementStartPos = null;
if(endCallback)
endCallback(el);
끌기 = 거짓;
}
this.startListening = function() {
if(listening || disposed) return;
듣기 = 사실;
hookEvent(attachEl, 'mousedown', dragStart);
};
this.stopListening = function(stopCurrentDragged) {
if(!listening || disposed)
return;
unhookEvent(attachEl, 'mousedown', dragStart);
듣기 = 거짓;
if(stopCurrentDragging && dragging)
dragStop();
};
this.dispose = function() {
if(disposed) return;
this.stopListening(true);
el = null;
attachEl = null;
lowerBound = null;
upperBound = null;
startCallback = null;
moveCallback = null;
endCallback = null;
처분됨 = 사실;
};
this.isDragged = function() {
드래깅을 반환합니다.
};
this.isListening = function() {
듣기 반환;
};
this.isDisposed = function() {
반환 폐기됨;
};
if(typeof attachmentEl == 'string')
attachEl = document.getElementById(attachEl);
// 如果没有配置, 或者没找到该Dom对象, 则用el
if(!attachEl) attachmentEl = el;
if(!attachLater)
this.startListening();
}

其中一些未给向, 在往下分析的过程中, 会一一给出....
我们先过cfg来使el和attachEl指向实际的Dom对象, 如果attachEl没配置或者没找到对应元素则用el替代. 우리는 같은 양의 중앙 정보를 사용하고 있습니다. 커서스타트포스(cursorStartPos)를 사용하면 더 많은 정보를 얻을 수 있습니다. elementStartPos를 사용하는 경우에는 모토를 사용하는 것이 좋습니다. 끌기, 듣기, 폐기하기. 듣기: 드래그 개체를 是否정재에서 监听拖拽开始事件. 끌기: 元素是否E 被拖拽. 배치됨: 개체 끌기被清리, 不能再被拖拽了.
复主代码 代码如下: this.startListening = function() {
if(listening ||disposed) return;
듣기 = 사실;
hookEvent(attachEl, 'mousedown', dragStart);
};

前两行就是做个判断 前两行就是做个判断, 如果已经开始对拖拽事件进行监听或者清理过了, 就什么都不做直接 리턴. 否则把listinging状态设为true, 表示我们开始监听啦, 把dragStart函数关联到attachEl'mousedown事件上. 这里碰到个hookEvent函数, 我们来看看它的样子:



复system代码
代码如下:

function HookEvent(el, eventName, callback) {
if(typeof el == 'string')
el = document.getElementById(el)
if(!el) return ;
if(el.addEventListener)
el.addEventListener(eventName, callback, false)
else if (el.attachEvent)
el.attachEvent('on' eventName, callback); 🎜>}

사실 아무것도 아닙니다. 단지 요소 이벤트를 모니터링하기 위한 크로스 브라우저 패키지를 만드는 것뿐입니다. 동일한 unhookEvent 메서드는 다음과 같습니다.

코드 복사 코드는 다음과 같습니다.
function unhookEvent(el, eventName, callback) {
if(typeof el == 'string ')
el = document.getElementById(el);
if(!el) return
if(el.removeEventListener)
el.removeEventListener(eventName, callback, false); else if(el.detachEvent)
el.detachEvent('on' eventName, callback);
}


그럼 dragStart 함수의 구현을 살펴보겠습니다. 드래그 객체의 전용 함수


function dragStart (eventObj) {
if(드래깅 || !listening || 배치) return;
draging = true;
if(startCallback)
startCallback(eventObj, el)
cursorStartPos = (eventObj);
elementStartPos = new Position(parseInt(getStyle(el, 'left')), parsInt(getStyle(el, 'top')))
elementStartPos.check(); >hookEvent(document, 'mousemove', dragGo);
hookEvent(document, 'mouseup', dragStopHook)
return cancelEvent(eventObj);


이 함수 AttachEl이 가리키는 DOM 객체가 mousedown 이벤트를 캡처한 후에 호출됩니다. 먼저 드래그 객체가 드래그에 적합한 상태인지 확인합니다. 드래그 이벤트가 모니터링되지 않는 경우. "마지막 작업"이 처리된 후 아무 작업도 수행하지 않습니다. 모든 것이 정상이면 드래그 상태를 true로 설정하고 startCallback이 정의된 경우 mousedown 이벤트와 el을 매개변수로 사용하여 호출합니다. 마우스의 절대 위치를 찾아 커서StartPos에 저장합니다. 그런 다음 드래그된 요소의 현재 상단과 왼쪽으로 이동하여 이를 Position 객체로 캡슐화하고 elementStartPos에 저장합니다. elementStartPos의 속성은 적법합니다. 하나는 드래그가 진행 중임을 의미하는 mousemove 이벤트이고, 하나는 드래그의 끝을 나타내고 호출됩니다. dragStopHook 함수. 여기에서는 el 또는 attachmentEl과 같은 드래그할 요소 대신 이벤트가 문서에 바인딩되는 이유가 궁금할 수 있습니다. 요소에 대한 직접 바인딩 이벤트를 고려하면 브라우저의 일부 지연으로 인해 효과에 영향을 미칠 수 있기 때문입니다. 그러니 이벤트를 문서에 직접 바인딩하세요. 실제로 이해하지 못한다면 영향이 크지 않을 수도 있습니다. P.... 마지막 문장을 읽어보세요. cancelEvent(eventObj)



코드 복사
코드는 다음과 같습니다. function cancelEvent(e) { e = e ?e
if(e.stopPropagation)
e.stopPropagation();
if(e.preventDefault)
e.preventDefault()
e.cancelBubble =
e.returnValue = false;
return false;
}


은 버블링을 중지하고 기본 이벤트를 방지하는 데 사용되며 이는 보안 고려 사항으로 이해할 수 있습니다.... dragStart에는 다음과 같은 몇 가지 메서드가 있습니다. 먼저 절대CursorPosition을 살펴보고 getStyle



코드 복사
를 살펴보겠습니다. function 절대CursorPosition(e) { e = e ? e : window.event;
var x = e.clientX (document.documentElement || document.body ).scrollLeft;
var y = e.clientY (document.documentElement || document.body).scrollTop;
return new Position(x, y)
}


이 방법은 브라우저에서 마우스의 절대 위치를 얻는 데에만 사용됩니다. 스크롤 막대를 고려하세요



코드 복사
코드는 다음과 같습니다. 다음과 같습니다:

function getStyle(el, property) {
if(typeof el == 'string')
el = document.getElementById(el)
if(!el || !property ) return;
var value = el.style[property];
if(!value) {
if(document.defaultView && document.defaultView.getCompulatedStyle) {
var css = document.defaultView .getCompulatedStyle(el, null);
value = css ? css.getPropertyValue(property) : null
} else if (el.currentStyle) {
value = el.currentStyle[property]; >}
}
return value == 'auto' ? '' : value;
}

getStyle 메소드는 요소의 CSS 속성 값을 가져오는 데 사용됩니다. 따라서 스타일은 중요하지 않습니다. 인라인으로 작성하든 CSS로 정의하든 올바른 값을 얻을 수 있습니다. 물론 요소의 위쪽 및 왼쪽 속성만 가져오면 실제로 드래그 앤 드롭이 처리됩니다. 작업: dragGo

코드 복사 코드는 다음과 같습니다.
function dragGo(e) {
if(!draging || disposed) return
var newPos =absoluteCursorPosition(e);
newPos = newPos.add(elementStartPos)
.subtract(cursorStartPos)
.bound(lowerBound) , upperBound);
newPos.apply(el );
if(moveCallback)
moveCallback(newPos, el)
return cancelEvent(e);
이 방법은 다른 방법과 마찬가지로 복잡하지 않습니다. 먼저 상태를 확인하고 모든 것이 잘되면 아무것도 하지 않습니다. 마우스, 요소의 초기 위치, 마우스의 초기 위치 및 제한된 범위(UpperBound 구성, lowerBound 구성인 경우)를 적용하여 결과 지점을 계산하고 계산된 좌표를 요소 style.top에 할당합니다. 및 style.left, 그리고 드래그 요소가 위치를 결정하도록 합니다. moveCallback이 구성된 경우 호출합니다. 마지막으로 cancelEvent가 옵니다... 여기서 새 좌표 작업은 Position의 각 메서드 때문에 jquery의 작업과 유사합니다. 객체는 Position 객체를 반환합니다... dragStart에 dragStopHook 메소드도 있습니다



코드 복사
코드는 다음과 같습니다. function dragStopHook(e) { dragStop();
return cancelEvent( e);
}
function dragStop() {
if(!draging || 폐기)
unhookEvent(document, 'mousemove', dragStopHook)
cursorStartPos = null
if (endCallback)
endCallback(el);
draging = false;
}


또한 모든 것이 상태인지 확인하는 것이 중요합니다. 좋아, 이벤트 바인딩 mousemove 및 mouseup을 제거하고 ​​cursorStartPos 및 elementStartPos의 값을 해제합니다. 드래그가 끝나면...endCallback을 구성한 후 이를 호출하고 마지막으로 드래그 상태를 false로 설정합니다. 마지막으로 사용될 public 메소드는



코드 복사

코드는 다음과 같습니다. this.stopListening = function(stopCurrentDragged) { if(!listening ||distributed) return; unhookEvent(attachEl, 'mousedown', dragStart)
listening = false; 🎜>if(stopCurrentDrging && dragging)
dragStop();
};
this.dispose = function() {
if (disposed) return;
el = null;
attachEl = null;
upperBound = null;
moveCallback = null
disposed = true;
};
this.isDragged = function() {
return dragging;
};
this.isListening = function() {
return listening;
};
this.isDisposed = function() {
return disposed;


stopListening은 드래그를 수신하는 mousedown 이벤트를 제거하고 청취를 설정합니다. false를 수신하는 상태입니다. 잘 알려진 stopCurrentDraging 매개변수가 있습니다. dispose 메소드는 드래그 객체를 드래그하지 않으려는 경우 다음 세 가지 작은 메소드에 대해 호출합니다. isDragged, isListening, isDisposed, 한 눈에 알 수 있고 관련 상태를 반환할 수 있습니다. 마지막으로 소스 코드에 대한 드롭다운 링크를 제공합니다
다운로드하고 클릭하세요
메시지를 남기고 소통할 수 있는 친구를 환영합니다!
관련 라벨:
원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!