【问题标题】:avoid html button being clicked again before it disapears (django)避免在它消失之前再次单击html按钮(django)
【发布时间】:2021-01-12 12:14:12
【问题描述】:

我正在一个 Django 项目中工作,该项目具有用户可以加入的事件(将 user_id 和 event_id 添加到模型参加者中),在我的事件中,我有一个加入按钮表单,点击后添加参加者,点击后该按钮消失并出现一个名为离开事件的新按钮,反之亦然。当用户加入或离开活动页面时,所有这些都会重新加载。

我遇到的问题是,我可以在按钮消失之前连续单击按钮 2 次,因为它正在尝试添加已存在的出席对象或删除不存在的对象存在。

所以我的问题是,是否有办法避免用户单击两次按钮,这样它就不会发送 POST 请求 2 次,或者至少如果他在它消失之前再次单击它而不发送请求,或者那里是否可以在发送 POST 请求之前应用按钮 onclick 功能?

编辑:我解决了 Django 部分,所以如果用户单击 2 次加入或离开按钮,我不会收到错误消息,但现在用户仍然可以继续单击按钮,页面将继续重新加载,直到他/她停止点击我认为不好的同一个按钮。

这里是显示加入或离开按钮的 javascript,该按钮在页面加载或单击任一按钮时执行(如果登录的用户正在参加,我首先查看了服务员列表,因为我没有找到方法在 Django 模板中查询参加模型):

script type="text/javascript">
    window.onload = function() {
        showJoinLeave();
    };
    function showJoinLeave() {
        var attendants = document.getElementsByClassName("attendant-username");
        var username = "{{ user.username }}";
        var joinButton = document.getElementById("event-info-join");
        var leaveButton = document.getElementById("event-info-leave");

        var is_attending = false;
        var attendant;
        for (attendant of attendants) {
            var attendant_name = attendant.innerHTML;
            if (attendant_name == username) {
                is_attending = true;
            }
        }
        
        if (is_attending===true){
            joinButton.style.display = "none";
            leaveButton.style.display = "flex";
        }
        
        else {
            joinButton.style.display = "flex";
            leaveButton.style.display = "none";
        }
    }

我的两个按钮:

<form action="{% url 'event-join' object.id %}" method="POST">
    {% csrf_token %}
    <button type="submit" id="event-info-join" class="icon" title="Join Event" onclick="showJoinLeave()">
        <i class="material-icons" title="Join Event">add</i>Join Event
    </button>
</form>
<form action="{% url 'event-leave' object.id %}" method="POST">
    {% csrf_token %}
    <button type="submit" id="event-info-leave" class="icon" title="Leave Event" onclick="showJoinLeave()">
        <i class="material-icons" title="Leave Event">add</i>Leave Event
    </button>
</form>

【问题讨论】:

  • showJoinLeave() 的顶部/内部添加this.onclick = null。但是,您也应该修复或考虑实际错误,因为每个人都可以发送手动请求,如果他们真的想要。您应该在删除或创建之前检查对象是否存在。
  • this.onclick = null 不起作用,但你是对的,有人可以输入 URL,同样会发生,谢谢。我会找到另一种方法来处理它
  • 现在,它正在禁用它但不发送 POST 请求,我不知道为什么。
  • 如您所说,最好的选择是保留按钮原样,但处理视图,以便用户在他/她已经离开的情况下不能离开事件吗?因为无论如何我都必须这样做
  • 在这种情况下应该使用Javascript来增强用户体验和预验证。然而,它不能取代实际的服务器端验证/过程。通常,您首先在服务器端对其进行验证,一旦完成并经过测试,您就可以在客户端进行预验证。可以以某种方式避免使用 Javascript 进行的每次验证。您可以禁用按钮,显示消息,显示等待符号.. 有很多方法可以处理装饰部分并防止 GUI 的双重请求。

标签: javascript html css django


【解决方案1】:

在隐藏按钮之前,我会选择pointer-events: none !important;,如下所示:

window.onload = function() {
    showJoinLeave();
};
function showJoinLeave() {
    var attendants = document.getElementsByClassName("attendant-username");
    var username = "{{ user.username }}";
    var joinButton = document.getElementById("event-info-join");
    var leaveButton = document.getElementById("event-info-leave");

    var is_attending = false;
    var attendant;
    for (attendant of attendants) {
        var attendant_name = attendant.innerHTML;
        if (attendant_name == username) {
            is_attending = true;
        }
    }
    
    if (is_attending===true){
        joinButton.style.pointerEvents = "none";
        joinButton.style.display = "none";
        leaveButton.style.pointerEvents = "auto";
        leaveButton.style.display = "flex";
    }
    
    else {
        joinButton.style.pointerEvents = "auto";
        joinButton.style.display = "flex";
        leaveButton.style.pointerEvents = "none";
        leaveButton.style.display = "none";
    }
}

指针事件:无

阻止指定 HTML 上的所有单击、状态和光标选项 元素

要了解更多关于pointer-events的信息,请查看以下链接:

https://css-tricks.com/almanac/properties/p/pointer-events/

【讨论】:

  • showJoinLeave() 也会在加载时触发。
  • 是的,它会在加载时触发,但无论哪种方式,我都可以点击它两次,就像我在函数执行之前点击它一样。
【解决方案2】:

我不具体了解 django,但通常您会在前端处理此问题,只需在单击按钮后立即将其设置为禁用即可。

这样,您不仅涵盖了技术方面,还涵盖了用户体验和可访问性方面。通过将按钮设置为禁用,用户可以立即获得点击反馈,并且知道他不能再次点击它。这也适用于残障用户(例如使用屏幕阅读器等)

我不建议设置pointer-events: none 或设置onclick = null,因为它不涵盖上述方面。

joinButton.disabled = true;

【讨论】:

  • 我按照你说的尝试过(joinButton.disabled = true; 在 if 中,leaveButton.disabled = true; 在 else 中),但我一直收到同样的错误。
猜你喜欢
  • 2020-06-30
  • 2017-02-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-08
  • 1970-01-01
相关资源
最近更新 更多