>  기사  >  웹 프론트엔드  >  JavaScript CSS 수정 학습 6장 드래그 앤 드롭_기본 지식

JavaScript CSS 수정 학습 6장 드래그 앤 드롭_기본 지식

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

예제 상자의 # 링크가 활성화된 경우(탭 및 Enter 또는 마우스 클릭) 화살표 키를 사용하여 이 요소를 드래그할 수 있습니다. 그런 다음 Enter 또는 Esc를 클릭하여 놓습니다. (이 키들은 자유롭게 변경하세요. 릴리즈 키를 무엇으로 설정해야 할지 잘 모르겠으니 Enter 키를 누르면 Esc가 작동합니다)

사용

1. 기사 뒤에 dragDrop 개체를 복사합니다.

2. 여기에 필요한 addEventSimple 및 RemoveEventSimple 함수를 복사합니다.

3. keyHTML 및 keySpeed ​​속성을 설정합니다(아래 설명 참조).

4. 드래그하려는 요소에 절대 또는 고정 위치 속성이 있는지 확인하세요.

5. 드래그 가능한 모든 요소를 ​​개체의 initElement 함수로 보냅니다. 객체 또는 객체 ID 문자열을 보낼 수 있습니다. 예:

dragDrop.initElement('test');<br>dragDrop.initElement(document.getElementById('test2'));

6. 요소를 드래그하면 코드가 자동으로 드래그된 클래스를 추가합니다. CSS 효과를 추가할 수 있습니다.

7. 사용자가 요소를 해제한 후 작업을 수행하려면 releaseElement에 고유한 함수를 추가할 수 있습니다.

속성

두 가지 속성을 설정해야 합니다.

keyHTML에는 드래그해야 하는 요소의 키보드로 액세스할 수 있는 링크의 내용이 포함되어 있습니다. HTML을 단순하게 유지하기 위해 간단한 스타일의 클래스만 추가합니다. 원하는 대로 HTML을 구성할 수 있지만 키보드 사용자가 드래그 이벤트를 트리거하려면 포커스가 필요하다는 점을 기억하세요.

keySpeed ​​​​는 키보드 드래그 속도와 키를 누를 때마다 이동할 픽셀 수를 설정하는 데 사용됩니다. 저는 10으로 설정하는 것을 좋아하지만 다른 값을 시도해 볼 수도 있습니다.

여기에는 7개의 속성이 더 있지만 모두 코드 안에 있습니다. 초기화 중에 모두 정의되지 않은 상태로 설정되며, 해당 기능이 이를 설정합니다.

객체 드래그


다음 개체를 페이지에 복사하세요. addEventSimple 및 RemoveEventSimple을 잊지 마세요.

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

