繁体   English   中英

单击按钮更改文本,JavaScript

[英]Change text on the click of a button, JavaScript

我有一个简单的 JavaScript,只需单击一个按钮即可展开和折叠文本。 我想要做的是在按钮旁边添加一个“+”号,并在文本折叠时将其更改为“-”,反之亦然。

这是我的 HTML:

<button onclick="expand('one')">First text</button><span class="plusminus">+</span>
<div class="text" id="one">
      A bunch of text here
</div>


<p><button onclick="expand('two')">Second text</button><span class="plusminus">+</span>
<div class="text" id="two">
      More text here
</div>


<p><button onclick="expand('three')">Third text</button><span class="plusminus">+</span>
<div class="text" id="three">
      And some text here
</div>

这是我的 CSS:

.text {
  display: none;
}  

这是 JavaScript:

function expand(textId) {
    var e = document.getElementById(textId);
    var sign = document.getElementsByClassName("plusminus");
    if (e.style.display === "block") {
        e.style.display = "none";
        sign.innerText = "+";
    } else {
        e.style.display = "block";
        sign.innerText = "-";
    }
}

展开/折叠有效,但不改变符号......我做错了什么?

非常感谢!

首先,让我们通过addEventListener转换为集中式事件处理来改进代码,而不是使 HTML 变得混乱的多个内联事件属性。

为此,我们需要将标志(“一”、“二”)等传递给每个按钮的数据属性。 所以 HTML 变成:

<p>
    <button data-which="three">Third text</button>
    <span class="plusminus">+</span>
</p> <!-- <-- note missing closing P tag in your original markup -->

因此,在外部 JS 文件中,您可以执行以下操作:

var btns = document.querySelectorAll('button[data-which]');
[].forEach.call(btns, function(btn) {
    btn.addEventListener('click', function() {
        expand(this.getAttribute('data-which'));
    }, false);
});

您的另一个问题是expand()函数当前针对所有plusminus元素,而不是与正在展开/折叠的区域相关的元素。 让我们解决这个问题:

var sign = document.querySelector('#'+textId).parentNode.querySelector('.plusminus');

小提琴

document.getElementsByClassName返回一个数组。 您将其视为单个对象。

您对document.getElementsByClassName实现不正确,您有多个具有相同类的跨度,您需要使用索引选择正确的跨度。 请记住您现有的代码,我对您的 expand 函数做了一个小的更正。

 function expand(textId, index) { var e = document.getElementById(textId); var sign = document.getElementsByClassName("plusminus")[index]; if (e.style.display === "block") { e.style.display = "none"; sign.innerText = "+"; } else { e.style.display = "block"; sign.innerText = "-"; } }
 .text { display: none; }
 <!DOCTYPE html> <html> <head> </head> <body> <button onclick="expand('one',0)">First text</button><span class="plusminus">+</span> <div class="text" id="one"> A bunch of text here </div> <p><button onclick="expand('two',1)">Second text</button><span class="plusminus">+</span> <div class="text" id="two"> More text here </div> <p><button onclick="expand('three',2)">Third text</button><span class="plusminus">+</span> <div class="text" id="three"> And some text here </div> </body> </html>

  • 您可以使用类classList的列表来检查类text是否应用于元素。

  • 使用nextElementSibling获取减号/加号元素。

function expand(button, textId) {
  var e = document.getElementById(textId);
  if (e.classList.contains('text')) {
    e.classList.remove('text');
    button.nextElementSibling.innerText = "-"
  } else {
    e.classList.add('text');
    button.nextElementSibling.innerText = "+"
  }
}

看看这个代码片段

 function expand(button, textId) { var e = document.getElementById(textId); if (e.classList.contains('text')) { e.classList.remove('text'); button.nextElementSibling.innerText = "-" } else { e.classList.add('text'); button.nextElementSibling.innerText = "+" } }
 .text { display: none; }
 <button onclick="expand(this, 'one')">First text</button><span class="plusminus">+</span> <div class="text" id="one"> A bunch of text here </div> <p/> <button onclick="expand(this, 'two')">Second text</button><span class="plusminus">+</span> <div class="text" id="two"> More text here </div> <p/> <button onclick="expand(this, 'three')">Third text</button><span class="plusminus">+</span> <div class="text" id="three"> And some text here </div>

看? 现在,您的减号/加号元素正在发生变化。

更好的方法

  • 使用addEventListener函数将单击事件绑定到按钮。
  • target作为数据属性data-target到您的按钮,即data-target='one'

看看这个代码片段

 document.querySelectorAll('button').forEach(function(b) { b.addEventListener('click', function(e) { expand(e.currentTarget, e.currentTarget.dataset.target); }); }); function expand(button, textId) { var e = document.getElementById(textId); if (e.classList.contains('text')) { e.classList.remove('text'); button.nextElementSibling.innerText = "-" } else { e.classList.add('text'); button.nextElementSibling.innerText = "+" } }
 .text { display: none; }
 <button data-target='one'>First text</button><span class="plusminus">+</span> <div class="text" id="one"> A bunch of text here </div> <p/> <button data-target='two'>Second text</button><span class="plusminus">+</span> <div class="text" id="two"> More text here </div> <p/> <button data-target='three'>Third text</button><span class="plusminus">+</span> <div class="text" id="three"> And some text here </div>

您可以通过遵循最佳实践来消除许多错误和错误:

  • 不要使用onclick属性
  • 使用事件委托
  • 使用 CSS 类来切换样式而不是直接更改style

另外,正确关闭<p>并记住<div>不能在<p>

现在,您最重要的问题是您误解getElement s ByClassName返回的内容HTMLCollection ,而不是单个元素。 innerText没有任何意义。

 document.addEventListener("click", function expand(e) { if (e.target.dataset.expand) { let textElement = document.getElementById(e.target.dataset.expand), expandIndicator = e.target.parentElement.getElementsByClassName("plusminus")[0]; expandIndicator.innerText = (textElement.classList.toggle("show") ? "-" : "+"); } });
 .text { display: none; } .show { display: block; }
 <p><button data-expand="one">First text</button><span class="plusminus">+</span></p> <div id="one" class="text"> A bunch of text here </div> <p><button data-expand="two">Second text</button><span class="plusminus">+</span></p> <div id="two" class="text"> More text here </div> <p><button data-expand="three">Third text</button><span class="plusminus">+</span></p> <div id="three" class="text"> And some text here </div>

您可以使用data-*属性来存储要显示的元素的 ID,而不是onclick属性。 通过事件委托(测试e.target的属性),您可以选择正确的textElement

要找到正确的expandIndicator您可以返回到您的父元素 ( <p> ) 并从那里找到class="plusminus"的元素。 请记住选择第一个 ( [0] ),因为您仍然会得到一个HTMLCollection

您也可以使用expandIndicator = e.target.nextElementSibling ,如果<span class="plusminus">总是出现在按钮之后——在这里,类名与事件无关。

最后,与其测试style属性,不如考虑使用类切换。 .classList.toggle根据类是否已设置,方便地返回truefalse ,这可以直接用于三元表达式 (... ? ... : ...)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM