【问题标题】:How to set multiple .textcontents to one click event in JavaScript?如何在 JavaScript 中将多个 .textcontents 设置为单击事件?
【发布时间】:2019-07-18 21:45:43
【问题描述】:

我在加载时显示一个带有“Drive”文本的按钮,该按钮启动一个让汽车车轮旋转的功能。当您单击“驱动器”按钮时,会出现另一个按钮,并带有“停止”文本。 我在 javascript 中设置了按钮的所有 .textContent 。 我希望您第一次单击“驱动器”按钮时,将 textContent 更改为“faster”,然后单击它,将 textContent 更改为“Faster!!”。 如果您完成驾驶,您可以按下“停止”按钮来停止车轮旋转。 “停止”按钮将消失并设置“更快!!”按钮,返回“驱动器”。

到目前为止,一切正常,但只是第一次.. 之后它将“更快”文本设置回“驱动器”,但是当我单击它时,它立即转到“更快!!”,跳过“更快”的内容。

我认为这里一定有问题:

  // Set text button to faster
  driveXcar.textContent = "faster";


  driveXcar.onclick = function() {
    driveXcar.textContent = "Faster!!";
  }

我无法让它工作。

代码如下:

// DRIVE BUTTON
let driveXcar = document.getElementById("drive");
driveXcar.addEventListener('click', driveCar);
driveXcar.textContent = "Drive";

//STOP BUTTON
let stopXcar = document.getElementById("stop");
stopXcar.style.display = "none";
stopXcar.textContent = "Stop";

let i = 0;

function driveCar() {
  // Display stop button on click drive
  document.getElementById("stop").style.display = "block";

    let start = setInterval(function () {
    i += 2;

    backLines.forEach(line => {
      line.setAttribute("transform", "rotate(" + i + ", 85, 180)");
      }),
      frontLines.forEach(line => {
        line.setAttribute("transform", "rotate(" + i + ", 336, 180)");
      }),
      backLinesHatchback.forEach(line => {
        line.setAttribute("transform", "rotate(" + i + ", 100, 180)");
      })
  }, 10);

  // Set text button to faster
  driveXcar.textContent = "faster";

  driveXcar.onclick = function() {
    driveXcar.textContent = "Faster!!";
  }


  // Add event listener to stop button
  stopXcar.addEventListener('click', stopCar);

  function stopCar() {
    clearInterval(start);
    driveXcar.textContent = "Drive";
    stopXcar.style.display = "none";
  }
}

【问题讨论】:

  • 嵌套事件监听器是一种不好的做法。你为什么需要这样的东西?

标签: javascript onclick addeventlistener


【解决方案1】:

嵌套事件侦听器时需要非常小心,在您的情况下,每次按下驱动器按钮时都会在停止按钮上添加一个新的事件侦听器,这很糟糕。嵌套事件侦听器被认为是不好的做法,应尽可能避免。我已经提出了一个可能的解决方案,您可以在 JS Bin 上查看。

let state = 'stop'; // 'stop' | 'faster' | 'Faster!!'
let driveXcar = initDriveCar();
let stopXcar = initStopCar();
let start;

function initDriveCar() {
  let driveXcar = document.getElementById("drive");
  driveXcar.addEventListener('click', driveCar);
  driveXcar.textContent = "Drive";
  return driveXcar;
}

function initStopCar() {
  let stopXcar = document.getElementById("stop");
  stopXcar.addEventListener('click', stopCar);
  stopXcar.style.display = "none";
  stopXcar.textContent = "Stop";
  return stopXcar;
}

function driveCar() {
  // Display stop button on click drive
  stopXcar.style.display = "block";

  if (start) {
    clearInterval(start);
  }

  start = setInterval(function () {
    // your logic
  }, 10);

  state = getNextState(state, 'drive');
  if (state === 'faster') {
    driveXcar.textContent = "faster";
  }
  else {
    driveXcar.textContent = "Faster!!";
  }
}

function stopCar() {
  clearInterval(start);
  driveXcar.textContent = "Drive";
  stopXcar.style.display = "none";
  state = getNextState(state, 'stop')
}

function getNextState(state, buttonClicked) {
  if (state === 'stop' && buttonClicked === 'drive') {
    return 'faster';
  }
  else if (state === 'faster' && buttonClicked === 'drive') {
    return 'Faster!!';
  }
  else if (state === 'Faster!!' && buttonClicked === 'drive') {
    return 'Faster!!';
  } // include more conditions if necessary
  else {
    return 'stop';
  }
}

我已将代码分成更小的块,以便更易于阅读和理解,但我尝试遵循与您相同的逻辑,但是我添加了一个 state 属性来帮助您跟踪汽车状态。

【讨论】:

  • 非常感谢您花时间写这篇文章。我肯定会避免在我未来的代码中嵌套事件监听器。要去编辑我的代码。
  • 我已经编辑了我的代码,但我仍然遇到问题。当我单击一次驱动器时,它会启动该功能,并将 textContent 更改为更快。如果我点击停止,功能停止,一切都很好。但是,如果我单击驱动器按钮几次以使其运行得更快,然后按停止它不会停止。再次,我把停止功能放回驱动功能,这实际上使它停止。我已经登录(开始)并且每次按下驱动器时,它都会计数 +1,当您单击停止时,它只会停止当前计数。只有当我把它放在函数中时它才会完全停止..
  • 我已经编辑了代码以解决一些问题,请查看。关于start 变量,你是对的,我忘记在创建新的间隔之前取消当前间隔,这是在编辑时处理的。
猜你喜欢
  • 2014-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-11
  • 1970-01-01
相关资源
最近更新 更多