You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 07:29:57