【问题标题】:javascript for loop not printing right dataset for each button in a classjavascript for循环没有为类中的每个按钮打印正确的数据集
【发布时间】:2020-06-15 12:49:41
【问题描述】:

我正在使用flask、javascript 和socketio 创建一个投票网络应用程序。我正在遍历属于vote 类的所有按钮。我正在尝试获取他们的数据投票值。出于某种原因,当单击按钮时为按钮打印 dataset.vote(如下面的函数中指定)时,它会在单击两个按钮时输出最后一个按钮的 dataset.vote。有人可以指出我的错误并帮助我解决它吗?如果您需要我指定某些内容,我很乐意这样做。

烧瓶:

from flask import Flask, render_template
from flask_socketio import SocketIO, emit

app = Flask(__name__)
sock =SocketIO(app)

@app.route("/")
def index():
    return render_template("index.html")

@sock.on("cast_vote")
def f(data):
    vote = data["vote"]
    print(vote)
    emit("vote_result", {"vote":vote}, broadcast=True)

HTML:

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <title>SocketIO</title>
    <script src="https://cdn.jsdelivr.net/npm/socket.io-client@2/dist/socket.io.js"></script>
    <script src="{{url_for('static', filename='main.js')}}"></script>
  </head>
  <body>
    <ul id="main"></ul>
        <button class="vote" data-vote="no">No</button>
    <button class="vote" data-vote="yes">Yes</button>
  </body>
</html>

Javascript:

document.addEventListener("DOMContentLoaded", ()=>{
  var sock = io.connect(location.protocol+"//"+document.domain+":"+location.port)
  sock.on("connect", ()=>{
    buttons = document.querySelectorAll(".vote");
    let i;
    for(i=0; i<buttons.length; ++i){
      button = buttons[i];
      button.onclick = () => {
        console.log(button.dataset.vote);
        let vote = button.dataset.vote;
        console.log(vote);
        sock.emit("cast_vote", {"vote":vote});
      };
    }
  });
  sock.on("vote_result", (data)=>{
    newli = document.createElement("li");
    newli.innerHTML=data["vote"]
    document.querySelector("#main").append(newli);
  });
});

输出:

yes
yes
yes
yes

【问题讨论】:

    标签: javascript python html flask socket.io


    【解决方案1】:

    您将一些变量声明为 global 之一,您应该避免这种情况。

    尝试更改此代码

    for(i=0; i<buttons.length; ++i){
      button = buttons[i];
    

    到这个

    for(i=0; i<buttons.length; ++i){
      let button = buttons[i];
    

    还请查看您的代码并将var/let/const 添加到您使用的所有其他变量中。

    【讨论】:

      【解决方案2】:

      问题是,在不使用constlet 声明的情况下创建按钮时,您会创建一个全局变量,如果您在浏览器的控制台中编写按钮,它将打印在每次迭代中重复使用的元素的引用,这就是为什么对dataset.vote 的调用在您的情况下返回yes,解决方案是使用声明letconst 例如

      let button = buttons[i];
      

      您可以利用 javascript 中的链接来简化您的代码,请查看此示例

      document.querySelectorAll("button.vote").forEach((button) =>
        button.addEventListener("click", (event) => {
          const vote = event.target.dataset.vote;
      
          console.log(vote);
          sock.emit("cast_vote", { vote });
        })
      );
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-09-24
        • 1970-01-01
        • 2014-08-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多