点击按钮,JavaScript即可更改文字

时间:2018-02-07 12:55:02

标签: 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 = "-";
    }
}

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

非常感谢!

4 个答案:

答案 0 :(得分:1)

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

为此做准备,我们需要将标志(“one”,“two”)等传递给每个按钮的数据属性。所以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');

Fiddle

答案 1 :(得分:0)

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

document.getElementsByClassName的实现不正确,您有多个具有相同类的跨度,您需要使用索引选择正确的。记住你现有的代码我已经在你的扩展函数中做了一个小的修正。

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>

答案 2 :(得分:0)

  • 您可以使用类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>

答案 3 :(得分:0)

您可以通过遵循最佳做法消除许多错误和错误:

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

另外,请正确关闭<p>,并请注意<div>不能在<p>内。

现在,您最重要的问题是您误解了what getElementsByClassName returnsHTMLCollection,而不是单个元素。 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>

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

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

如果expandIndicator = e.target.nextElementSibling总是在按钮之后,您也可以使用<span class="plusminus"> - 此处,类名称并不重要。

最后,不要测试style属性,而应考虑使用类切换。 .classList.toggle方便地返回truefalse,具体取决于该类是否已设置,可以直接用于三元表达式中...(? ... {{1} } ...)。