用dojo.dnd实现拖放功能

STM32 使用rtthread的DMA 串口发送失败 在一次使用RTthread的DMA 串口发送时,持续性通过DMA 发送串口数据时,偶发发送过程中后续数据包无法正常发送出去,后经查,发现为RT-Thread的串口中断处理有瑕疵,后做出修改。另,为了更方便的排查为题,建议修改。左为修改前,右为修改后。 阅读详情

用dojo.dnd实现拖放功能

 

相信很多人都自己动手写过拖放。DHTML里做拖放的原理很简单,一般有这么三个阶段:mousedown 的时候做一些初始化, mousemove 的时候更新拖放对象的位置, mouseup 的时候再做一些清理工作。讲起来简单,但做起来总要花一些功夫的。 Dojo 的 dnd 模块提供了通用且功能强大的拖放支持,让我们可以不用自己造轮子,而且用起来也很方便。

废话少说,先来看看它到底有多方便。假设页面上有两个ul ,我们需要对 ul 里的 li 元素实现拖放,让它们可以自由地在两个列表间移动。如果自己手写,虽然不难但也要花点时间吧。用 Dojo 的话,除了加载模块之外,甚至连一行 javascript 语句都不需要:

 

这个例子用了host在google的dojo1.5版本,可以直接运行。这里唯一需要写的javascript 语句就是加载 dojo.dnd.Source 类。剩下的就是在要拖放的对象上做一些标记,用html和 CSS class 就行了。而且 Dojo 为拖放对象添加的 CSS class 非常丰富,让我们能自由定制它们的外观。

 

Fig.1: Source内部DnD

Fig.2: Source之间DnD

Fig.3: 在无法接受拖放内容的地方改变Avatar的外观

 

好,现在来仔细看一下dojo.dnd 模块到底是怎么一回事。

 

dojo.dnd包结构

打开dojo/dnd 源码文件夹,可以看到里面有很多东西:

Fig.4: dojo.dnd的目录结构

 

刚才用的 dojo.dnd.Source 就在Source.js里面。顾名思义, Source 就是拖放源,一个存放可拖放对象的容器。相对的还有 dojo.dnd.Target(也在Source.js里) ,它继承了 dojo.dnd.Source ,不过只能接受从别处拖过来的东西,却不能拖出去。另一个Source的子类是AutoSource,如果你需要在运行时添加可拖放的结点(实时更新可拖放结点列表),那么它就是为你准备的。

Dojo.dnd 包中的几个主要类之间的关系大致是这样:

Fig.5: DnD包中主要类的结构

 

其中Container 是顶层基类,它的实例包含有一些子元素,能感知 onmouseover/onmouseout 事件,并且知道具体 over 的是哪个元素。 Selector 是 Container 的子类,让容器支持鼠标选择,可以支持单选或多选。 Avatar 就是在拖放时跟着鼠标跑的那个东西,一般会直接包含拖放对象的 dom 结点。而 Manager (是一个 Singleton )则统筹了整个 dnd 过程,管理拖放的起点和终点,以及负责创建、更新和销毁 Avatar 。

包里剩下的东西其实组成了一个子模块: dojo.dnd.move ,如果你只是需要把某个 dom 结点拖来拖去,就应该用这个模块。这里只介绍 dojo.dnd ,以后再写 dojo.dnd.move 。

 

dojo.dnd工作流程

当你在要拖动的对象上按住鼠标左键并开始移动时,Source 会调用 Manager.startDrag 函数,标志拖放过程的开始。这个函数记录当前发起拖放的 Source 和拖放的结点,然后创建出 Avatar ,建立起一切必要的事件关联,并发布( dojo.publish )一个“开始拖放”( /dnd/start )的主题( topic )。 Dojo.dnd 里广泛采用主题广播的方式管理拖放过程,这样页面上所有的 Source 都能监听这些主题并作出反应。例如这个 /dnd/start 主题发布后,页面上所有的 Source (包括刚才拖出来的那个)都将检查自己是否能够接受那些正在被拖动的结点(通过一个叫 checkAcceptance 的方法)。

这里有必要提一下默认的检查方法。Source 有一个属性叫 accept ,这是一个字符串数组,默认是 ["text"] ,表示这个 Source 能够接受的东西只限于包含文本的结点。你可以自由定义 accept 里的内容,这将在下一节具体解释。

当这些结点被拖到一个Source 上时( onmouseover ),将使 Manager 发布 /dojo/source/over 主题,更新 Avatar 上的图标,以反映是否能在这个 Source 上 Drop 。

当你释放鼠标的时候,首先触发Manager 对 onmouseup 事件的响应函数。这个函数将判断当前是否有 Source 能够接受拖放的内容,如果有,就发布 /dnd/drop/before 以及 /dnd/drop 主题;如果没有,就发布 /dnd/cancel 主题。然后销毁 Avatar 、事件句柄、以及所有与本次拖放相关的信息。所有的 Source 都会监听这些主题,并作出相应的应对。

