PyScript中@when装饰器事件处理:JS转Python遇阻求助
解决PyScript中拖动输入框数值的JS转Python问题
核心问题分析
JS里直接给DOM元素添加自定义对象属性(evt.target.dragging = {dx: ...})的写法,在PyScript中无法直接运行——因为PyScript里的DOM元素是JavaScript对象的代理,Python语法不能直接给它赋值JS风格的对象属性。
修正后的代码实现
1. 两种可行的状态存储方案
方案一:用DOM自定义属性存储状态
把拖动需要的dx和初始值转成JSON字符串,通过元素的setAttribute方法存储,读取时再解析:
from pyscript import when import json @when("mousedown", selector="input[type='number']") def start_drag(evt): # 计算初始差值并存储为JSON格式的自定义属性 dx = evt.target.pos.x - evt.clientX evt.target.setAttribute("data-dragging", json.dumps({"dx": dx})) # 同时记录输入框的初始数值 evt.target.setAttribute("data-original-value", evt.target.value) @when("mousemove", selector="input[type='number']") def on_drag(evt): dragging_data = evt.target.getAttribute("data-dragging") if not dragging_data: return # 解析存储的状态数据 dragging = json.loads(dragging_data) original_value = float(evt.target.getAttribute("data-original-value")) # 计算新数值,0.1为步长可自行调整 delta = evt.clientX - (evt.target.pos.x - dragging["dx"]) new_value = original_value + delta * 0.1 evt.target.value = str(round(new_value, 2)) @when("mouseup", selector="input[type='number']") def end_drag(evt): # 拖动结束后清除自定义属性 evt.target.removeAttribute("data-dragging") evt.target.removeAttribute("data-original-value")
方案二:用Python字典维护拖动状态(推荐)
直接用全局Python字典存储每个输入框的拖动状态,避免操作DOM属性:
from pyscript import when # 全局字典,以输入框id为键存储拖动状态 drag_states = {} @when("mousedown", selector="input[type='number']") def start_drag(evt): element_id = evt.target.id # 存储初始差值和原始数值 drag_states[element_id] = { "dx": evt.target.pos.x - evt.clientX, "original_value": float(evt.target.value) } @when("mousemove", selector="input[type='number']") def on_drag(evt): element_id = evt.target.id if element_id not in drag_states: return state = drag_states[element_id] delta = evt.clientX - (evt.target.pos.x - state["dx"]) new_value = state["original_value"] + delta * 0.1 evt.target.value = str(round(new_value, 2)) @when("mouseup", selector="input[type='number']") def end_drag(evt): element_id = evt.target.id if element_id in drag_states: del drag_states[element_id]
关键说明
- PyScript中的
evt.target是JS元素的代理对象,不能直接用Python语法添加自定义属性,必须通过DOM API或Python容器管理状态。 - 可以根据需求调整数值计算的步长(比如把
0.1改成1实现整数拖动),或者添加边界限制(比如判断新值是否在输入框的min和max范围内)。
内容的提问来源于stack exchange,提问作者Neon22
相关产品推荐
相关产品推荐

