How to Drag and Drop in JavaScript

本文介绍如何使用JavaScript实现网页上的元素拖放功能。通过监听鼠标事件并计算元素位置,可以使页面元素支持拖拽交互。适用于希望提升用户体验的前端开发者。

reference:http://www.webreference.com/programming/javascript/mk/column2/index.html

 

JavaScript excels at modifying the DOM of a Web page, but we usually only do simple things with it, such as creating image rollovers, making tabs, etc. This article is going to show you how to create items on your page that you can drag and drop.

There are several reasons you might want to encorporate this drag and drop ability into your Web pages. One of the simplest reasons is to reorganize Data. As an example, you might want to have a queue of items that your users can reorganize. Instead of putting an input or select box next to each item to represent its order, you could make the entire group of items draggable. Or perhaps you want to have a navigation window on your site that can be moved around by your users. Then there's always the simplest reason: because you can!

There's really not much involved with dragging an item around on your Web page. First we have to know where the mouse cursor is, second we need to know when the user clicks on an item so that we know we should be dragging it, and finally we need to move the item.

Demo - Drag any of the images

Demo - Drag and Drop any item
Item #1
Item #2
Item #3
Item #4
Item #5
Item #6
Item #7
Item #8
Item #9
Item #10
Item #11
Item #12

 

Capturing Mouse Movement

To start we need to capture the mouse coordinates. This is done by adding a function to document.onmousemove:

  view plain | print | copy to clipboard | ?
 
1document.onmousemove = mouseMove;  
2 
3 function mouseMove(ev){  
4    ev           = ev || window.event;  
5    var mousePos = mouseCoords(ev);  
6}  
7 
8 function mouseCoords(ev){  
9    if(ev.pageX || ev.pageY){  
10        return {x:ev.pageX, y:ev.pageY};  
11    }  
12    return {  
13        x:ev.clientX + document.body.scrollLeft - document.body.clientLeft,  
14        y:ev.clientY + document.body.scrollTop  - document.body.clientTop  
15    };  
16}  
document.onmousemove = mouseMove; function mouseMove(ev){ ev = ev || window.event; var mousePos = mouseCoords(ev); } function mouseCoords(ev){ if(ev.pageX || ev.pageY){ return {x:ev.pageX, y:ev.pageY}; } return { x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, y:ev.clientY + document.body.scrollTop - document.body.clientTop }; }
Demo - Move your mouseMouse X Position:   Mouse Y Position:

 

We must first explain the event object. Whenever you move the mouse, click, press a key, etc., an event is fired. in Internet Explorer this event is global; it's stored in window.event. In Firefox, and other browsers, this event is passed to whatever function is attached to the action. Since we attached the mouseMove function to document.onmousemove, mouseMove gets passed the event object.

To make ev contain the event object in every browser we OR it with window.event. In Firefox the " || window.event" will be ignored since ev already contains the event. In IE ev is null so it will get set to window.event.

Since we'll need to obtain the mouse coordinates many times over this article we make a mouseCoords function that takes one argument: the event.

Again we run into differences between IE and other browsers. Firefox and other browsers use event.pageX and event.pageY to represent the mouse position relative to the document. If you have a 500x500 window and your mouse is in the middle, pageX and pageY will both be 250. If you then scroll down 500 pixels pageY will now by 750.

Contrary to this, IE decided to use event.clientX and event.clientY to represent the mouse position relative to the window, not the document. In our same example clientX and clientY will both be 250 if you put your mouse at the middle of a 500x500 window. If you scroll down on the page, clientY will remain 250 since it is measured relative to the window and not where you are on the document. As a result we need to add the scrollLeft and scrollTop properties of the document body to our mouse position. Finally, the document in IE isn't actually at the 0,0 position. There is a small (usually 2px) border surrounding it. document.body.clientLeft and clientTop countain the width of this border, so we add those also to our mouse position.

Fortunately since we now have our mouseCoords function we don't have to worry about this again.

Capturing Mouse Clicks

Next we need to know when your mouse button is pressed and when it is released. If we skip this step you would be "dragging" items whenever your mouse happened to move over them. This would be both annoying and counterintuitive.

There are two more functions that help us here: onmousedown and onmouseup. We previously attached a function to document.onmousemove, so it only seems logical that we would attach functions to document.onmousedown and document.onmouseup. If we attach a function to document.onmousedown, however, our function would get fired on any object we click on: text, images, tables, etc. We only want certain items on our page to be draggable so we instead attach a function to the onmousedown event of whatever we want to move.

  view plain | print | copy to clipboard | ?
 
1document.onmouseup = mouseUp;  
2 var dragObject     = null;  
3 
4 function makeClickable(object){  
5    object.onmousedown = function(){  
6        dragObject = this;  
7    }  
8}  
9 
10 function mouseUp(ev){  
11    dragObject = null;  
12}  
document.onmouseup = mouseUp; var dragObject = null; function makeClickable(object){ object.onmousedown = function(){ dragObject = this; } } function mouseUp(ev){ dragObject = null; }

We now have a variable, dragObject, that contains any item you click on. If you release the mouse button dragObject gets set to null. So if dragObject != null we know that we should be dragging something.

Demo - Click any image


You clicked on:

 

Moving an Item

We now know how to capture mouse movements and clicks. All that's left to do is move around whatever we want to drag. First, to move an item to exactly where we want it to be on a page, the style position of that item must be set to 'absolute'. Setting an item's position to absolute means that when you set a style.top or style.left on the item, the measurements are relative to the top-left of your page. Since all of our mouse movements are also relative to the top-left of our page, this is generally the way to go.