如果某个Source 在响应/dnd/drop主题时发现自己就是 Drop 的目标,就把这次拖放的结点传给一个叫 _normalizedCreator 的私有方法,该方法负责把这些结点转换成自己可以接受的形式。这里其实有一个定制点,让用户自定义转换的方式,这也将在下一节讲到。最后 insertNodes 方法把这些新结点插进来。如果做的是“移动”而不是“复制”(拖动时按住CTRL就是复制),还需要通知作为拖放起点的 Source 删除那些拖出来的子结点。


定制dojo.dnd

定制dojo.dnd 的基本方式和 dijit 类似,就是在构造函数中传入参数对象。如果是声明式创建,就可以直接用 html 属性的方式写在 html 元素中。 Dojo.dnd 具有非常多的定制点,一一列举会过于冗长,这里只挑最常用的几个。(当然,一旦你阅读了源码,完全可以抛开一切约束,通过继承的方式任意扩展 dojo.dnd 里的内容)

1. 首当其冲是 accept 数组,刚才已经讲到,只有和这个数组有交集的拖放源才能被接受。例如,一个 Source 的 accept 数组是 ["text", "image"] ,另一个是 ["image", "video"] ,那么这两个 Source 就能接受从对方那里拖过来的东西。你肯定会问:为什么这是一个数组而不是单个字符串?答:对不同的拖放结点可以再定制其拖放类型。例如一个 Source 里可以既有 text 类型的结点,也有 image 类型的结点,你可以通过 dndType 属性在这些结点上做标记:


这样,如果你拖的是标记为text 的 li 元素,那么那个 accept=["image", "video"] 的 Source 就无法接受它了:


Fig.6: 运用accept和dndType精确控制拖放

2. 第二重要的个人感觉就是 creator ,前面提到,通过这个函数可以任意定制拖进来的东西。这个函数接受两个参数,一个是拖进来的 dom 结点的 innerHTML (注: Container 里说这是一个形如 {data: data, type: type} 的对象,但在 Source 的实际使用中,传的仅仅是 data ),另一个叫 hint 字符串,目前据我所知其唯一的可能值是 "avatar" ,表示创建出的结点是在 Avatar 中使用的。它需要返回一个形如: {node: node, data: data, type: type} 的对象。这里的 node 可以跟传进来的那个没有半点关系。 Data 表示拖动的真正内容,一般就是 node.innerHTML 。 Type 就是这个结点的 dndType 。例如我要在传进来的内容前面加一点东西,可以这样写:


效果如图:


 

3.  一个简单但有用的开关属性:horizontal 。如果你的拖放源是一个横向容器,请把它设为 true 。

 

4.  三个很有用的且互相有关联的开关属性:copyOnly 默认 false, selfAccept 默认 true ,  selfCopy 默认 false 。顾名思义,如果 copyOnly 是 true ,那么这个 Source 里的东西只能被复制而不能被移走。当 copyOnly 是 true ,且 selfAccept 是 false 的时候,在容器内 dnd 也被禁止了。当 copyOnly 是 true , selfAccept 是 true ,且 selfCopy 是 true 的时候,容器内 dnd 的意思是复制而不是移动。


 

结语


本文很粗浅地介绍了dojo.dnd 包的基本用法,如果要深入了解,强烈建议阅读源码并不断实践。 Dojo.dnd 是 dojo 的核心组件之一,功能强大且代码优雅,相信你一定能从中学到不少东西。

 

 

 

基于 Qt C++ 的 船舶导航系统 UI 你想实现一个基于 **Qt C++** 的 **船舶导航系统 UI**,核心功能包括 **Qt Quick** 电子海图显示和 **NMEA 0183** 协议解析。"断开" : "连接"创建一个 Qt Quick 项目,选择 **Qt 6** 版本,确保勾选 **Qt Quick**、**Qt Network** 和 **Qt SQL** 模块。Label { text: "纬度:" }3. **连接设备**:点击 "连接" 按钮连接到 GPS 设备或模拟数据源。title: "连接设置" 阅读详情

相关推荐

接入穿山甲SDK时,Unity打Android包报错日志

SDK工程设置为Enable,项目工程设置为Disable。2、将unitypackage导入包名为:com.DefaultCompany.Myproject的另一个工程,打包报错。3、点击工程默认弹出Enable Android Auto-resolution 设置选项,点击Enable。1、新建一个空工程,设置包名为:com.ceshi.hewen,正常打包无报错,导出unitypackage。2、点击Reset to Defaults 重置参数,再点击ok关闭设置窗口。

不文不武的禾文 3585

详解《基于 javascript 的流程图编辑框架LogicFlow》