dragDrop = {
    keyHTML: '#',
    keySpeed: 10, // 키 누름당 픽셀 이벤트
    initialMouseX: 정의되지 않음,
    initialMouseY: 정의되지 않음,
    startX: 정의되지 않음,
    startY: 정의되지 않음,
    dXKeys: 정의되지 않음,
    dYKeys: 정의되지 않음,
    daggedObject: 정의되지 않음 ,
    initElement: 함수(요소) {
        if (요소 유형 == '문자열')
            요소 = document.getElementById(요소);
        element.onmousedown = dragDrop.startDragMouse;
        element.innerHTML = dragDrop.keyHTML;
        varlinks = element.getElementsByTagName('a');
        var lastLink = 링크[links.length-1];
        lastLink.관련Element = 요소;
        lastLink.onclick = dragDrop.startDragKeys;
    },
    startDragMouse: function (e) {
        dragDrop.startDrag(this);
        var evt = e || 창.이벤트;
        dragDrop.initialMouseX = evt.clientX;
        dragDrop.initialMouseY = evt.clientY;
        addEventSimple(document,'mousemove',dragDrop.dragMouse);
        addEventSimple(document,'mouseup',dragDrop.releaseElement);
        false를 반환합니다.
    },
    startDragKeys: function () {
        dragDrop.startDrag(this.관련Element);
        dragDrop.dXKeys = dragDrop.dYKeys = 0;
        addEventSimple(document,'keydown',dragDrop.dragKeys);
        addEventSimple(document,'keypress',dragDrop.switchKeyEvents);
        this.blur();
        false를 반환합니다.
    },
    startDrag: function (obj) {
        if (dragDrop.draggedObject)
            dragDrop.releaseElement();
        dragDrop.startX = obj.offsetLeft;
        dragDrop.startY = obj.offsetTop;
        dragDrop.draggedObject = obj;
        obj.className = '끌어옴';
    },
    dragMouse: function (e) {
        var evt = e || 창.이벤트;
        var dX = evt.clientX - dragDrop.initialMouseX;
        var dY = evt.clientY - dragDrop.initialMouseY;
        dragDrop.setPosition(dX,dY);
        false를 반환합니다.
    },
    드래그 키: function(e) {
        var evt = e || 창.이벤트;
        var key = evt.keyCode;
        스위치(키) {
            case 37:    // left
            case 63234:
              dragDrop.dXKeys -= dragDrop.keySpeed;
                휴식;
            case 38:    // up
            case 63232:
               dragDrop.dYKeys -= dragDrop.keySpeed;
                휴식;
            case 39:    // 오른쪽
            case 63235:
               dragDrop.dXKeys = dragDrop.keySpeed;
                휴식;
            case 40:    // down
            case 63233:
               dragDrop.dYKeys = dragDrop.keySpeed;
                휴식;
            사례 13:     // 입력
            사례 27:     // 이스케이프
               dragDrop.releaseElement();
                false를 반환합니다.
            기본값:
                true를 반환합니다.
        }
        dragDrop.setPosition(dragDrop.dXKeys,dragDrop.dYKeys);
        if (evt.preventDefault)
            evt.preventDefault();
        false를 반환합니다.
    },
    setPosition: function (dx,dy) {
        dragDrop.draggedObject.style.left = dragDrop.startX dx 'px';
        dragDrop.draggedObject.style.top = dragDrop.startY dy 'px';
    },
    switchKeyEvents: function () {
        // Opera 및 Safari 1.3용
        removeEventSimple(document,'keydown',dragDrop.dragKeys);
        removeEventSimple(document,'keypress',dragDrop.switchKeyEvents);
        addEventSimple(document,'keypress',dragDrop.dragKeys);
    },
    releaseElement: function() {
        removeEventSimple(document,'mousemove',dragDrop.dragMouse);
        removeEventSimple(document,'mouseup',dragDrop.releaseElement);
        removeEventSimple(document,'keypress',dragDrop.dragKeys);
        removeEventSimple(document,'keypress',dragDrop.switchKeyEvents);
        removeEventSimple(document,'keydown',dragDrop.dragKeys);
        dragDrop.draggedObject.className = dragDrop.draggedObject.className.replace(/dragged/,'');
        dragDrop.draggedObject = null;
    }
}

드래그란
드래그는 화면의 요소를 이동시키는 방법입니다. 요소를 이동하려면 요소에 위치 속성(절대 또는 고정)이 있어야 하며 좌표(style.top 및 style.left)를 수정하여 이동할 수 있습니다.
(이론적으로는 position:relative도 가능하지만 거의 쓸모가 없습니다. 게다가 계산하려면 추가 데이터가 필요하므로 여기서는 작성하지 않았습니다.)
좌표 설정은 요소의 좌표를 찾는 것이 매우 간단합니다. 설정해야 할 코드는 이 코드입니다. 더 어려운 부분입니다. 대부분의 코드는 이 문제를 처리하도록 설계되었습니다.
또한 사용 편의성을 유지하는 것도 중요합니다. 전통적으로는 마우스로 요소를 드래그하는 것이 가장 좋은 방법이지만, 마우스가 없는 사용자도 고려해야 하므로 키보드의 가용성도 보장되어야 합니다.

