早些时候发布了这个,但在意识到一个不适用于我的代码的限制之前,将回复标记为“答案”。重新发布我的问题。
JS 新手。我正在从头开始创建博客,并尝试实现“阅读更多/阅读更少”按钮。我能够在一篇博客文章中实现这一点,但是如果我尝试将相同的类添加到其他博客文章中,显然会出现问题,因为这样该函数将无法确定要对哪些对象进行操作。
我最接近让它工作的是另一个用户提供的这个解决方案:
function readMoreFunction(buttonIndex) {
var dots = document.getElementsByClassName("dots")[buttonIndex];
var contentText = document.getElementsByClassName("content")[buttonIndex];
var btnText = document.getElementsByClassName("buttonReadMore")[buttonIndex];
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read More";
contentText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read Less";
contentText.style.display = "inline";
}
}
.content{
display: none;
}
<p><strong>Blog Title</strong></p>
<p>Here is an example of the short snippet I want to show by default. <span class="dots">...</span></p>
<span class="content">
<p>Here is the longer text I want to show after the user clicks Read More.</p>
</span>
<button onclick="readMoreFunction(0)" class="buttonReadMore">Read More</button>
<p><strong>Blog Title 2</strong></p>
<p>Here is another short snippet I want to show by default for the second blog post. <span class="dots">...</span></p>
<span class="content">
<p>Here is the longer text I want to show after the user clicks Read More on the second blog post.</p>
</span>
<button onclick="readMoreFunction(1)" class="buttonReadMore">Read More</button>
基本上,当用户点击“阅读更多”时,省略号消失,隐藏的内容现在显示,按钮变为“阅读更少”。当他们点击“阅读更少”时,省略号将重新插入较短的片段部分,再次隐藏完整内容,按钮变回“阅读更多”。
问题是,我们通过一个索引号,当我们通过readMoreFunction(0)
时会找到页面上“dots”类的第一个实例,当我们通过时,“dots”类的第二个实例通过readMoreFunction(1)
等。所以你会发现,如果你把上面HTML中的(0)和(1)切换了,代码就不能正常工作了。单击“博客 1”阅读更多按钮将尝试展开“博客 2”,因为它正在寻找“点”类的第二个实例。
这意味着每次我在顶部添加一个新的博客文章时,我都需要更新在我所有博客文章中传递的索引号,以便最近的(顶部)文章现在是 (0) 并且第二篇文章现在是(1),通过我可能拥有的数百篇博客文章,这是不合理的。
如何编写一个函数,使“阅读更多/阅读更少”按钮独立运行所有不同的博客文章?我试图通过 this
中的 readMoreFunction
,但无法弄清楚如何引用具有特定 id 或类名的前一个元素(以便它可以获取具有id“点”等)。我只能弄清楚如何使用 this.previousElementSibling;
你们能帮我指出正确的方向吗?
答案 0 :(得分:1)
如果您可以随意编辑 html 标记,建议将每个博客内容包含在一个父元素中。
通过从父元素开始搜索类名,可以唯一标识按钮对应的每个元素。
function readMoreFunction(el) {
var parent = el.closest(".wrapper")
var dots = parent.querySelector(".dots");
var contentText = parent.querySelector(".content");
var btnText = parent.querySelector(".buttonReadMore");
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read More";
contentText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read Less";
contentText.style.display = "inline";
}
}
.content{
display: none;
}
<div class="wrapper">
<p><strong>Blog Title</strong></p>
<p>Here is an example of the short snippet I want to show by default. <span class="dots">...</span></p>
<span class="content">
<p>Here is the longer text I want to show after the user clicks Read More.</p>
</span>
<button onclick="readMoreFunction(this)" class="buttonReadMore">Read More</button>
</div>
<div class="wrapper">
<p><strong>Blog Title 2</strong></p>
<p>Here is another short snippet I want to show by default for the second blog post. <span class="dots">...</span></p>
<span class="content">
<p>Here is the longer text I want to show after the user clicks Read More on the second blog post.</p>
</span>
<button onclick="readMoreFunction(this)" class="buttonReadMore">Read More</button>
</div>
答案 1 :(得分:1)
您可以在所有按钮内使用事件:onclick="readMoreFunction(event)"
然后在您的函数中,您使用 event.target
作为点击按钮的引用,并根据您的 HTML 标记从那里导航。
function readMoreFunction(event) {
var dots = event.target.previousElementSibling.previousElementSibling.querySelector(".dots")
var contentText = event.target.previousElementSibling
var btnText = event.target
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read More";
contentText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read Less";
contentText.style.display = "inline";
}
}
.content {
display: none;
}
<p><strong>Blog Title</strong></p>
<p>Here is an example of the short snippet I want to show by default. <span class="dots">...</span></p>
<span class="content">
<p>Here is the longer text I want to show after the user clicks Read More.</p>
</span>
<button onclick="readMoreFunction(event)" class="buttonReadMore">Read More</button>
<p><strong>Blog Title 2</strong></p>
<p>Here is another short snippet I want to show by default for the second blog post. <span class="dots">...</span>
</p>
<span class="content">
<p>Here is the longer text I want to show after the user clicks Read More on the second blog post.</p>
</span>
<button onclick="readMoreFunction(event)" class="buttonReadMore">Read More</button>
答案 2 :(得分:1)
尝试将每个帖子包装在一个容器中,然后仅像下面那样通过该容器访问子项,这样您就永远不会遇到此类问题。
function readMoreFunction() {
var parent = event.target.parentElement;
var dots = parent.getElementsByClassName("dots")[0];
var contentText = parent.getElementsByClassName("content")[0];
var btnText = parent.getElementsByClassName("buttonReadMore")[0];
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read More";
contentText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read Less";
contentText.style.display = "inline";
}
}
.content{
display: none;
}
<div class="conainer-post">
<p><strong>Blog Title</strong></p>
<p>Here is an example of the short snippet I want to show by default. <span class="dots">...</span></p>
<span class="content">
<p>Here is the longer text I want to show after the user clicks Read More.</p>
</span>
<button onclick="readMoreFunction()" class="buttonReadMore">Read More</button>
</div>
<div class="conainer-post">
<p><strong>Blog Title 2</strong></p>
<p>Here is another short snippet I want to show by default for the second blog post. <span class="dots">...</span></p>
<span class="content">
<p>Here is the longer text I want to show after the user clicks Read More on the second blog post.</p>
</span>
<button onclick="readMoreFunction()" class="buttonReadMore">Read More</button>
</div>