Brython 拖放(Drag and Drop)实战:基于 HTML5 规范的元素拖拽实现指南
编程语言语言运行时编译器前端【免费下载链接】brythonBrython (Browser Python) is an implementation of Python 3 running in the browser项目地址https://gitcode.com/gh_mirrors/br/brython点击查看免费下载导读本文基于 Brython 官方 Cookbook 中的拖放示例法文版、英文版系统讲解如何在浏览器中用 Python 实现元素的拖放交互。BrythonBrowser Python是在浏览器中运行的 Python 3 实现它把 HTML5 的拖放 API 封装成贴合 Python 习惯的接口。读完本文你将掌握dragstart/dragover/drop三个核心事件的回调绑定、通过dataTransfer在拖放过程中传递数据、以及用unbind卸载事件回调的完整套路可直接照搬到自己的页面项目中。问题在网页上拖放一个元素拖放Drag and Drop是网页交互中的常见需求用户按住一个元素源把它移动到另一个区域目标松开鼠标完成放置。在 Brython 中实现这一行为并不需要写一行 JavaScript——全部逻辑都可以用 Python 表达由 Brython 运行时负责与浏览器底层 API 对接。解决方案基于 HTML5 规范的 Brython 拖放 APIBrython 实现了一套基于 HTML5 拖放规范的 API详见官方事件文档 drag_events.md。在本文示例的基础形态下只需要为 3 个事件定义回调函数事件绑定的元素触发时机dragstart可拖动的源元素用户开始拖动该元素时dragover目标区域被拖动的元素移动到目标区域上方时drop目标区域用户松开鼠标完成放置时把回调函数callback绑定到元素element的某个event上使用的方法是element.bind(event, callback)注原文档正文用斜体表示的_event_、_element_、_rappel_等标识符在代码中即对应事件名如dragstart、元素对象DOMNode实例与回调函数。回调函数的签名与数据传递每个回调函数只接收一个参数一个DOMEvent实例即浏览器原生事件对象的 Brython 封装。为了在拖放过程中传递信息该实例带有一个dataTransfer属性在dragstart回调中通过ev.dataTransfer.setData(text, 值)写入数据在drop回调中通过ev.dataTransfer.getData(text)读取数据从而识别当前被放置的是哪个元素。这一机制对应 HTML5 规范中的DataTransfer对象setData/getData负责携带数据effectAllowed声明源元素允许的操作如movedropEffect声明目标区域最终采用的操作效果。官方文档 drag_events.md 对此有更完整的字段说明例如对dragstart、drag、dragleave事件dropEffect初始为none且赋值不生效对drop、dragend事件dropEffect会被初始化为最后一次dragover结束时设定的值。放置后禁止再次拖动unbind示例中还演示了一个常见业务规则对象被放置后就不能再被拖动。做法是通过element.unbind(event)移除该元素上已绑定的回调elt.unbind(mouseover)完整示例把红色方块拖入绿色区域下面是原文档的完整可运行代码HTML 中通过exec_on_load指令在页面加载时执行。先把两个块定位在黄色面板内红色块为可拖动对象绿色块为放置目标。div stylewidth:400px;height:150px;background-color:yellow idpanel div iddest styleposition:absolute;width:180px;height:80px;background-color:green;color:white;zone de destination/div div idsource styleposition:absolute;width:80px;height:40px;background-color:red;objet déplaçable/div /divfrom browser import document panel document[panel] # zone jaune source document[source] # zone rouge # on la place à (10, 10) du bord supérieur gauche du panel source.style.top {}px.format(10 panel.abs_top) source.style.left {}px.format(10 panel.abs_left) # rend la zone rouge déplaçable source.draggable True dest document[dest] # zone verte # on la place à (10, 150) du bord supérieur gauche du panel dest.style.top {}px.format(10 panel.abs_top) dest.style.left {}px.format(150 panel.abs_left) # coordonnées de la souris relativement au bord supérieur gauche de lobjet # déplacé quand le glissement commence m0 [None, None] def mouseover(ev): Quand la souris passe sur lobjet déplaçable, changer le curseur. print(voilà la souris !) ev.target.style.cursor pointer source.bind(mouseover, mouseover) def dragstart(ev): Fonction appelée quand lutilisateur commence à déplacer lobjet. global m0 # calcul des coordonnées de la souris # ev.x et ev.y sont les coordonnées de la souris quand lévénement est déclenché # ev.target est lobjet déplacé. Ses attributs left et top sont des entiers, # la distance par rapport aux bords gauche et supérieur du document m0 [ev.x - ev.target.left, ev.y - ev.target.top] # associer une donnée au processus de glissement ev.dataTransfer.setData(text, ev.target.id) # permet à lobject dêtre déplacé dans lobjet destination ev.dataTransfer.effectAllowed move source.bind(dragstart, dragstart) def dragover(ev): Fonction appelée quand lobjet déplaçable vient au-dessus de la zone de destination. ev.dataTransfer.dropEffect move # il faut désactiver le comportement par défaut pour ce genre dévénement ev.preventDefault() dest.bind(dragover, dragover) def drop(ev): Fonction attachée à la zone de destination. Elle définit ce qui se passe quand lobjet est déposé, cest-à-dire quand lutilisateur relâche la souris alors que lobjet est au-dessus de la zone. # récupère les données stockées dans drag_start (lid de lobjet déplacé) src_id ev.dataTransfer.getData(text) elt document[src_id] # définit les nouvelles coordonnées de lobjet déplacé elt.style.left {}px.format(ev.x - m0[0]) elt.style.top {}px.format(ev.y - m0[1]) # ne plus déplacer lobjet elt.draggable False # enlever la fonction associée à mouseover elt.unbind(mouseover) elt.style.cursor auto ev.preventDefault() dest.bind(drop, drop)逐段拆解代码背后的关键机制1. 元素定位abs_top与abs_left示例没有使用 CSS 静态定位而是用panel.abs_top和panel.abs_left获取面板左上角相对文档的绝对坐标再把红色块放在(10, 10)、绿色块放在(150, 10)。这两个属性是 Brython 为DOMNode提供的只读扩展属性其取值直接来自内部函数$getPosition(self)返回的left/top即元素相对文档的像素偏移见 brython.js 中abs_left_get/abs_top_get的实现。使用绝对坐标而非固定像素值可以保证示例在页面滚动或布局变化时依然定位正确。2. 让元素可拖动draggable属性source.draggable Truedraggable是 HTML5 拖放规范定义的布尔属性。只有设置为True元素才能被浏览器识别为可拖动的源。Brython 的DOMNode把该原生属性直接暴露给 Python设置后即生效。3. 鼠标偏移量实现跟手拖动dragstart回调中记录了鼠标按下位置相对元素左上角的偏移m0 [ev.x - ev.target.left, ev.y - ev.target.top]其中ev.x、ev.y是事件触发时鼠标的坐标ev.target是被拖动的元素其left、top属性是相对文档左、上边界的整数距离。在drop回调中把鼠标当前位置减去该偏移就能让元素跟手地落在鼠标松开的位置elt.style.left {}px.format(ev.x - m0[0]) elt.style.top {}px.format(ev.y - m0[1])注意这里存储的是列表m0跨回调共享因此drop中才需要在dragstart中声明global m0。4.dataTransfer的角色与preventDefaultdragstart中ev.dataTransfer.setData(text, ev.target.id)把源元素的id写入拖放数据ev.dataTransfer.effectAllowed move声明允许移动操作dragover中ev.dataTransfer.dropEffect move指定目标侧的操作效果。关键的是必须调用ev.preventDefault()HTML5 规范规定dragover的默认行为是拒绝放置只有阻止默认行为drop事件才会被触发drop中ev.dataTransfer.getData(text)取回源元素id再通过document[src_id]取回该元素完成重定位。5. 放置后禁止再拖unbind的两种用法drop回调最后执行了三步收尾elt.draggable False # 禁止再次拖动 elt.unbind(mouseover) # 卸载鼠标悬停回调 elt.style.cursor auto # 恢复默认光标unbind是本例最有价值的细节它演示了事件生命周期的管理。查看运行时源码 brython.jsDOMNode.unbind支持两种调用形态element.unbind(event)移除该事件上的全部回调并把内部$events[event]置空element.unbind(event, func)只移除指定的回调函数若该回调不存在会抛出TypeError提示missing callback for event ...。与之对称bind的实现brython.js会为每个 Python 回调包装一个 JS 包装函数把原生事件转换为DOMEvent实例后调用 Python 函数并将配对关系登记在元素内部的$events表中这正是unbind能精准移除回调的基础。此外bind还支持第三个可选参数options可以是布尔值或字典会原样传给浏览器原生的addEventListener如capture等选项。延伸bind的更多形态与配套 API除了元素方法element.bind(event, callback)Brython 的browser模块还提供了模块级函数bind对应 brython.js 中browser.bind的实现它接收(elt, evt, options)返回一个装饰器风格的函数可直接用于装饰回调函数且能接受元素 id 字符串、DOMNode、JSObj或可迭代元素集合方便批量绑定from browser import bind bind(#source, dragstart) def dragstart(ev): ...配合本文示例还经常用到以下DOMNode扩展 API同样定义于 brython.jselement.bindings()返回字典列出该元素各事件当前绑定的 Python 回调列表见 brython.jselement.events(event)返回指定事件下已绑定的回调列表见 brython.jselement.trigger(event)手动触发一个事件见 brython.js。这些 API 可用于调试或实现更复杂的交互编排例如在drop前用bindings()检查是否已绑定过处理函数。动手实践建议直接运行把上面的 HTML exec_on_load代码块保存为.html在浏览器中打开本地file://或通过项目仓库的 server.py / server_aiohttp.py 启动 HTTP 服务均可。改造练习把drop回调中elt.draggable False和elt.unbind(mouseover)两行注释掉观察差异——元素被放置后仍可再次拖动mouseover每次经过都会打印提示直观体会unbind的作用。数据扩展setData的类型参数目前使用text可按需携带更多信息如多个id、坐标快照等实现多元素拖放排序、拖放进购物车等进阶场景。小结Brython 把 HTML5 拖放规范封装成了简洁的 Python 接口三个事件dragstart、dragover、drop加上bind/unbind两个方法配合dataTransfer的数据通道即可完成完整的拖放交互。示例中还展示了元素绝对定位abs_top/abs_left、鼠标偏移计算、draggable开关等实用技巧这些模式同样适用于 Brython 的其它 DOM 交互开发。更多事件类型与DataTransfer字段的完整说明可继续查阅 drag_events.md。赞分享编程语言语言运行时编译器前端【免费下载链接】brythonBrython (Browser Python) is an implementation of Python 3 running in the browser项目地址https://gitcode.com/gh_mirrors/br/brython点击查看免费下载相关推荐Brython 拖放Drag and Drop实战基于 HTML5 拖放规范的浏览器端 Python 实现Brython 拖放Drag and Drop实战基于 HTML5 拖放规范的浏览器端 Python 实现 本篇技术指南聚焦 BrythonBrowse编程语言语言运行时编译器前端Brython 实现 HTML5 拖放Drag and Drop基于 bind/unbind 与 dataTransfer 的完整实战Brython 实现 HTML5 拖放Drag and Drop基于 bind/unbind 与 dataTransfer 的完整实战 本文以 Bryth编程语言语言运行时编译器前端惠普OMEN性能终极解锁OmenSuperHub深度调优完全指南惠普OMEN性能终极解锁OmenSuperHub深度调优完全指南 OmenSuperHub是一款专为惠普OMEN/光影精灵游戏本设计的第三方控制台通过深度硬桌面应用硬件开发上一篇Virtual-Display-Driver终极指南Windows虚拟显示器驱动源码深度解析下一篇OmenSuperHub惠普游戏本性能控制的终极开源解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

