Javascript:为博客帖子创建多读/少读功能
Javascript: Create Read More / Read Less Functionality for Blog Posts
较早发布,但在意识到不适用于我的代码的限制之前将回复标记为“答案”。回复post我的问题。
JS 新手。我正在从头开始创建博客,并尝试实现阅读更多/阅读更少按钮。我能够在一个博客 post 上实现此功能,但如果我尝试将相同的 class 添加到其他博客 post 中,显然会出现问题,因为那样函数就赢了'确定要作用于哪些对象。
我最接近它工作的是另一个用户提供的这个解决方案:
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>
基本上,当用户点击“阅读更多”时,省略号消失,隐藏的内容现在显示出来,按钮变为“少读”。当他们点击“Read Less”时,省略号将被插入到较短的片段部分,完整内容再次隐藏,按钮变回“Read More”。
问题是,我们正在通过一个索引号,当我们通过 readMoreFunction(0)
时,该索引号将找到页面上“点”class 的第一个实例,“点”的第二个实例“点”class当我们经过readMoreFunction(1)
时,等等。所以你会发现,如果你切换上面HTML中的(0)和(1),代码将不再正常工作。单击“博客 1”阅读更多按钮将尝试展开“博客 2”,因为它正在寻找“点”的第二个实例 class.
这意味着每次我在顶部添加一个新博客时,我都需要更新在我的所有博客 post 上传递的索引号,以便最新的(顶部)post 现在是 (0),第二个 post 现在是 (1),通过我可能拥有的数百个博客 post,这是不合理的。
我如何编写一个函数来为所有不同的博客 post 独立制作“阅读更多/阅读更少”按钮 运行?我试图通过 readMoreFunction
中的 this
,但无法弄清楚如何引用具有特定 id 或 class 名称的前一个元素(以便它会抓住最近的前一个具有 ID“点”等的 span 标签)。我只能弄清楚如何使用 this.previousElementSibling;
引用最近的前一个元素
你们能帮我指明正确的方向吗?
如果您可以随意编辑 html 标记,建议将每个博客内容包含在父元素中。
从父元素开始查找class名称,可以唯一标识按钮对应的每个元素。
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>
您可以在所有按钮中使用事件: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>
尝试将每个 post 包装在一个容器中,然后仅像下面那样通过该容器访问子项,这样您就永远不会遇到此类问题。
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>
较早发布,但在意识到不适用于我的代码的限制之前将回复标记为“答案”。回复post我的问题。
JS 新手。我正在从头开始创建博客,并尝试实现阅读更多/阅读更少按钮。我能够在一个博客 post 上实现此功能,但如果我尝试将相同的 class 添加到其他博客 post 中,显然会出现问题,因为那样函数就赢了'确定要作用于哪些对象。
我最接近它工作的是另一个用户提供的这个解决方案:
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>
基本上,当用户点击“阅读更多”时,省略号消失,隐藏的内容现在显示出来,按钮变为“少读”。当他们点击“Read Less”时,省略号将被插入到较短的片段部分,完整内容再次隐藏,按钮变回“Read More”。
问题是,我们正在通过一个索引号,当我们通过 readMoreFunction(0)
时,该索引号将找到页面上“点”class 的第一个实例,“点”的第二个实例“点”class当我们经过readMoreFunction(1)
时,等等。所以你会发现,如果你切换上面HTML中的(0)和(1),代码将不再正常工作。单击“博客 1”阅读更多按钮将尝试展开“博客 2”,因为它正在寻找“点”的第二个实例 class.
这意味着每次我在顶部添加一个新博客时,我都需要更新在我的所有博客 post 上传递的索引号,以便最新的(顶部)post 现在是 (0),第二个 post 现在是 (1),通过我可能拥有的数百个博客 post,这是不合理的。
我如何编写一个函数来为所有不同的博客 post 独立制作“阅读更多/阅读更少”按钮 运行?我试图通过 readMoreFunction
中的 this
,但无法弄清楚如何引用具有特定 id 或 class 名称的前一个元素(以便它会抓住最近的前一个具有 ID“点”等的 span 标签)。我只能弄清楚如何使用 this.previousElementSibling;
你们能帮我指明正确的方向吗?
如果您可以随意编辑 html 标记,建议将每个博客内容包含在父元素中。
从父元素开始查找class名称,可以唯一标识按钮对应的每个元素。
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>
您可以在所有按钮中使用事件: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>
尝试将每个 post 包装在一个容器中,然后仅像下面那样通过该容器访问子项,这样您就永远不会遇到此类问题。
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>