Once we set item.style.position='absolute', all we have to do is change the top or left position of the item and voila, it's moved!

  view plain | print | copy to clipboard | ?
 
1document.onmousemove = mouseMove;  
2document.onmouseup   = mouseUp;  
3 
4 var dragObject  = null;  
5 var mouseOffset = null;  
6 
7 function getMouseOffset(target, ev){  
8    ev = ev || window.event;  
9 
10    var docPos    = getPosition(target);  
11    var mousePos  = mouseCoords(ev);  
12    return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y};  
13}  
14 
15 function getPosition(e){  
16    var left = 0;  
17    var top  = 0;  
18 
19    while (e.offsetParent){  
20        left += e.offsetLeft;  
21        top  += e.offsetTop;  
22        e     = e.offsetParent;  
23    }  
24 
25    left += e.offsetLeft;  
26    top  += e.offsetTop;  
27 
28    return {x:left, y:top};  
29}  
30 
31 function mouseMove(ev){  
32    ev           = ev || window.event;  
33    var mousePos = mouseCoords(ev);  
34 
35    if(dragObject){  
36        dragObject.style.position = 'absolute';  
37        dragObject.style.top      = mousePos.y - mouseOffset.y;  
38        dragObject.style.left     = mousePos.x - mouseOffset.x;  
39 
40        return false;  
41    }  
42}  
43 function mouseUp(){  
44    dragObject = null;  
45}  
46 
47 function makeDraggable(item){  
48    if(!item) return;  
49    item.onmousedown = function(ev){  
50        dragObject  = this;  
51        mouseOffset = getMouseOffset(this, ev);  
52        return false;  
53    }  
54}  
document.onmousemove = mouseMove; document.onmouseup = mouseUp; var dragObject = null; var mouseOffset = null; function getMouseOffset(target, ev){ ev = ev || window.event; var docPos = getPosition(target); var mousePos = mouseCoords(ev); return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y}; } function getPosition(e){ var left = 0; var top = 0; while (e.offsetParent){ left += e.offsetLeft; top += e.offsetTop; e = e.offsetParent; } left += e.offsetLeft; top += e.offsetTop; return {x:left, y:top}; } function mouseMove(ev){ ev = ev || window.event; var mousePos = mouseCoords(ev); if(dragObject){ dragObject.style.position = 'absolute'; dragObject.style.top = mousePos.y - mouseOffset.y; dragObject.style.left = mousePos.x - mouseOffset.x; return false; } } function mouseUp(){ dragObject = null; } function makeDraggable(item){ if(!item) return; item.onmousedown = function(ev){ dragObject = this; mouseOffset = getMouseOffset(this, ev); return false; } }

 

 

 

Qt Quick enables you to build UIs around the behavior of components and how they connect with one another. You create components using Qt Quick and QML types that are available in the Design mode. You can specify values for the properties of a component to change its appearance and behavior. All QML types have a set of predefined properties, some of which control things that are visible to users, while others are used behind the scene. While it is useful to learn the basics of Qt Quick, you can also rely on Qt Design Studio to write the code for you when you drag-and-drop the ready-made components to the working area and change them to your liking by modifying their properties in the Design mode. You can always check up details in the extensive Qt Quick documentation by pressing F1. Creating Qt Quick Projects You can use wizards to create Qt Quick projects. Editing QML Files in Design Mode You can use the Form Editor or the Text Editor in the Design mode to develop Qt Quick applications. Creating Components In addition to your imported artwork, you can use the Design mode to customize ready-made components or design any custom form and shape directly as QML types. You can import visual assets in various formats, such as PNG, JPG, and SVG for use in the components. Managing Item Hierarchy You can manage the items in the current QML file and their relationships in the Navigator. Specifying Item Properties You can specify values for the properties of a component to change its appearance and behavior. All QML types have a set of predefined properties. Some properties, such as position, size, and visibility, are common to all QML types, whereas others are specific to the QML type. You can specify properties for your components in the Properties pane. Creating Animations You can use a timeline and keyframe based editor in the Timeline view to animate the properties of UI components. Animating properties enables their values to move through intermediate values at specified keyframes instead of immediately changing to the target value. Adding Connections You can create connections between the UI components and the application to enable them to communicate with each other. For example, how does the appearance of a button change on a mouse click and which action does the application need to perform in response to it. You can also create connections between UI components by binding their properties together. This way, when the value of a property changes in a parent component, it can be automatically changed in all the child components, for example. Adding States Qt Quick allows you to declare various UI states that describe how component properties change from a base state. Therefore, states can be a useful way of organizing your UI logic. You can associate transitions with items to define how their properties will animate when they change due to a state change. Related Topics Editing PathView Properties You can use a graphical spline editor to specify PathView paths. A path view lays out data provided by data models on a Path. Browsing ISO 7000 Icons You can add ISO 7000 icons from a library delivered with Qt Creator to UIs and change their color. Qt Quick UI Forms Some of the wizards create Qt Quick projects that contain UI forms (.ui.qml files). The forms use a purely declarative subset of the QML language and you can edit them in the Design mode. Using QML Modules with Plugins QML modules may use plugins to expose components defined in C++ to QML applications. Qt Creator cannot load the plugins to determine the details of the contained components, and therefore, the modules must provide extra type information for code completion and the semantic checks to work correctly. Converting UI Projects to Applications Qt Quick UI projects (.qmlproject) are useful for creating user interfaces. To use them for application development, you have to convert them to Qt Quick Application projects that contain .pro, .cpp, and .qrc files. Designing User Interfaces ◦ Creating Qt Quick Projects
09-11
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值