openJiuwen agent-core 加密解密抽象层详解:CryptUtils 注册表与 AES-256-GCM 实战指南

openJiuwen agent-core 加密解密抽象层详解:CryptUtils 注册表与 AES-256-GCM 实战指南

人工智能AI AgentAgent 框架大模型工具调用RAG提示工程强化学习 【免费下载链接】agent-core openJiuwen agent-core可提供AI Agent开发、运行、调优与演进相关的全套SDK能力 项目地址: https://gitcode.com/openJiuwen/agent-core 点击查看 免费下载 本篇技术指南…

2026/10/9 1:30:01 阅读更多 →
jstips 實戰:在 JavaScript 陣列中插入元素,push、unshift、splice 與 concat 的效能對比指南

jstips 實戰:在 JavaScript 陣列中插入元素,push、unshift、splice 與 concat 的效能對比指南

教程 【免费下载链接】jstips This is about useful JS tips! 项目地址: https://gitcode.com/gh_mirrors/js/jstips 点击查看 免费下载 本篇為 jstips 開源專案的第一篇技巧(Tip 00),主題是「在既有陣列中插入新元素」的各種寫法…

2026/10/9 1:30:01 阅读更多 →
Zeek 的 Linux SLL2(Linux Cooked Capture v2)链路层解析器:源码剖析与实战配置