기본
먼저 몇 가지 기본 사항을 살펴보겠습니다.
요소 초기화
모든 드래그 앤 드롭 코드는 요소 초기화로 시작됩니다. 이 작업은 다음 문자를 통해 완료됩니다.
코드 복사 코드는 다음과 같습니다.

initElement: function ( element) {
if (typeof element == 'string')
element = document.getElementById(element)
element.onmousedown = dragDrop.startDragMouse
element.innerHTML = dragDrop.keyHTML;
var link = element.getElementsByTagName('a');
var lastLink =links[links.length-1]
lastLink.관련Element = 요소
lastLink.onclick = dragDrop.startDragKeys;
},

함수가 문자열을 받으면 요소 ID로 처리됩니다. 그런 다음 이 요소에 대한 onmousedown 이벤트를 설정하여 코드의 마우스 부분을 시작합니다. 여기서는 이 키워드가 startDragDrop에서 작동하도록 하기 위해 전통적인 이벤트 등록 방법을 사용하고 있습니다.

그런 다음 사용자 정의 keyHTML을 요소에 추가하면 이 링크가 키보드 이벤트를 트리거하는 데 사용되는 것 같습니다. 그런 다음 이 링크에 대한 키보드 트리거 프로그램을 설정하십시오. 그런 다음 나중에 필요할 주요 요소를 관련 요소에 저장합니다.

이제 코드는 사용자 작업을 기다리고 있습니다

기본 위치 정보
다음 방법을 사용할 계획입니다. 먼저 드래그된 요소의 초기 위치를 읽어서 저장하겠습니다. startX 및 startY를 입력합니다. 그런 다음 마우스 이동 위치 또는 키보드 제어 하의 이동 위치를 계산하여 초기 위치에서 요소의 이동 범위를 결정합니다.
image
startX 및 startY는 마우스 및 키보드 이벤트에 사용되는 startDrag 함수를 통해 설정됩니다.
코드 복사 코드는 다음과 같습니다.

startDrag: function(obj) {
if ( dragDrop.draaggedObject)
dragDrop.releaseElement();
dragDrop.startX = obj.offsetLeft;
dragDrop.startY = obj.offsetTop;
dragDrop.draggedObject = obj; obj.className = 'dragged';
},

먼저 요소가 드래그된 상태이면 해제합니다(나중에 설명하겠습니다).
그런 다음 함수는 시작 위치(offsetLeft 및 offsetTop)에서 요소의 좌표를 찾은 다음 나중에 사용할 수 있도록 startX 및 startY에 저장합니다.
그런 다음 draggedObject에 개체에 대한 참조를 저장합니다. 그런 다음 CSS를 통해 드래그 스타일을 설정할 수 있도록 드래그 클래스를 추가합니다.
사용자가 마우스나 키보드를 사용하여 요소를 드래그할 때 코드에서 가장 복잡한 부분은 위치 변경을 추적하는 것입니다. 그런 다음 dX와 dY(X와 Y의 변화)가 제공됩니다. 그런 다음 startX 및 startY를 추가하여 요소의 현재 위치를 가져옵니다.
위치를 설정하는 데는 다음 함수가 사용됩니다.

코드 복사 코드는 다음과 같습니다.
setPosition: function (dx,dy) {
dragDrop.draggedObject.style.left = dragDrop.startX dx 'px'
dragDrop.draggedObject.style.top = dragDrop.startY dy 'px ';
},


이 함수는 마우스와 키보드 움직임으로 계산된 dX, dY와 초기 위치를 사용하여 요소의 새 위치를 설정합니다.
이 부분은 매우 간단합니다. 복잡한 부분은 dx와 dy의 획득에 있습니다. 마우스 부분과 키보드 부분의 처리가 매우 다릅니다.