shortcuts 则可以定义用户自定义的一组快捷键 值得一提的是 keys 的规则,与mousetrap一致。我们已自定义删除功能为例,在删除之前添加一个确认操作。

tigerhhzz的博客 4943

Ubuntu20.04运行Vins-fusion

因已安装ROS noetic,eigen,opencv及ceres等库,这部分环境配置就不细讲,直接下载VINS-FUSION的代码库 下载编译 cd ~/vins-fusion/src git clone https://github.com/HKUST-Aerial-Robotics/VINS-Fusion.git cd ../ catkin_make source ~/catkin_ws/devel/setup.bash 编译时会发现一堆错误,别急,无非就是环境冲突问题,一个个解决 1)首先,ROS

xiaojinger_123的博客 1万+

解释下事件代理

在传统的事件处理中,你按照需要为每一个元素添加或者是删除事件处理器。然而,事件处理器将有可能导致内存泄露或者是性能下降——你用得越多这种风险就越大。JavaScript事件代理则是一种简单的技巧,通过它你可以把事件处理器添加到一个父级元素上,这样就避免了把事件处理器添加到多个子级元素上。 它是怎么运作的呢?       事件代理用到了两个在JavaSciprt事件中常被忽略的特性:事件冒泡以及

xujie_0311的专栏 4652

手把手教你用闲置安卓手机+蓝鲸支付,零成本搞定个人项目自动收款(附私有化部署教程)

本文详细介绍了如何利用闲置安卓手机和蓝鲸支付系统,零成本搭建个人项目自动收款解决方案。通过私有化部署教程,读者可以学习到从手机选择、系统配置到支付渠道对接的全流程,实现安全、高效的收款系统,特别适合个人开发者和小型项目使用。

weixin_29597551的博客 334

1998年高教社杯全国大学生数学建模竞赛 B 题:《灾情巡视路线》真题解析与 MATLAB 解决方案

🏆 本文已收录于专栏:《滚雪球学数学建模(含历年真题)》,持续更新最新及历年数学建模竞赛资料,每篇内容力求做到“问题讲透、模型讲清、代码可用、论文可参考”,帮助你从零开始逐步建立完整的数学建模知识体系。

**My Coding Family** 883

利用Dojo实现拖动(Drag and Drop)效果

如今各种使用AJAX技术的站点都实现了Drag and Drop(拖动)效果,利用Dojo框架也可以很方便的实现,相比较其它框架,代码更少,且对浏览器的兼容性支持比较好。  先看一下效果,以下是51AJAX.com站点首页的效果,其中各个模块是可以任意拖动的:    如何来实现呢?以下是具体步骤。为简单起见,做了一个Drag and Drop的Demo页面:    以下是具体步骤:  1.html

懒散狂徒的专栏 1753

第一章 EB安装

1.DemoWorkspace 是基于EB当前组件配置下的例程,包含了启动文件和中断服务函数以及组件demo。2.Mclsar 下存放的是EB的插件包和静态MCAL的驱动文件。

舊梦的博客 1963

java 拖拽_JAVA拖拽

sun在java2中引入了一些新的方法来帮助实现拖拽功能,这些新的类在java.awt.dnd包中实现一个D&D操作一般包括三个步骤:首先实现一个拖拽源,这个拖拽源和相应的组件是关联起来的第二步实现一个拖拽目标,这个目标用来实现拖拽物的接收第三步实现一个数据传输对象,该对象封装拖动的数据_____________________...

weixin_36287059的博客 510

Python爬虫实战:基于最新技术栈的政府招标采购数据抓取与分析

对于企业、研究人员和数据分析师来说,能够高效地获取这些数据意味着可以获得宝贵的商业洞察和市场先机。随着反爬技术的不断升级和网站结构的日益复杂,传统的爬虫方法已经难以满足需求。我们将采用Selenium、Playwright等现代浏览器自动化工具,结合Scrapy框架和异步请求库,构建一个能够应对各种反爬措施的强大爬虫系统。Playwright是微软开发的浏览器自动化工具,支持Chromium、WebKit和Firefox,比Selenium更快速、更稳定。

2201_76125261的博客 1312

SAP_SD模块更改销售订单定价简介

方式优点缺点适用场景MASS简单,无需开发不能触发重新定价逻辑修改特定字段BDC (VA02)可模拟人工操作维护复杂,速度慢少量订单批改稳定、安全需ABAP支持推荐用于批量重新定价VBOF标准重算返利仅适返利类条件返利更新通过本文,我们了解了 SAP 的[SAP_SD模块更改销售订单定价]的基本概念和应用方法。希望这些信息能帮助您在实际工作中更好地使用 SAP 系统,提高工作效率和管理水平。更多SAP文章请点击更多SAP文章更新,大家一起学习进步!!!

我小时候很黑的博客 714

利用Dojo进行DOM事件编程