Zeek 的 Linux SLL2(Linux Cooked Capture v2)链路层解析器:源码剖析与实战配置

网络安全网络IDS 【免费下载链接】zeek Zeek is a powerful network analysis framework that is much different from the typical IDS you may know. 项目地址: https://gitcode.com/gh_mirrors/ze/zeek 点击查看 免费下载 本指南以 Zeek 仓库中 linux_sll2 包文…

2026/10/9 1:29:00 阅读更多 →

最新新闻

Weave Net Fast Datapath 加密实现详解:基于 XFRM 的 ESP 传输模式与 AES-GCM

Weave Net Fast Datapath 加密实现详解:基于 XFRM 的 ESP 传输模式与 AES-GCM

网络云原生 【免费下载链接】weave Simple, resilient multi-host containers networking and more. 项目地址: https://gitcode.com/gh_mirrors/weave4/weave 点击查看 免费下载 本文深入解析 Weave Net 中 fast datapath(快速数据通路,基于…

2026/10/9 2:05:22 阅读更多 →
ROS2 Humble实战开发:Python/C++双栈与Linux底层协同

ROS2 Humble实战开发:Python/C++双栈与Linux底层协同

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 2:05:22 阅读更多 →
GLM-5.3-Flash 实战解析:更快更省的API大模型调用与成本优化