마우스 부품 코드
마우스 부품 계산은 키보드 계산보다 복잡하지만 브라우저 호환성 측면에서는 큰 문제가 없습니다. 그럼 마우스 부분부터 시작하겠습니다.
이벤트
먼저 이벤트에 대해 이야기해보겠습니다. 분명히 객체 선택, 드래그 및 드래그 작업을 완료하려면 드래그 프로세스 중에 mousedown, mousemove 및 mouseup이 필요합니다.
이 일련의 이벤트는 요소를 드래그해야 하는 mousedown 이벤트로 시작됩니다. 따라서 모든 드래그 요소에는 드래그가 시작되었음을 나타내기 위해 이 이벤트가 필요합니다.
코드 복사 코드는 다음과 같습니다.
element.onmousedown = dragDrop.startDragMouse; 🎜>
그러나 mousemove 및 mouseup 이벤트는 요소에 설정해서는 안 되며 문서 전체에 설정해야 합니다. 사용자가 마우스를 빠르고 정신없이 움직일 수 있고 드래그한 요소를 잃을 수 있기 때문입니다. 요소에 설정하면 해당 요소 위에 마우스가 없기 때문에 제어가 불가능할 수 있는데, 이는 사용성 측면에서 좋지 않습니다.
문서에 mousemove와 mouseup을 설정하면 이런 문제는 발생하지 않습니다. 마우스가 어디에 있든 요소는 mousemove 및 mouseup에 응답합니다. 이것은 사용하기 매우 쉽습니다.
또한 드래그가 시작된 후에만 mousemove 및 mouseup을 설정할 수 있으며, 사용자가 요소를 놓을 때 삭제할 수 있습니다. 이 코드는 매우 깔끔하고 시스템 리소스를 절약해 줍니다. 왜냐하면 mousemove는 많은 시스템 리소스를 소비하기 때문입니다.
Mousedown
드래그 요소에서 mousedown 이벤트가 발생하면 startDragMouse 함수가 실행되기 시작합니다.

먼저 앞서 논의한 startDrag가 실행됩니다. 그런 다음 마우스의 좌표를 찾아 이를initialMouseX 및initialMouseY에 저장합니다. 나중에 마우스 위치를 이것과 비교해 보겠습니다.

마지막으로 기본 마우스 이벤트인 텍스트 선택을 방지하는 데 사용되는 false가 반환됩니다. 우리는 더 이상 드래그할 때 텍스트가 선택되는 것을 원하지 않습니다. 이는 성가신 일입니다.

image

그런 다음 문서에 대한 mouseup 및 mousemove 이벤트 핸들러를 설정합니다. 문서에 자체적인 mouseup 및 mousemove 이벤트 핸들러가 있을 가능성이 있으므로 addEventSimple 함수를 사용하여 원래 이벤트 핸들러가 실패하는 것을 방지합니다.

Mousemove
이제 사용자가 마우스를 움직일 때 dragMouse 함수가 실행됩니다.


코드 복사 코드는 다음과 같습니다.
dragMouse: 함수(e) {
var evt = e || window.event;
var dX = evt.clientX - dragDrop.initialMouseX;
var dY = evt.clientY - dragDrop.setPosition(dX; ,dY) ;
false
},

반환

这个函数会读取鼠标现在的坐标,然后减去之前的坐标,把得到的dX和dY传递给sePosition。

然后通过返回false来阻止鼠标选择文本的默认属性。

image

Mouseup

当用户松开鼠标的时候,会调用releaseElement。我们后面讨论。

 

键盘部分代码

现在我们开始更复杂的键盘部分代码。不像鼠标拖拽那样,键盘拖拽并没有一个标准。虽说基本的交互不是太复杂,但是最好还是简要说明一下。

基本交互

用来拖拽的键最好是方向键,这很简单。

激活和释放元素是比较有技巧的,在这里我的代码还需要加强。

我觉得如果用键盘来激活的话就应该使用一个我添加的额外的链接。这里没有太多选择:因为链接能够在所有的浏览器里面获得焦点(好吧,表单也可以,你也可是选择复选框),而且把一个链接放置在可拖拽的元素里面也是合乎逻辑的(你可以放在任何地方,但是如何让用户知道那个是用来激活拖拽的呢?)。