Dojo提供了一个DOM事件框架,该框架在所有Dojo支持的浏览器中具有一致的行为。Dojo更是修复了IE免费提供的内存泄漏问题。Dojo的DOM事件框架函数与W3C DOM Level 2的事件模型(http://www.w3.org/TR/DOM-Level-2-Events/)十分相似。对于支持W3C DOM Level 2的浏览器,Dojo只是简单地把事件处理函数的关联/取消关联请求传递给

w_j_w2010的博客 663

论文阅读-Whisper语音识别(OpenAI)

Whisper 是一个自动语音识别(ASR,Automatic Speech Recognition)系统,OpenAI 通过从网络上收集了 68 万小时的多语言,其中11万小时覆盖96 种语言,12万小时的语言标号为英语,用多任务(multitask)监督数据对 Whisper 进行了训练。

一位不是很硕的鉴伪方向硕士 6366

刚才先入为主到了令人发指的地步

刚才用dojo实现一个拖放操作。在初始化拖放目标时,老是得到JavaScript错误,“Object expected”。反复检查源代码,反复调试,没发现代码问题。。。把dojo dnd 测试用例里初始化目标的代码,dojo.dnd.HtmlDropTarget,拷贝到搜索框里。嗯,居然说找不到这行语句。把这段代码和我的代码上下并列,*反复*比较,终于发现我的句子是dojo.dnd.HtmlDra...

威尔软件 99

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

dojo-dnd 拖拽功能

拖拽(dojo/dnd)作为Dojo的基础功能之一,可视化地支持页面元素或对象在多个容器之间拖放。Dojo/dnd还支持同时拖拽多个对象;另外还可以制定规则过滤拖放对象的目标容器,比如“桌子”应该被放在“家具”容器内,而不该放在“家电”容器中。下面通过一个有趣的故事,开始我们的Dojo拖拽功能实践。 单个容器内的拖拽首先来介绍一下Dylan,Dylan这家伙最大爱好就是收集二手旧货。刚才他决定把...

Zzzpiu的博客 611

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Dojo Dnd - 拖拽功能实战

本文翻译自:http://www.sitepen.com/blog/2011/12/05/dojo-drag-n-drop-redux/原文作者:Colin Snover译者:Ruan Qi 拖拽(dojo/dnd)作为Dojo的基础功能之一,可视化地支持页面元素或对象在多个容器之间拖放。Dojo/dnd还支持同时拖拽多个对象;另外还可以制定规则过滤拖放对象的目标容器,比如“桌子”应该被放在“家具

Dojo中文博客 1万+

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

dojo.dnd

[code="java"][/code][b][/b]dojo支持拖放和移动操作,在dojo中采用了如下机制 [b]拖放[/b] 在 dojo的应用中,拖放是一个比较常见的操作。拖放操作最早的时候比较多的出现在桌面应用中,在传统的 Web 应用中比较少见。随着 Ajax 应用的流行,拖放操作越来越多的出现,可以提供与桌面应用类似的用户体验。在 Ajax 应用中实现拖放操作并不是一件容易的事情,...

netliving的专栏 260

dojo dnd

Insert title here #dndOne {   width: 100px;   height: 100px;   position: absolute;    left:0;    top:0;   border: 1px solid #000;   background: red; } .dojoDndItem {

霍华德的专栏 691

学习Ajax框架之dojo:第四节——Dojo拖拽效果的实现(附源代码)

Dojo在dojo.dnd包中提供了对页面元素拖拽效果的支持,其中用于实现拖拽效果的关键类如下。 <1> dojo.dnd.HtmlDragSource <2> dojo.dnd.HtmlDragMoveSource <3> dojo.dnd.HtmlDropTarget <4> dojo.d...

aeon521730041的博客 157

dojo入门(1)

常用包介绍Dojo 1.1.1 提供了上百个包,这些包分别放入三个一级命名空间:Dojo,Dijit 和 DojoX 。其中 Dojo 是核心功能包 , Dijit 中存放的是 Dojo 所有的 Widget 组件,而 DojoX 则是一些扩展或试验功能,DojoX 中的试验功能在成熟之后有可能在后续版本中移入到 Dojo 或 Dijit 命名空间中。由于 Dojo 包种类繁多,下面只列举

一室阳光,温暖你我他! 1131

dojo1.0的dnd示例以及问题!

Dojo DnD test @import "../../resources/dojo.css"; @import "../../resources/dnd.css"; @import "dndDefault.css"; body { padding: 1em; background: #FFFFFF; } .containe...

manlibie的博客 112
上一篇: 部分Dojo常用函数简介(三)——页面生命周期及DOM相关常用函数
下一篇: 部分Dojo常用函数简介(四)——String及Array扩展
dojotoolkit
博客等级 码龄16年 1205粉丝 61原创
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值