我建议,如果您能够使用 ES6:
// a named function to handle the toggling of visibility:
function toggleNextSibling(event) {
// event.target is the element/node that triggered
// the event:
event.target
// the nextElementSibling finds the next element
// sibling of the clicked node:
.nextElementSibling
// we use Element.classList.toggle to add the
// supplied class-name if it's not present, or
// remove the supplied class-name if it is
// present:
.classList.toggle('shown');
}
// here we document.querySelectorAll() to retrieve a (non-live)
// NodeList of the elements of the document that match the
// supplied CSS selector, this NodeList is then passed to
// Array.from() to convert the Array-like NodeList into an
// Array:
Array.from(document.querySelectorAll('.message-head'))
// as we have an Array we can then use Array.prototype.forEach()
// to iterate over each element of the Array to perform actions
// upon them:
.forEach(
// 'head' is a reference to the Array element of the Array
// over which we're iterating, and upon each of those
// Array elements we're then using addEventListener() to
// bind a function (toggleNextSibling()) as the event-
// handler for the 'click' event (but note the deliberate
// absence of parentheses following the function name):
head => head.addEventListener('click', toggleNextSibling)
);
function toggleNextSibling(event) {
event.target.nextElementSibling.classList.toggle('shown');
}
Array.from(document.querySelectorAll('.message-head'))
.forEach(head => head.addEventListener('click', toggleNextSibling));
.message-head {
cursor: pointer;
margin: 0.5em 0 0 0;
}
.news-message:first-child.message-head {
margin-top: 0;
}
.message-content {
display: none;
text-indent: 1em;
color: rebeccapurple;
}
.message-content.shown {
display: block;
}
<div class="news-message">
<div class="message-head">
Headline of Message 1
</div>
<div class="message-content">
Here comes the content of message 1
</div>
</div>
<div class="news-message">
<div class="message-head">
Headline of Message 2
</div>
<div class="message-content">
Here comes the content of message 2
</div>
</div>
<div class="news-message">
<div class="message-head">
Headline of Message 3
</div>
<div class="message-content">
Here comes the content of message 3
</div>
</div>
如果没有 ES6,上面的内容可以转换为以下内容(尽管函数本身不需要更改):
// here we use Function.prototype.call(), to enable us to
// pass the NodeList to Array.prototype.slice(), which converts
// the NodeList to an Array:
Array.prototype.slice.call(document.querySelectorAll('.message-head'))
// again, having an Array allows us to use Array methods, but
// here we cannot use Arrow function expressions (as they were
// not available until ES6), so instead we use a function expression:
.forEach(function(head) {
// 'head' refers to the current Array element of the Array
// over which we're iterating, and we again use addEventListener
// to bind the named function to the 'click' event:
head.addEventListener('click', toggleNextSibling)
});
function toggleNextSibling(event) {
event.target.nextElementSibling.classList.toggle('shown');
}
Array.prototype.slice.call(document.querySelectorAll('.message-head'))
.forEach(function(head) {
head.addEventListener('click', toggleNextSibling)
});
.message-head {
cursor: pointer;
margin: 0.5em 0 0 0;
}
.news-message:first-child.message-head {
margin-top: 0;
}
.message-content {
display: none;
text-indent: 1em;
color: rebeccapurple;
}
.message-content.shown {
display: block;
}
<div class="news-message">
<div class="message-head">
Headline of Message 1
</div>
<div class="message-content">
Here comes the content of message 1
</div>
</div>
<div class="news-message">
<div class="message-head">
Headline of Message 2
</div>
<div class="message-content">
Here comes the content of message 2
</div>
</div>
<div class="news-message">
<div class="message-head">
Headline of Message 3
</div>
<div class="message-content">
Here comes the content of message 3
</div>
</div>