GLM-5.3-Flash 实战解析:更快更省的API大模型调用与成本优化

智谱推出 GLM-5.3-Flash:更快、更省的 API 大模型实战解析最近看到智谱 AI 开放平台上线了 GLM-5.3-Flash 模型,官方给出的关键词是“faster and cheaper”,也就是更快、更便宜。这个定位非常明确,就是奔着高并发、低成本、大规模…

2026/10/9 2:05:22 阅读更多 →
RISC-V内存子系统六大核心机制实操解析

RISC-V内存子系统六大核心机制实操解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 2:05:22 阅读更多 →
CATIA CAA代码资源实战:从获取、整理到构建的完整落地指南

CATIA CAA代码资源实战:从获取、整理到构建的完整落地指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/9 2:05:22 阅读更多 →
Hyperf WebSocket Server 完整实战指南:从服务注册、握手路由到跨进程消息推送

Hyperf WebSocket Server 完整实战指南:从服务注册、握手路由到跨进程消息推送

后端Web框架微服务RPC框架异步编程 【免费下载链接】hyperf 🚀 A coroutine framework that focuses on hyperspeed and flexibility. Building microservice or middleware with ease. 项目地址: https://gitcode.com/hyperf/hyperf 点击查看 免费下载 …

2026/10/9 2:04:22 阅读更多 →

日新闻

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API实战:LocalDate、Date与ZonedDateTime的转换与避坑指南

Java时间API这个话题,隔三差五就会在群里被翻出来讨论一次。上周还有个同事线上处理一个订单超时问题,排查到最后发现是ZonedDateTime序列化后时区丢了,用户在下单当天晚上看到的时间整整差了8个小时。这类问题几乎每个做Java开发的人都遇到过…

2026/10/9 0:00:49 阅读更多 →
EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

EasyTier实践:从NAT穿透到子网代理的异地组网部署与排错

前几个月我手头有好几台机器需要互相访问:办公室台式机、家里 NAS、还有一台云主机。如果只是偶尔传个文件倒还好,问题是工作场景经常要在几处环境之间来回切换,每次都先登录跳板机再层层代理,实在折腾。我先后试过端口映射、自建…

2026/10/9 0:00:49 阅读更多 →
AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent工程实战:从七要素到七个决策点的系统设计指南

AI Agent 这个词在过去一年里被反复提及,但真正动手搭过一套能跑起来的 Agent 系统的人都知道,从"知道它是什么"到"让它稳定干活"之间隔着一整套工程决策。我前后参与过几个 Agent 项目的落地,从最初用现成框架拼装&…

2026/10/9 0:01:50 阅读更多 →

周新闻

KT148A语音芯片外挂8002D功放的工程实践指南

KT148A语音芯片外挂8002D功放的工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:32 阅读更多 →
LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

LLC谐振变换器增益公式推导:从FHA等效到完整归一化表达式

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:40 阅读更多 →
ARM架构深度解析:从RISC设计理念到交叉编译实战

ARM架构深度解析:从RISC设计理念到交叉编译实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 10:10:36 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 21:13:17 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/8 15:26:17 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/7 13:34:55 阅读更多 →