如何根据按钮元素的点击事件触发的切换状态呈现不同的文本内容?

How does one render different text-content depending on a button-element's click-event triggered toggle-state?

我有一个按钮,单击该按钮时,会将文本从 'Report A Problem' 更改为 'Close' 并打开下拉文本输入,再次单击该按钮时,它仍设置为 'Close' ,而我希望它 return 到 'Report A Problem'。我只知道如何通过单击触发 2 个事件,而这将是两次单击操作。有什么解决此问题的最佳方法吗?

function change() {
  document.getElementById("myBtnToReportABug").innerHTML = "Close";
}
<button id="myBtnToReportABug" onclick="change()" type="button" class="btn btn-secondary float-right" data-toggle="myModal" data-target="#myModal"> Report A Problem </button>

只需检查当前值:

<button id="myBtnToReportABug" onclick="change()" type="button" class="btn btn-secondary float-right" data-toggle="myModal" data-target="#myModal"> Report A Problem </button>
function change() {
      var theButton = document.getElementById("myBtnToReportABug");
      if (theButton.innerHTML == "Close")
          theButton.innerHTML = "Report A Problem";
      else
          theButton.innerHTML = "Close";
}

您只需要在您的函数中添加一个条件来测试 textContent 是什么,并相应地更改它。

(注意:内联 JS 通常不受欢迎,所以我在这里使用 addEventListener。)

// Cache the button element and add a listener to it
const button = document.getElementById('myBtnToReportABug');
button.addEventListener('click', handleClick, false);

function handleClick() {

  // Depending on the textContent of the button
  // switch between the two texts
  if (button.textContent === 'Close') {
    button.textContent = 'Report a problem';
  } else {
    button.textContent = 'Close';
  }
}
<button id="myBtnToReportABug">Report A Problem</button>

我会使用 data attribute 来维护按钮的状态。

您还应该使用 addEventListener 而不是 onclick 属性。

const report_btn = document.getElementById('myBtnToReportABug');

report_btn.addEventListener('click', function(){
  var btn_state = this.getAttribute('data-state');
  switch(btn_state){
    case "report":
    
      // The button is in the "report" state
      this.innerHTML = "Close";
    
      // Change the button state
      this.setAttribute('data-state', 'close')
      
      // do other stuff here...
      
      break;
    case "close":
    
      // The button is in the "close" state
      this.innerHTML = " Report A Problem ";
    
      // Change the button state
      this.setAttribute('data-state', 'report')
    
      // do other stuff here..
    
      break;
  }
});
<button id="myBtnToReportABug" data-state='report' type="button" class="btn btn-secondary float-right" data-toggle="myModal" data-target="#myModal"> Report A Problem </button>

你的意思是按钮需要改变状态而不是事件!事件总是一样的……onclick!

所以你只需要在每次点击时循环一个变量计数器,就像这样...

 if(State==3){State=1;} else {State ++;}

然后...

 if(State==1) {RunFunction1();} else 

  if(State==2) {RunFunction2();} else 

   if(State==3) {RunFunction3();}

更改按钮文本将发生在上面每个编号的函数内,以及您打算为每个状态发生的任何其他事情。

我会使用另一个数据属性来跟踪切换状态,例如 data-button-state 作为新属性:

function change() {
    var button = document.getElementById("myBtnToReportABug");
    var buttonState = button.dataset.buttonState;
    var buttonText;
    var buttonState;

    if (buttonState === 'report') {
        buttonText = "Close";
        buttonState = "close";
    } else {
        buttonText = "Report A Problem";
        buttonState = "report"
    }

    button.innerHTML = buttonText;
    button.dataset.buttonState = buttonState;
}
<button
    id="myBtnToReportABug"
    onclick="change()"
    type="button"
    class="btn btn-secondary float-right"
    data-toggle="myModal"
    data-target="#myModal"
    data-button-state="report"
>
        Report A Problem
</button>

通过这种方法,您可以拥有多个状态,只需在每个 if 语句中定义您想要对这些状态执行的操作:)

下面这种方式的最大优点是国际化和本地化不依赖于客户端JavaScript渲染。

由于复选框非常适合表示切换状态,因此这种依赖于状态的切换文本只需要呈现为 checkbox 控件的两个 data-* 属性,连同外部 label 元素模仿切换按钮的行为。

只需要 HTML 和 CSS。

并在这个小组件上制作负责打开和关闭模式的客户端脚本,运行 应该不是问题...

[data-modal-checkbox-button] {
  /* appearance: button; */
  display: inline-block;
  position: relative;
  min-width: 1em;
  padding: 4px;
  text-align: center;
  white-space: nowrap;
  background: #ccc;
  border: 2px solid;
  border-radius: 4px;
  border-style: outset;
}
[data-modal-checkbox-button]:active {
  border-style: inset;
}
[data-modal-checkbox-button] > [type="checkbox"]:focus {
  outline-offset: 8px;
  outline-color: darkorange;
}
[data-modal-checkbox-button]:active > [type="checkbox"] {
  left: -1px;
  top: -1px;  
}

[data-modal-checkbox-button] > [type="checkbox"] {
  appearance: none;
  display: inline-block;
  position: relative;
}
[data-modal-checkbox-button] > [type="checkbox"]::after {
  content: attr(data-checked-false);
}
[data-modal-checkbox-button] > [type="checkbox"]:checked::after {
  content: attr(data-checked-true);
}
<label data-modal-checkbox-button>
  <input
    name="report-a-bug"

    type="checkbox"
    class="btn btn-secondary"

    data-toggle="myModal"
    data-target="#myModal"

    data-checked-true="Close"
    data-checked-false="Report A Problem"
  />
</label><br/>

<label data-modal-checkbox-button>
  <input
    name="report-a-bug"

    type="checkbox"
    class="btn btn-secondary"

    data-toggle="myModal"
    data-target="#myModal"

    data-checked-true="Schließen"
    data-checked-false="Ein Problem melden"
  />
</label><br/>

<label data-modal-checkbox-button>
  <input
    name="report-a-bug"

    type="checkbox"
    class="btn btn-secondary"

    data-toggle="myModal"
    data-target="#myModal"

    data-checked-true="закрывание"
    data-checked-false="Сообщить о проблеме"
  />
</label>

如果 OP 必须依赖脚本方法,OP 可能会考虑以下通用且独立于语言的解决方案...

function toggleModalButtonState({ currentTarget }) {
  const { dataset } = currentTarget;
  const { textClose, textReport } = dataset;

  const state = (dataset.state === 'close')
    ? 'report'
    : 'close';
    
  dataset.state = state;

  currentTarget.textContent = ({
    report: textReport,
    close: textClose,
  })[state];
}
document
  .querySelector('#myBtnToReportABug')
  .addEventListener('click', toggleModalButtonState);
<button
  id="myBtnToReportABug"

  type="button"
  class="btn btn-secondary float-right"

  data-toggle="myModal"
  data-target="#myModal"

  data-state="report"
  data-text-close="Close"
  data-text-report="Report A Problem"

>Report A Problem</button>