- 浏览: 296761 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (176)
- Algorithm (4)
- Diary (9)
- GIS-RS-GPS (15)
- Hibernate (1)
- JavaSE (4)
- 其他开源 (0)
- 架构与设计 (4)
- Web 客户端技术 (21)
- Web 框架与开发 (6)
- ArcEngine 开发 (2)
- ArcGIS Server 开发 (0)
- ArcIMS 开发 (3)
- 空间数据库 (0)
- Eclipse Plugin (1)
- Eclipse Framework (0)
- GIS-GPS-RS (0)
- [网站分类]1.网站首页原创Java技术区(对首页文章的要求: 原创、高质量、经过认真思考并精心写作。BlogJava管理团队会对首页的文章进行管理。) (54)
- [网站分类]2.Java新手区 (10)
- [网站分类]3.非技术区 (8)
- [网站分类]4.其他技术区 (19)
- [网站分类]6.转载区(Java技术文章转载, 请注明原文出处) (8)
最新评论
-
wen0301:
认同! 程序员必须锻炼内功,而不是华丽的花拳绣腿。
Google的Offer -
leelight:
我用了凸角圆弧法,发现此算法在半径相对较大时,输入结果经常是一 ...
GIS 缓冲区应用及算法实现 -
palmer:
据说 Google 有中国本地的服务器.有没有这方面的原因?? ...
地震为什么没有影响到 Google -
chxkyy:
跑getShapefileFeatureClass方法
AE92 SDK for Java 最小示例学习 -
chxkyy:
我在本地跑这个代码怎么报这个错:java.lang.Unsat ...
AE92 SDK for Java 最小示例学习
[翻译] 如何在 JavaScript 中实现拖放(下)
译者:
Flyingis
终于完成了全文的翻译,由于时间比较参促,文章没有过多的校正与润色,阅读过程中难免会有些许生硬或不准确的感觉,请大家见量并指出,方便他人阅读。
原文作者将拖放功能的实现分步讲解,其核心的地方在于移动和放置元素时,鼠标、移动元素、目标元素关系的处理,只要这个问题处理好了,代码就很容易理解,译文仅供辅助参考之用。
整合所有的功能
最后我们使用所有代码片断,来创建一个完整的拖放函数脚本。我们所要做的第一件事情是DOM操作,如果你对此并不十分熟悉,可以阅读《 JavaScript Primer on DOM Manipulation 》。
接下来的代码创建容器和容器组,使得在这些容器中可以拖动每个元素,这在本文第二个demo的基础上来完成。这段代码能够用来重新规划元素的顺序,将导航窗口放在页面的左侧或右侧,或再加入你所能想到的其他的功能。
我们将使用伪代码来一步步进行讲解,将真实的代码通过注释的方式留给读者查看。
1.当文档第一次被加载时,我们创建一个名为dragHelper的DIV标签,当我们开始移动一个元素的时候,dragHelper将成为一个隐藏元素,可以四处移动。真实的元素并不会被拖动,仅仅使用insertBefore和appendChild来移动。我们在开始的时候隐藏dragHelper。
2.我们创建mouseDown和mouseUp函数。起初,所有的这些函数都假设记录了鼠标按钮的状态,以至于iMouseDown变量在鼠标按下的时候为true,没有按下的时候为false。
3.我们创建一个全局变量DragDrops,以及一个函数CreateDragContainer。DragDrops包含一组相互关联的容器。传入CreateDragContainer的任何变量(代表容器)被组织成一个新的集合,使元素能够在这些容器间自由移动。通过setAttribute,CreateDragContainer函数同样将各容器中的元素绑定在一起。
4.现在我们的代码知道每个元素所在的集合,现在来看mouseMove函数。mouseMove函数首先设置了一个变量target,表示鼠标下面的目标元素,如果这个元素在集合(用getAttribute判断)中就继续下面操作:
4.1.首先,在必要的时候,我们运行一个简单的脚本来改变目标元素的class属性,这样就创造了一个翻动的效果。
4.2.然后我们检查鼠标是否点击(因为我们的代码已经运行到这里),如果事件发生:
4.2.1.设置变量curTarget为当前元素。
4.2.2.记录元素当前在文档中的位置,以便在需要的时候可以将它的值取回。
4.2.3.将当前元素克隆到dragHelper,使得我们能够移动元素的隐藏备份。
4.2.4.因为在dragHelper中我们完全拥有了拖动元素的一个备份,这个元素会始终在鼠标下,我们必须移除dragObj属性,让代码知道dragObj已不在集合中。
4.2.5.我们快速记录集合中每个元素当前的位置、宽度和高度。当元素第一次开始被拖动时,我们仅需做一次这种工作,否则每当鼠标移动的时候我们都必须做一次,甚至一秒内几百次。
4.3.如果鼠标没有点击,要么我们和之前拥有同样的目标元素,要么没有目标元素,不论哪种情况我们都不会做任何事情。
5.现在我们检查curTarget变量。curTarget应该仅包含一个被拖动的对象,因此如果它存在,表示我们正在拖动一个元素:
5.1.移动隐藏DIV到鼠标,这个元素和文章前面所创建的元素一样能够被拖动。
5.2.然后我们检查鼠标是否存在于当前集合中每个容器中。
5.2.1.如果鼠标在某个容器中,我们检查容器中的每个元素,查看我们正拖动的元素属于哪个位置。
5.2.2.然后我们将所拖动的元素放置在容器中另一个元素的前面,或容器的最后位置。
5.2.3.最后我们确定元素可见。
6.剩下的事情就是捕获mouseUp事件:
6.1.首先需要隐藏dragHelper:它不再被需要,因为我们没有拖动任何东西。
6.2.如果拖动的元素是可见的,它已经存在于任何它所属的容器中,所有工作已完成。
6.3.如果拖动的元素不可见,我们将它放回它原来所在的地方。
终于完成了全文的翻译,由于时间比较参促,文章没有过多的校正与润色,阅读过程中难免会有些许生硬或不准确的感觉,请大家见量并指出,方便他人阅读。
原文作者将拖放功能的实现分步讲解,其核心的地方在于移动和放置元素时,鼠标、移动元素、目标元素关系的处理,只要这个问题处理好了,代码就很容易理解,译文仅供辅助参考之用。
整合所有的功能
最后我们使用所有代码片断,来创建一个完整的拖放函数脚本。我们所要做的第一件事情是DOM操作,如果你对此并不十分熟悉,可以阅读《 JavaScript Primer on DOM Manipulation 》。
接下来的代码创建容器和容器组,使得在这些容器中可以拖动每个元素,这在本文第二个demo的基础上来完成。这段代码能够用来重新规划元素的顺序,将导航窗口放在页面的左侧或右侧,或再加入你所能想到的其他的功能。
我们将使用伪代码来一步步进行讲解,将真实的代码通过注释的方式留给读者查看。
1.当文档第一次被加载时,我们创建一个名为dragHelper的DIV标签,当我们开始移动一个元素的时候,dragHelper将成为一个隐藏元素,可以四处移动。真实的元素并不会被拖动,仅仅使用insertBefore和appendChild来移动。我们在开始的时候隐藏dragHelper。
2.我们创建mouseDown和mouseUp函数。起初,所有的这些函数都假设记录了鼠标按钮的状态,以至于iMouseDown变量在鼠标按下的时候为true,没有按下的时候为false。
3.我们创建一个全局变量DragDrops,以及一个函数CreateDragContainer。DragDrops包含一组相互关联的容器。传入CreateDragContainer的任何变量(代表容器)被组织成一个新的集合,使元素能够在这些容器间自由移动。通过setAttribute,CreateDragContainer函数同样将各容器中的元素绑定在一起。
4.现在我们的代码知道每个元素所在的集合,现在来看mouseMove函数。mouseMove函数首先设置了一个变量target,表示鼠标下面的目标元素,如果这个元素在集合(用getAttribute判断)中就继续下面操作:
4.1.首先,在必要的时候,我们运行一个简单的脚本来改变目标元素的class属性,这样就创造了一个翻动的效果。
4.2.然后我们检查鼠标是否点击(因为我们的代码已经运行到这里),如果事件发生:
4.2.1.设置变量curTarget为当前元素。
4.2.2.记录元素当前在文档中的位置,以便在需要的时候可以将它的值取回。
4.2.3.将当前元素克隆到dragHelper,使得我们能够移动元素的隐藏备份。
4.2.4.因为在dragHelper中我们完全拥有了拖动元素的一个备份,这个元素会始终在鼠标下,我们必须移除dragObj属性,让代码知道dragObj已不在集合中。
4.2.5.我们快速记录集合中每个元素当前的位置、宽度和高度。当元素第一次开始被拖动时,我们仅需做一次这种工作,否则每当鼠标移动的时候我们都必须做一次,甚至一秒内几百次。
4.3.如果鼠标没有点击,要么我们和之前拥有同样的目标元素,要么没有目标元素,不论哪种情况我们都不会做任何事情。
5.现在我们检查curTarget变量。curTarget应该仅包含一个被拖动的对象,因此如果它存在,表示我们正在拖动一个元素:
5.1.移动隐藏DIV到鼠标,这个元素和文章前面所创建的元素一样能够被拖动。
5.2.然后我们检查鼠标是否存在于当前集合中每个容器中。
5.2.1.如果鼠标在某个容器中,我们检查容器中的每个元素,查看我们正拖动的元素属于哪个位置。
5.2.2.然后我们将所拖动的元素放置在容器中另一个元素的前面,或容器的最后位置。
5.2.3.最后我们确定元素可见。
6.剩下的事情就是捕获mouseUp事件:
6.1.首先需要隐藏dragHelper:它不再被需要,因为我们没有拖动任何东西。
6.2.如果拖动的元素是可见的,它已经存在于任何它所属的容器中,所有工作已完成。
6.3.如果拖动的元素不可见,我们将它放回它原来所在的地方。
//
iMouseDown represents the current mouse button state: up or down
/**/ /**/ /**/ /*
lMouseState represents the previous mouse button state so that we can
check for button clicks and button releases:
if(iMouseDown && !lMouseState) // button just clicked!
if(!iMouseDown && lMouseState) // button just released!
*/
var mouseOffset = null ;
var iMouseDown = false ;
var lMouseState = false ;
var dragObject = null ;
// Demo 0 variables
var DragDrops = [];
var curTarget = null ;
var lastTarget = null ;
var dragHelper = null ;
var tempDiv = null ;
var rootParent = null ;
var rootSibling = null ;
Number.prototype.NaN0 = function () { return isNaN( this ) ? 0 : this ;}
function CreateDragContainer() {
/**/ /**/ /**/ /*
Create a new "Container Instance" so that items from one "Set" can not
be dragged into items from another "Set"
*/
var cDrag = DragDrops.length;
DragDrops[cDrag] = [];
/**/ /**/ /**/ /*
Each item passed to this function should be a "container". Store each
of these items in our current container
*/
for ( var i = 0 ; i < arguments.length; i ++ ) {
var cObj = arguments[i];
DragDrops[cDrag].push(cObj);
cObj.setAttribute('DropObj', cDrag);
/**/ /**/ /**/ /*
Every top level item in these containers should be draggable. Do this
by setting the DragObj attribute on each item and then later checking
this attribute in the mouseMove function
*/
for ( var j = 0 ; j < cObj.childNodes.length; j ++ ) {
// Firefox puts in lots of #text nodesskip these
if (cObj.childNodes[j].nodeName == '#text') continue ;
cObj.childNodes[j].setAttribute('DragObj', cDrag);
}
}
}
function mouseMove(ev) {
ev = ev || window.event;
/**/ /**/ /**/ /*
We are setting target to whatever item the mouse is currently on
Firefox uses event.target here, MSIE uses event.srcElement
*/
var target = ev.target || ev.srcElement;
var mousePos = mouseCoords(ev);
// mouseOut event - fires if the item the mouse is on has changed
if (lastTarget && (target !== lastTarget)) {
// reset the classname for the target element
var origClass = lastTarget.getAttribute('origClass');
if (origClass) lastTarget.className = origClass;
}
/**/ /**/ /**/ /*
dragObj is the grouping our item is in (set from the createDragContainer function).
if the item is not in a grouping we ignore it since it can't be dragged with this
script.
*/
var dragObj = target.getAttribute('DragObj');
// if the mouse was moved over an element that is draggable
if (dragObj != null ) {
// mouseOver event - Change the item's class if necessary
if (target != lastTarget) {
var oClass = target.getAttribute('overClass');
if (oClass) {
target.setAttribute('origClass', target.className);
target.className = oClass;
}
}
// if the user is just starting to drag the element
if (iMouseDown && ! lMouseState) {
// mouseDown target
curTarget = target;
// Record the mouse x and y offset for the element
rootParent = curTarget.parentNode;
rootSibling = curTarget.nextSibling;
mouseOffset = getMouseOffset(target, ev);
// We remove anything that is in our dragHelper DIV so we can put a new item in it.
for ( var i = 0 ; i < dragHelper.childNodes.length; i ++ ) dragHelper.removeChild(dragHelper.childNodes[i]);
// Make a copy of the current item and put it in our drag helper.
dragHelper.appendChild(curTarget.cloneNode( true ));
dragHelper.style.display = 'block';
// set the class on our helper DIV if necessary
var dragClass = curTarget.getAttribute('dragClass');
if (dragClass) {
dragHelper.firstChild.className = dragClass;
}
// disable dragging from our helper DIV (it's already being dragged)
dragHelper.firstChild.removeAttribute('DragObj');
/**/ /**/ /**/ /* </sp>
/**/ /**/ /**/ /*
lMouseState represents the previous mouse button state so that we can
check for button clicks and button releases:
if(iMouseDown && !lMouseState) // button just clicked!
if(!iMouseDown && lMouseState) // button just released!
*/
var mouseOffset = null ;
var iMouseDown = false ;
var lMouseState = false ;
var dragObject = null ;
// Demo 0 variables
var DragDrops = [];
var curTarget = null ;
var lastTarget = null ;
var dragHelper = null ;
var tempDiv = null ;
var rootParent = null ;
var rootSibling = null ;
Number.prototype.NaN0 = function () { return isNaN( this ) ? 0 : this ;}
function CreateDragContainer() {
/**/ /**/ /**/ /*
Create a new "Container Instance" so that items from one "Set" can not
be dragged into items from another "Set"
*/
var cDrag = DragDrops.length;
DragDrops[cDrag] = [];
/**/ /**/ /**/ /*
Each item passed to this function should be a "container". Store each
of these items in our current container
*/
for ( var i = 0 ; i < arguments.length; i ++ ) {
var cObj = arguments[i];
DragDrops[cDrag].push(cObj);
cObj.setAttribute('DropObj', cDrag);
/**/ /**/ /**/ /*
Every top level item in these containers should be draggable. Do this
by setting the DragObj attribute on each item and then later checking
this attribute in the mouseMove function
*/
for ( var j = 0 ; j < cObj.childNodes.length; j ++ ) {
// Firefox puts in lots of #text nodesskip these
if (cObj.childNodes[j].nodeName == '#text') continue ;
cObj.childNodes[j].setAttribute('DragObj', cDrag);
}
}
}
function mouseMove(ev) {
ev = ev || window.event;
/**/ /**/ /**/ /*
We are setting target to whatever item the mouse is currently on
Firefox uses event.target here, MSIE uses event.srcElement
*/
var target = ev.target || ev.srcElement;
var mousePos = mouseCoords(ev);
// mouseOut event - fires if the item the mouse is on has changed
if (lastTarget && (target !== lastTarget)) {
// reset the classname for the target element
var origClass = lastTarget.getAttribute('origClass');
if (origClass) lastTarget.className = origClass;
}
/**/ /**/ /**/ /*
dragObj is the grouping our item is in (set from the createDragContainer function).
if the item is not in a grouping we ignore it since it can't be dragged with this
script.
*/
var dragObj = target.getAttribute('DragObj');
// if the mouse was moved over an element that is draggable
if (dragObj != null ) {
// mouseOver event - Change the item's class if necessary
if (target != lastTarget) {
var oClass = target.getAttribute('overClass');
if (oClass) {
target.setAttribute('origClass', target.className);
target.className = oClass;
}
}
// if the user is just starting to drag the element
if (iMouseDown && ! lMouseState) {
// mouseDown target
curTarget = target;
// Record the mouse x and y offset for the element
rootParent = curTarget.parentNode;
rootSibling = curTarget.nextSibling;
mouseOffset = getMouseOffset(target, ev);
// We remove anything that is in our dragHelper DIV so we can put a new item in it.
for ( var i = 0 ; i < dragHelper.childNodes.length; i ++ ) dragHelper.removeChild(dragHelper.childNodes[i]);
// Make a copy of the current item and put it in our drag helper.
dragHelper.appendChild(curTarget.cloneNode( true ));
dragHelper.style.display = 'block';
// set the class on our helper DIV if necessary
var dragClass = curTarget.getAttribute('dragClass');
if (dragClass) {
dragHelper.firstChild.className = dragClass;
}
// disable dragging from our helper DIV (it's already being dragged)
dragHelper.firstChild.removeAttribute('DragObj');
/**/ /**/ /**/ /* </sp>
发表评论
-
小议final关键字
2005-10-28 21:50 1768作者:Flyingis final是Java语言中一 ... -
多态学习心得
2005-10-31 19:28 1267作者:Flyingis 这几天我在重新复习Java语言基 ... -
Java接口特性学习
2005-11-02 21:18 1176作者:Flyingis 在Jav ... -
理解Java内部类的基本特性(一)
2005-11-04 17:11 1419作者:Flyingis 内部类是Java语言一个 ... -
理解Java内部类的基本特性(二)
2005-11-04 18:55 1291作者:Flyingis4. 内部类拥有其外围类的所有元素的访 ... -
JSF VS Tapestry 全面比较
2005-11-09 13:08 1241作者:Flyingis Java不像微软拥有Vi ... -
Hibernate学习心得--性能优化
2005-11-15 10:22 1330作者:Flyingis 在使用Hiber ... -
Struts Action的多种角色
2005-11-18 17:10 1244作者:Flyingis ... -
中国企业对软件人才利用的思考
2005-11-21 14:08 1165作者:Flyingis 刚刚看到一篇文章《中方落 ... -
关键字new和newInstance方法区别
2005-12-03 16:48 1201作者:Flyingis 在初始化一个类,生成一个 ... -
Google的Offer
2005-12-07 15:05 1298作者:Flyingis 昨 ... -
Google新服务--出行路线规划服务
2005-12-09 20:04 1505作者: ... -
浅议类型识别与反射机制
2005-12-11 14:43 981作者:Flyingis 运行时类型识别(Run- ... -
ClassCastException深入分析
2005-12-18 18:57 1192作者:Flyingis ClassCastExcep ... -
热点讨论--"Java? It's So Nineties"
2005-12-18 19:32 920作者:Flyingis贴一则消息。今天在各大网站上都 ... -
Java容器分析--List和Set
2005-12-21 15:06 821作者:Flyingis 容器类可以大大提高编程 ... -
GIS数据建库基本思想(上)
2005-12-22 18:43 1227地理信息系统的建设中,数据库的建设极为重要,基础地形 ... -
GIS数据建库基本思想(下)
2005-12-25 15:24 1332GIS数据建库基本思想(上) ... -
Java容器分析--Map
2005-12-27 10:07 1031作者:Flyingis标准的Java类库中包含了几种类 ... -
Java I/O中的设计模式
2005-12-30 21:47 986作者:Flyingis 任何程序语言的I/O设计都是一项 ...
相关推荐
在"ExtJS4官方指南翻译:DragandDrop拖放/Grid组件/Tree组件/容器与布局"中,我们将会探讨以下几个核心概念: 1. **Drag and Drop(拖放)**: ExtJS4提供了完善的拖放支持,允许用户通过鼠标操作在界面上移动元素...
这个库专注于易用性、性能和无障碍性,使得在React应用中实现拖放操作变得简单而优雅。 `react-beautiful-dnd`的设计目标是提供一种直观的方式,让用户可以通过鼠标或触摸设备轻松地重新排序列表项目。它支持各种...
在电商应用中,实现类似购物车的拖放功能是常见的需求。以下展示了如何创建一个简单的购物车: ```html <!-- 产品列表 --> <!-- 购物车内容 --> ``` 产品列表由 `ul` 元素中的 `li` 元素表示,每个产品包括...
在这个“ASP.NET客户关系管理系统的实现”项目中,开发者利用ASP.NET技术来设计并实现了客户关系管理系统(CRM),这是一套用于企业管理和维护客户关系的重要工具。 CRM系统的主要目标是通过收集、分析、组织和利用...
10. **拖放功能**:HTML5的拖放API使得用户可以方便地在网页元素之间拖放内容,无需复杂的JavaScript实现。 这个资源包可能包含了这些功能的实例代码,帮助开发者了解和学习如何在实际项目中应用HTML5。通过`code1`...
在本资源包“翻译翻译什么叫HTML5(四)配套资源”中,很可能包含了关于HTML5的深入讲解、示例代码、教程或者相关练习,帮助用户更好地理解和掌握这一技术。 HTML5的核心特性包括: 1. **语义化标签**:HTML5引入了...
4. **AJAX(Asynchronous JavaScript and XML)**:ASP.NET支持AJAX,允许创建异步的、部分刷新的用户界面,提高用户体验,特别是在数据密集型的CRM系统中。 5. **安全性**:ASP.NET内置的安全特性包括身份验证、...
在实现网络商店的过程中,安全性是一个关键考虑因素。ASP.NET提供了内置的安全性机制,如身份验证、授权和会话管理。开发者可能使用Forms Authentication进行用户登录验证,并设置角色权限,以限制不同用户对资源的...
该压缩包"js弹出可拖动计算器代码.zip"包含了一个实用的JavaScript实现的可拖动计算器代码。这个计算器不仅能够进行基本的计算操作,还具有动态效果和用户交互功能,使得它在网页中可以作为一个方便的小工具使用。...
6. **AJAX技术**:为了提高用户体验,可能使用了AJAX(异步JavaScript和XML)技术,使得用户在不刷新整个页面的情况下能获取数据和更新内容。 7. **翻译API集成**:若系统具备翻译功能,可能使用了第三方翻译API,...
在Web开发中,日历插件是一种常见的用户交互元素,尤其对于日程管理、时间预约等应用场景尤为重要。jQuery WeekCalendar是一款强大的周历插件,它允许用户直观地查看和管理一周的日程。本文将详细介绍如何对这个插件...
在网站中应用CSS,可实现页面的统一风格,提升视觉效果。 #### 3.2 应用JavaScript设计网页 JavaScript是一种脚本语言,它的出现让网页从静态展示转变为动态交互,增强了用户体验。通过JavaScript,网页可以实时...
在国际化(i18n)开发中,这种JSON文件通常用于存储不同语言环境下的字符串资源,便于程序根据用户设置的语言加载相应的翻译。通过修改和更新en.json,开发者或用户可以实现Activiti界面的中文显示,使得中国用户...
React DND(Drag and Drop)中文文档主要涵盖了在React应用中实现拖放功能的相关知识点。React DND是一个流行的JavaScript库,它使得在React组件中添加拖放行为变得简单且直观。下面将详细介绍这个库的核心概念、...
这个文件包含了所有EXT JS组件和方法的中文翻译,通过在应用程序中引用这个文件,可以将EXT JS的默认英文界面转换为中文。使用时,开发者通常会在EXT JS的初始化代码中指定这个语言文件,例如: ```javascript Ext....
js拖拽的时候,发现了一个强大而又灵活的拖拽框架,(之前用了代码混淆器,还好代码比较短,我就翻译过来了)利用这个框架不仅能实现简单的拖动,更能轻易的实现各种复杂的拖放功能。这一篇先实现最简单的拖拽,稍微...
在这里,JavaScript作为后端处理语言,负责处理拖放事件中的翻译逻辑。 4. **翻译API**:QT-Drag-Translator可能使用了某种在线翻译服务的API,如Google Translate API或Bing Translator API,来实现翻译功能。这些...
虽然标题提到的是3.3版本,但很可能是文档更新到3.2版本时的中文翻译,而3.3的更新可能在英文版中。CHM文件是Windows系统的帮助文档格式,包含索引、搜索和目录等功能,方便用户查找和学习。 下面将详细讲解ExtJS ...
在这个播放器中,可能被用来实现弹幕的多语言翻译,使得不同地区的观众能理解其他用户的弹幕内容,增加互动性。 5. **图灵机器人API**: 图灵机器人API提供智能对话功能,能够处理自然语言并与用户进行交互。在斗鱼...