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

Flask项目实现长按按钮重复触发执行指定函数的问题求助

后端调整

首先新增一个独立的异步接口处理动作执行请求,避免页面刷新:

from flask import (
    Blueprint, render_template, request, jsonify
)

from webapp.Utilities.utilities import SerialHandler
from webapp.blueprints.decorators import login_required

bp = Blueprint('main', __name__)

serial_scheduler = SerialHandler()

# 原页面路由保留
@bp.route('/', methods=('GET',))
@login_required
def index():
    return render_template('index.html', title="Index")

# 新增动作执行接口
@bp.route('/run-action', methods=('POST',))
@login_required
def run_action():
    button_action = request.form.get('action')
    # 这里可以根据button_action的值执行对应的逻辑,调用serial_scheduler的方法
    foo()
    return jsonify({"status": "success"})

前端调整

修改原有表单和按钮逻辑,用JS处理长短按事件,异步调用后端接口:

{% extends "layout.html" %}
{% block stylesheet %}
  <link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">
{% endblock %}
{% block content %}

  <div class="container new_container">
    <div class="card" style="width: 18rem;">
      <div class="card-header">
        Featured
      </div>
      <ul class="list-group list-group-flush">
        <li class="list-group-item">An item</li>
        <li class="list-group-item">A second item</li>
        <li class="list-group-item">A third item</li>
      </ul>
    </div>
  </div>

  <div class="container">
    <img src="{{ url_for('video.video') }}" alt="">
  </div>

  <!-- 去掉原有form的默认提交逻辑,给按钮加标识 -->
  <div class="btn-group" style="width:100%">
    <button class="action-btn" data-action="Apple" style="width:33.3%">Apple</button>
    <button class="action-btn" data-action="Samsung" style="width:33.3%">Samsung</button>
    <button class="action-btn" data-action="Sony" style="width:33.3%">Sony</button>
  </div>

  <div class="container new_container">
    <div class="col-md-12 text-center">
      <button onclick="switch_theme()" class="btn btn-light shadow-none" id="switch_button" style="width: 15%;">Dark Mode</button>
    </div>
  </div>

  <script>
    function switch_theme() {
      const theme = document.getElementById('switch_theme').className;

      if(theme === "dark-theme") {
        document.getElementById('switch_theme').className = "light-theme";
        document.getElementById('switch_button').className = "btn btn-dark shadow-none";
        document.getElementById('switch_button').innerHTML = "Light Mode";
      } else {
        document.getElementById('switch_theme').className = "dark-theme";
        document.getElementById('switch_button').className = "btn btn-light shadow-none";
        document.getElementById('switch_button').innerHTML = "Dark Mode";
      }
    }

    // 长短按逻辑
    let pressTimer = null;
    let repeatTimer = null;
    let pressStartTime = 0;
    const LONG_PRESS_THRESHOLD = 200; // 长按判定阈值,单位ms
    const REPEAT_INTERVAL = 150; // 长按后重复执行的间隔,单位ms

    // 发送请求的公共方法
    function sendActionRequest(action) {
      const formData = new FormData();
      formData.append('action', action);
      fetch('/run-action', {
        method: 'POST',
        body: formData,
        headers: {
          'X-CSRFToken': '{{ csrf_token() }}' // 如果你的Flask开启了CSRF保护需要加这行
        }
      });
    }

    // 给所有动作按钮绑定事件
    document.querySelectorAll('.action-btn').forEach(btn => {
      const action = btn.dataset.action;

      // 按下事件
      btn.addEventListener('mousedown', (e) => {
        e.preventDefault();
        pressStartTime = Date.now();
        // 长按判定定时器
        pressTimer = setTimeout(() => {
          // 长按触发重复执行
          repeatTimer = setInterval(() => {
            sendActionRequest(action);
          }, REPEAT_INTERVAL);
        }, LONG_PRESS_THRESHOLD);
      });

      // 松开/移出按钮事件
      ['mouseup', 'mouseleave', 'touchend', 'touchcancel'].forEach(eventName => {
        btn.addEventListener(eventName, (e) => {
          e.preventDefault();
          // 清除所有定时器
          clearTimeout(pressTimer);
          clearInterval(repeatTimer);
          pressTimer = null;
          repeatTimer = null;
          // 判断是否为短按
          if (Date.now() - pressStartTime < LONG_PRESS_THRESHOLD) {
            sendActionRequest(action);
          }
        });
      });
    });
  </script>

{% endblock %}

说明

  • 短按按钮会触发1次后端动作执行,长按按钮超过200ms后会每隔150ms触发一次,松开就停止
  • 所有请求都是异步发起,不会刷新当前页面
  • 如果你的Flask项目开启了CSRF保护,需要保留代码里CSRFToken的配置

内容的提问来源于stack exchange,提问作者std124_lf

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 06:09:02