我假设当用户点击enter或者Esc的时候释放元素,至少我没找到其他合适的键。你想选择其他的话可以在这里查找键盘代码

case 13: // enter<br>case 27: // escape<br>	dragDrop.releaseElement();<br>	return false;

 

事件

点击可以激活元素。当鼠标点击链接或者当元素获得焦点的时候点击enter键就能激活。所以键盘代码的激活可以使点击enter键或者点击链接。

(严格来说,当你用鼠标点击链接的时候,元素先被鼠标事件激活然后释放了然后再被键盘模式激活。)

事件的其余部分也非常的模糊。当你想检测方向键的时候键盘事件尤为麻烦。

首先我们需要一个允许重复点击的事件,因为用户可能按着方向键不放,那么事件就需要一遍遍的触发,这样拖拽才能继续。所以我们使用keypress事件。

不幸的是,IE在keypress的情况下不支持方向键。在IE里面keydown会重复发生,看起来我们需要使用keydown事件了。

你可能才到事情没那么简单。在Opera和Safari里面keydown事件只能触发一次,所以当用户按下键之后,元素移动一次之后就不动了。在这些浏览器中我们需要keypress。

所以理想情况下,我们使用keypress,如果不支持就是用keydown。但是怎么切换事件呢?你又怎么知道keypress在这个时候不能用呢?

我的解决办法就是给keypress事件设置一个事件处理程序。如果这个程序执行了说明支持keypress,我们就可以安全的切换了。

startDragKeys函数用来设置keydown和keypress事件:

复制代码 代码如下:

addEventSimple(document,'keydown',dragDrop.dragKeys);
addEventSimple(document,'keypress',dragDrop.switchKeyEvents);

首先keydown触发完成拖拽的dragKeys函数。这是第一个触发的事件,而且元素总会移动。然后我们做其他的话,那么元素在Opera和Safari1.3里面移动一次以后就会停止。
这就是为什么我们还需要keypress。第一个keypress事件会触发switchKeyEvents函数,这个函数会调整事件处理程序:
复制代码 代码如下:

switchKeyEvents: function () {
    removeEventSimple(document,'keydown',dragDrop.dragKeys);
    removeEventSimple(document,'keypress',dragDrop.switchKeyEvents);
    addEventSimple(document,'keypress',dragDrop.dragKeys);
},

他会先删除掉原来的事件处理程序,然后将keypress设置为触发dragKeys。因为这个函数只会在支持他的浏览器里面执行,所以我们只在这些浏览器里面将keydown改为keypress。
初始键盘代码
当用户点击了连接激活了元素,那么就会调用startDragKeys。
复制代码 代码如下:

startDragKeys: function () {
dragDrop.startDrag(this.관련Element);
dragDrop.dXKeys = dragDrop.dYKeys = 0
addEventSimple(document,'keydown',dragDrop. dragKeys);
addEventSimple(document,'keypress',dragDrop.switchKeyEvents)
this.blur();
return false

앞서 설명한 startDrag 함수를 호출합니다. 그는 드래그할 요소인 관련 요소를 이 함수에 전달합니다.
그런 다음 dXKeys 및 dYKeys를 0으로 설정합니다. 이러한 변수는 요소의 변위를 추적하는 데 사용됩니다.
그런 다음 위에서 설명한 이벤트 핸들러를 설정합니다.
그런 다음 방금 클릭한 링크에서 포커스를 제거하세요. Enter 키를 누르면 요소가 해제되지만 포커스가 제거되지 않는 경우 사용자가 Enter 키를 클릭하면 요소는 해제되지만 링크는 Enter를 통해 다시 클릭되어 다시 드래그 가능해지기 때문입니다. 포커스를 제거하면 문제가 더 이상 존재하지 않습니다.
기본 동작을 방지하려면 마지막으로 false를 반환합니다.
키보드를 통한 드래그
드래그키는 키보드 드래그를 담당합니다.

코드 복사 코드는 다음과 같습니다.
dragKeys: function(e) {
var evt = e || window.event;
var key = evt.keyCode; 키보드 키 값.
그런 다음 스위치 문을 사용하여 수행할 작업을 결정합니다. 이 부분의 목적은 dXKeys와 dYKeys의 값을 업데이트하여 요소의 위치를 ​​설정하여 이동할 수 있도록 하는 것입니다.



코드 복사
코드는 다음과 같습니다. 스위치(키) { 케이스 37: / / 왼쪽
케이스 63234:
dragDrop.dXKeys -= dragDrop.keySpeed;
break
케이스 38: // 위로
케이스 63232:
dragDrop.dYKeys - = dragDrop.keySpeed;
break;
케이스 39: // 오른쪽
케이스 63235:
dragDrop.dXKeys =
케이스 4 0: // down
case 63233:
dragDrop.dYKeys = dragDrop.keySpeed;
break;


저자는 keySpeed를 설정하여 각 이동의 픽셀 크기를 결정합니다. 사용자가 왼쪽 화살표 키를 클릭하면 keySpeed가 뺍니다.



이 코드에는 63232-63235 케이스가 포함되어 있습니다. Safari 1.3은 표준 37-40 화살표 키 값을 사용하지 않기 때문입니다(Safari 3에서는 이미 지원함).
image

코드 복사
코드는 다음과 같습니다.case 13: // Enter 사례 27: // escape dragDrop.releaseElement(); return false;

사용자가 Enter 또는 Esc 키를 클릭하면 releaseElement() 함수가 호출됩니다. 요소를 해제하기 위해 키를 변경하려면 여기에 추가할 수 있습니다.




코드 복사
코드는 다음과 같습니다.기본값: return true; 🎜>} 사용자가 다른 키를 누르면 기본 동작을 실행하고 기능을 종료합니다.



코드 복사

코드는 다음과 같습니다. dragDrop.setPosition(dragDrop.dXKeys,dragDrop .dY키)
이제 dXKeys 및 dYKeys가 업데이트되었으므로 이를 setPosition() 함수로 보내 요소의 위치를 ​​변경합니다.

코드 복사 코드는 다음과 같습니다.
if (evt.preventDefault)
evt.preventDefault ();
return false;
},

마지막으로 사용자가 아래쪽 화살표 키를 클릭하면 위의 내용을 실행한 후 페이지가 아래로 스크롤됩니다. 암호. 이는 W3C 호환 브라우저에서는 PreventDefault를 사용하고 IE에서는 false를 반환하여 구현됩니다.


요소 해제
사용자가 요소를 해제하면 releaseElement 함수가 호출됩니다. 코드에 의해 설정된 모든 이벤트 핸들러를 제거하고, 드래그된 클래스를 제거하고, draggedObject를 정리하고 사용자 작업을 기다립니다.
코드 복사 코드는 다음과 같습니다.

releaseElement: function() {
RemoveEventSimple(document ,'mousemove',dragDrop.dragMouse);
removeEventSimple(document,'mouseup',dragDrop.releaseElement);
removeEventSimple(document,'keypress',dragDrop.dragKeys)
removeEventSimple( document,' keypress',dragDrop.switchKeyEvents);
RemoveEventSimple(document,'keydown',dragDrop.dragKeys)
dragDrop.draggedObject.className = dragDrop.draggedObject.className.replace(/dragged/,'' );
DragDrop.draggedObject = null;
}

사용자가 요소를 해제한 후 뭔가를 하고 싶을 수도 있습니다. 여기에 함수를 추가할 수 있습니다.
번역 주소: http://www.quirksmode.org/js/dragdrop.html
재인쇄를 위해 다음 정보를 보관해 주세요
저자: Beiyu(tw:@rehawk)
성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.