Eventlistener function requires two clicks - javascript

I just started JS and trying to get a button which opens a block of text and with this same button you can close the block. All works fine but the first click is doing the focus and second click is opening the block of text. Block of text needs to open on the first click.
Hope you can help me out with plain JS...Thanks!
document.getElementById("homeBtn").addEventListener("click", function(){
var x = document.getElementById("parText");
var y = document.getElementById("homeBtn");
if (x.style.display === "none") {
x.style.display = "block";
y.innerHTML = "Sluiten";
} else {
x.style.display = "none";
y.innerHTML = "Lees verder...";
}
});
HTML:
<div>
<button type="button" id="homeBtn">Lees verder...</button>
</div>
<div id="parText">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Etiam sed leo felis. Maecenas tincidunt orci id orci vulputate congue.
Aliquam in molestie tortor. Sed erat felis, tincidunt id commodo sit amet,
dignissim fringilla metus. Proin porta, justo eget sollicitudin hendrerit,
sapien ligula imperdiet erat, vel hendrerit odio quam ut mauris.
Etiam laoreet justo massa, ac pretium sem pharetra at. Nullam ut felis orci.
Duis faucibus mauris libero, at semper nulla finibus vitae. In ut ex justo.
</p>
</div>

You need to set the display to none first. When your code is running it goes to the else part and then it is setting the display to none, so nothing is happening. When you click again the if statement is now true as the display is set to none and the code works. I have fixed your code. Check the snippet.
var y = document.getElementById("homeBtn");
var x = document.getElementById("parText");
x.style.display = "none";
y.addEventListener("click", function(){
if (x.style.display === "none") {
x.style.display = "block";
y.innerHTML = "Sluiten";
} else {
x.style.display = "none";
y.innerHTML = "Lees verder...";
}
});
<button type="button" id="homeBtn">Lees verder...</button>
<div id="parText">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Etiam sed leo felis. Maecenas tincidunt orci id orci vulputate congue.
Aliquam in molestie tortor. Sed erat felis, tincidunt id commodo sit amet,
dignissim fringilla metus. Proin porta, justo eget sollicitudin hendrerit,
sapien ligula imperdiet erat, vel hendrerit odio quam ut mauris.
Etiam laoreet justo massa, ac pretium sem pharetra at. Nullam ut felis orci.
Duis faucibus mauris libero, at semper nulla finibus vitae. In ut ex justo.
</p>
</div>

Related

Reusing a Javascript function?

I have this simple read more JS function. I want to reuse it, what's the best practice for this? For example, below, I have two read more buttons but I have to copy paste the function and some number to it to use it. Not the cleanest way, what's a better way around this?
function myFunction() {
var dots = document.getElementById("dots");
var moreText = document.getElementById("more");
var btnText = document.getElementById("myBtn");
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read more";
moreText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read less";
moreText.style.display = "inline";
}
}
function myFunction2() {
var dots = document.getElementById("dots2");
var moreText = document.getElementById("more2");
var btnText = document.getElementById("myBtn2");
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read more";
moreText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read less";
moreText.style.display = "inline";
}
}
#more {display: none;}
#more2 {display: none;}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span id="dots">...</span><span id="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction()" id="myBtn">Read more</button>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, naliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida isi lorem egestas vitae scel<span id="dots2">...</span><span id="more2">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction2()" id="myBtn2">Read more</button>
First, when repeating behavior you should refrain from attempting to use id attributes since (as you know) they must be unique. Additionally, it leads to naming things without much meaning (thing1, thing2 etc).
One technique is to use the class attribute.
Each event allows access to the target of the event. We can find the paragraph to effect using the previousElementSibling to find the <p>.
From there, we can use that node to query for the .dots and .more classes and change them as needed.
Since the button is the target of the event, we just change the button text directly.
EDIT: Thanks #Carston for the previousElementSibling hint.
function myFunction(e) {
const paragraph = e.target.previousElementSibling;
var dots = paragraph.querySelector('.dots');
var moreText = paragraph.querySelector(".more");
if (dots.style.display === "none") {
dots.style.display = "inline";
e.target.innerHTML = "Read more";
moreText.style.display = "none";
} else {
dots.style.display = "none";
e.target.innerHTML = "Read less";
moreText.style.display = "inline";
}
}
.more {display: none;}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span class="dots">...</span><span class="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction(event)">Read more</button>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, naliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida isi lorem egestas vitae scel<span class="dots">...</span><span class="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction(event)">Read more</button>
You could use a function parameter to dynamically add a suffix to your ids :
function myFunction(suffix) {
var dots = document.getElementById("dots" + suffix);
var moreText = document.getElementById("more" + suffix);
var btnText = document.getElementById("myBtn" + suffix);
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read more";
moreText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read less";
moreText.style.display = "inline";
}
}
#more {display: none;}
#more2 {display: none;}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span id="dots">...</span><span id="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction('')" id="myBtn">Read more</button>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, naliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida isi lorem egestas vitae scel<span id="dots2">...</span><span id="more2">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction('2')" id="myBtn2">Read more</button>
Or 3 parameters corresponding to the ids :
function myFunction(dotsId, moreTextId, btnTextId) {
var dots = document.getElementById(dotsId);
var moreText = document.getElementById(moreTextId);
var btnText = document.getElementById(btnTextId);
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read more";
moreText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read less";
moreText.style.display = "inline";
}
}
#more {display: none;}
#more2 {display: none;}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span id="dots">...</span><span id="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction('dots','more','myBtn')" id="myBtn">Read more</button>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, naliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida isi lorem egestas vitae scel<span id="dots2">...</span><span id="more2">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction('dots2','more2','myBtn2')" id="myBtn2">Read more</button>
use template literals like this:
function myFunction(number) {
var dots = document.getElementById(`dots${number}`);
var moreText = document.getElementById(`more${number}`);
var btnText = document.getElementById(`myBtn${number}`);
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read more";
moreText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read less";
moreText.style.display = "inline";
}
}
<button onclick="myFunction('')" id="myBtn">Read more</button>
<button onclick="myFunction2('2')" id="myBtn2">Read more</button>
I guess this answer was not really called for. In my opinion #RandyCasburn already nailed it. However, here is another version that works with even less html to put in place to create unfoldable sections.
By placing a <span class="more"></span> within a paragraph this section is marked to be "unfoldable". The first part of my script adds the three dots and a "Read more" button and makes the span's original content invisible.
The delegated click event handler then does all the work:
// prepare document once (put "..." and buttons in place):
document.querySelectorAll(".more").forEach(el=>{
el.dataset.html=el.innerHTML;
el.textContent="...";
const btn=document.createElement("button");
btn.className="morebtn";
btn.textContent="Read more";
el.closest("p").after(btn);
})
// delegated event attachment:
document.body.onclick=e=>{
if (e.target.className==="morebtn"){
const mor = e.target.previousElementSibling.querySelector(".more");
[mor.innerHTML,mor.dataset.html]=[mor.dataset.html,mor.innerHTML];
e.target.innerHTML = mor.textContent==="..."?"Read more":"Read less";
}
}
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span class="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, naliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida isi lorem egestas vitae scel<span class="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<p>And another paragraph with more nonsensical text that will only <span class="more">be shown completely, once the "Read more" button was hit.</span></div>

How to apply fade animation or any other animation from display none to display block?

I have provided the javascript code that I have used to apply to hide and appear the read more text on clicking the button and it is working very fine but now the client wants that the text should appear and hide with any animation. I don't know what should I apply fade or slide or something else to show it to the client. I don't know how to do that.
function ReadmoreFunction() {
var dots = document.getElementById("dots");
var moreText = document.getElementById("more-text");
var btnText = document.getElementById("readMoreBtn");
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read more";
moreText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read less";
moreText.style.display = "inline";
}
}
#more-text{
display: none;
transition: 2s;
}
#readMoreBtn{
background: #ff963b;
color: #fff;
border:1px solid #ff963b;
border-radius: 5px;
padding: 7px 5px;
}
<div class="category-description std">
<h2 style="text-align:=justify;"><strong>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</strong></h2>
<p style="text-align:=justify;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur efficitur sodales erat luctus blandit. Vestibulum rutrum tellus fermentum massa pharetra maximus. Morbi sit amet metus vel massa tempus iaculis. Ut sit amet ligula dolor. Nam a sem at est sagittis volutpat. Vestibulum dapibus et orci eu placerat. Suspendisse placerat quis elit sed fringilla. Praesent finibus vestibulum augue in auctor. Etiam interdum dolor mi, ut facilisis magna malesuada ut. Fusce sed eros nibh.</p><span id="dots"></span>
<span id="more-text">
<h2 style="text-align:=justify;"><strong>**Get best quality art and craft supplies within your budget**</strong></h2>
<p style="text-align:=justify;">Integer hendrerit suscipit quam ultrices tristique. Integer vel tortor vel risus ultrices tempus tempor a mauris. Etiam venenatis, elit non aliquam sollicitudin, diam tellus dictum lacus, ac scelerisque metus purus nec quam. Donec elementum vitae erat sed condimentum. Aliquam at lorem mollis, porttitor dui at, finibus magna. Aliquam id efficitur lectus, eu ultricies nibh. Nam et posuere mauris, eget hendrerit nisi. Curabitur non tortor enim.</p>
<h2 style="text-align:=justify;"><strong>Lorem ipsum dolor sit amet, consectetur adipiscing elit. </strong></h2>
<p style="text-align:=justify;">Integer hendrerit suscipit quam ultrices tristique. Integer vel tortor vel risus ultrices tempus tempor a mauris. Etiam venenatis, elit non aliquam sollicitudin, diam tellus dictum lacus, ac scelerisque metus purus nec quam. Donec elementum vitae erat sed condimentum. Aliquam at lorem mollis, porttitor dui at, finibus magna. Aliquam id efficitur lectus, eu ultricies nibh. Nam et posuere mauris, eget hendrerit nisi. Curabitur non tortor enim.</p></span>
</div>
<center><button onclick="ReadmoreFunction()" id="readMoreBtn">Read more</button></center>
Ok here I made some changes to your code to use font-size instead of display, to apply transition effect
function ReadmoreFunction() {
var dots = document.getElementById("dots");
var moreText = document.getElementById("more-text");
var btnText = document.getElementById("readMoreBtn");
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read more";
moreText.style.fontSize = "0";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read less";
moreText.style.fontSize = "initial";
}
}
#more-text{
font-size: 0;
transition: 1s font-size;
}
#readMoreBtn {
background: #ff963b;
color: #fff;
border:1px solid #ff963b;
border-radius: 5px;
padding: 7px 5px;
}
<div class="category-description std">
<h2 style="text-align:=justify;"><strong>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</strong></h2>
<p style="text-align:=justify;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur efficitur sodales erat luctus blandit. Vestibulum rutrum tellus fermentum massa pharetra maximus. Morbi sit amet metus vel massa tempus iaculis. Ut sit amet ligula dolor. Nam a sem at est sagittis volutpat. Vestibulum dapibus et orci eu placerat. Suspendisse placerat quis elit sed fringilla. Praesent finibus vestibulum augue in auctor. Etiam interdum dolor mi, ut facilisis magna malesuada ut. Fusce sed eros nibh.</p><span id="dots"></span>
<span id="more-text">
<h2 style="text-align:=justify;"><strong>**Get best quality art and craft supplies within your budget**</strong></h2>
<p style="text-align:=justify;">Integer hendrerit suscipit quam ultrices tristique. Integer vel tortor vel risus ultrices tempus tempor a mauris. Etiam venenatis, elit non aliquam sollicitudin, diam tellus dictum lacus, ac scelerisque metus purus nec quam. Donec elementum vitae erat sed condimentum. Aliquam at lorem mollis, porttitor dui at, finibus magna. Aliquam id efficitur lectus, eu ultricies nibh. Nam et posuere mauris, eget hendrerit nisi. Curabitur non tortor enim.</p>
<h2 style="text-align:=justify;"><strong>Lorem ipsum dolor sit amet, consectetur adipiscing elit. </strong></h2>
<p style="text-align:=justify;">Integer hendrerit suscipit quam ultrices tristique. Integer vel tortor vel risus ultrices tempus tempor a mauris. Etiam venenatis, elit non aliquam sollicitudin, diam tellus dictum lacus, ac scelerisque metus purus nec quam. Donec elementum vitae erat sed condimentum. Aliquam at lorem mollis, porttitor dui at, finibus magna. Aliquam id efficitur lectus, eu ultricies nibh. Nam et posuere mauris, eget hendrerit nisi. Curabitur non tortor enim.</p>
</span>
<center><button onclick="ReadmoreFunction()" id="readMoreBtn">Read more</button></center>
</div>

Read More collapse script change

I want to be able to collapse each "read-more" for its own section. The code is borrowed from w3schools and trying to modify by adding a second section. But the second button expands s the first text. I understand (from reading on other sections) I will have to modify the id for elements so that each section is self-contained. What do I need to modify this behavior? This is a new area for me, be gentle ...
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
#more {display: none;}
</style>
</head>
<body>
<h2>One</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span id="dots">...</span><span id="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction()" id="myBtn">Read more</button>
<h2>Two</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span id="dots">...</span><span id="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction()" id="myBtn">Read more</button>
<script>
function myFunction() {
var dots = document.getElementById("dots");
var moreText = document.getElementById("more");
var btnText = document.getElementById("myBtn");
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read more";
moreText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read less";
moreText.style.display = "inline";
}
}
</script>
</body>
</html>
You have to change all your IDs with classes, for example, 'cause IDs must be unique in a page.
After that, a solution could be to insert the 2 texts in 2 divs, passing this element to the myFunction to select the right parent box to work on.
function myFunction(elmnt) {
var myID = elmnt.parentNode;
var dots = myID.getElementsByClassName("dots")[0];
var moreText = myID.getElementsByClassName("more")[0];
var btnText = myID.getElementsByClassName("myBtn")[0];
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read more";
moreText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read less";
moreText.style.display = "inline";
}
}
.more {display: none;}
<div>
<h2>One</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span class="dots">...</span><span class="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction(this)" class="myBtn">Read more</button>
</div>
<div>
<h2>Two</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span class="dots">...</span><span class="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction(this)" class="myBtn">Read more</button>
</div>
EDIT 1
You have to change all IDs 'cause they must be unique in a page. You can't use them for another textbox. So if you want to use 2,3,4... several textboxes, you have to transform all IDs in classes.
In my example, I changed a little the script to manage those classes, not IDs. Copy and paste my code in w3school snippet, click "Run" and you'll see it work. I changed the name of variable myID in parentElement so maybe it is more clear to you.
The script var dots = parentElement.getElementsByClassName("dots")[0]; means find first element that has a class named "dots" in my parentElement (i.e. the external div that I added)
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
.more {display: none;}
</style>
</head>
<body>
<div>
<h2>One</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span class="dots">...</span><span class="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction(this)" class="myBtn">Read more</button>
</div>
<div>
<h2>Two</h2>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus imperdiet, nulla et dictum interdum, nisi lorem egestas vitae scel<span class="dots">...</span><span class="more">erisque enim ligula venenatis dolor. Maecenas nisl est, ultrices nec congue eget, auctor vitae massa. Fusce luctus vestibulum augue ut aliquet. Nunc sagittis dictum nisi, sed ullamcorper ipsum dignissim ac. In at libero sed nunc venenatis imperdiet sed ornare turpis. Donec vitae dui eget tellus gravida venenatis. Integer fringilla congue eros non fermentum. Sed dapibus pulvinar nibh tempor porta.</span></p>
<button onclick="myFunction(this)" class="myBtn">Read more</button>
</div>
<script>
function myFunction(elmnt) {
var parentElement = elmnt.parentNode;
var dots = parentElement.getElementsByClassName("dots")[0];
var moreText = parentElement.getElementsByClassName("more")[0];
var btnText = parentElement.getElementsByClassName("myBtn")[0];
if (dots.style.display === "none") {
dots.style.display = "inline";
btnText.innerHTML = "Read more";
moreText.style.display = "none";
} else {
dots.style.display = "none";
btnText.innerHTML = "Read less";
moreText.style.display = "inline";
}
}
</script>
</body>
</html>

JavaScript class to modify a paragraph using click handlers

Create a JavaScript class "ModifyParagraph", here constructor accepts paragraph element. inside the constructor, create 4 buttons (which change the paragraph, Bold, color, size, position) using document.createElement and add click event handler on each. Click handler on bold button will turn on/off the boldness.
My code:
HTML
<!DOCTYPE html>
<html>
<head>
<title>Question-2</title>
<meta charset="UTF-8">
<script src="q2.js"></script>
<link rel="stylesheet" href="q2.css" />
</head>
<body>
<div id="myDIV" style="width:500px; ">Lorem ipsum dolor sit amet, porttitor ut donec ut egestas, purus urna consectetuer, arcu et vitae elementum nulla etiam in, sit leo lacus. Ligula cras tortor dignissim laoreet ut, nonummy hendrerit mauris, vitae augue congue congue, vel et augue, eros at. Fringilla id donec libero mauris eleifend. Nulla nunc sit. Consequat sodales placerat faucibus mauris, urna lectus vitae, sit nisl laoreet libero at suscipit ut, neque laoreet dapibus sapien. Sodales sit ut metus commodo tellus, ultricies cursus, et faucibus vitae quam, sit ultrices rhoncus. Massa duis mauris arcu vulputate, iste orci porttitor a ac, quisque venenatis pellentesque in in velit sed, repellat lorem consectetur vero, urna tellus donec. Suscipit in, donec beatae, lectus bibendum morbi justo consectetuer ac, facilisis metus vel non sapien vel. Magna congue vitae quia nulla nulla, lorem enim urna augue et et, sem morbi lorem ornare velit neque morbi, erat id et blandit iaculis.</div>
</body>
</ul>
</html>
JavaScript
class ModifyParagraph{
constructor(myDIV){
this.myDIV = myDIV;
function myFunction(){
var btn = document.createElement("BUTTON");
var bold = document.getElementById(myDIV);
btn.addEventListener('click', function(){
if (bold.style['font-weight']) {
bold.style.removeProperty('font-weight');
} else {
bold.style['font-weight'] = "800";
}
}
}
}
}
In my code, I have a problem in creating a button inside the constructor and adding click handlers on each button. Please let me know how to proceed
Apart from your syntax mistakes(I'll cover them later in the answer), your main issue is that you missed to append the created button to the DOM.
Here's a working demo:
class ModifyParagraph {
constructor(div) {
this.myDIV = div;
}
toggleBoldStyle() {
// create the button.
var btn = document.createElement('button');
// give it some text/value.
btn.textContent = 'toggle Bold styling';
// add click event listener to the button.
btn.addEventListener('click', function() {
// if the font-weight is 800 make it 'normal' else if it's other than 800 make it 800'
// add the 'this' keyword in the addEventListener method references the button, to get the member myDIV we'll just call it without preceding it by 'this'(myDIV in place of this.myDIV).
myDIV.style.fontWeight = (myDIV.style.fontWeight === '800') ? 'normal':'800';
});
// append the button to the DOM
this.myDIV.appendChild(btn);
}
}
// testing...
var p = new ModifyParagraph(document.getElementById('myDIV'));
p.toggleBoldStyle();
<div id="myDIV" style="width:500px; ">Lorem ipsum dolor sit amet, porttitor ut donec ut egestas, purus urna consectetuer, arcu et vitae elementum nulla etiam in, sit leo lacus. Ligula cras tortor dignissim laoreet ut, nonummy hendrerit mauris, vitae augue congue congue, vel et augue, eros at. Fringilla id donec libero mauris eleifend. Nulla nunc sit. Consequat sodales placerat faucibus mauris, urna lectus vitae, sit nisl laoreet libero at suscipit ut, neque laoreet dapibus sapien. Sodales sit ut metus commodo tellus, ultricies cursus, et faucibus vitae quam, sit ultrices rhoncus. Massa duis mauris arcu vulputate, iste orci porttitor a ac, quisque venenatis pellentesque in in velit sed, repellat lorem consectetur vero, urna tellus donec. Suscipit in, donec beatae, lectus bibendum morbi justo consectetuer ac, facilisis metus vel non sapien vel. Magna congue vitae quia nulla nulla, lorem enim urna augue et et, sem morbi lorem ornare velit neque morbi, erat id et blandit iaculis.</div>
Apart from missing to append the button to the DOM, you had some mistakes:
Class methods doesn't require the 'function' keyword, you have to just write the method name.
You missed a closing parenthesis of the addEventListener method.
Why you're trying to get the element that you just saaved in the muyDIV member. Better, you have two choices: send the element itself to the constructor or send it's ID and in the assignment to the myDIV member you fetch the element by the getElementById method. In my demo I sent the element itself to the constructor. But, you can make things more complicated to allow sending the ID or the element itself possible, innthe constructor you have to check the type of the incoming argument.
Finally, here's the link of the MDN documentation of the ECMAScript 5 classes.
Hope I pushed you further.
My code,
HTML:
<!DOCTYPE html>
<html>
<head>
<title>Question-2</title>
<meta charset="UTF-8">
<script src="q2.js"></script>
</head>
<body>
<div id="myDIV" style="width:500px; ">Lorem ipsum dolor sit amet, porttitor ut donec ut egestas, purus urna consectetuer, arcu et vitae elementum nulla etiam in, sit leo lacus. Ligula cras tortor dignissim laoreet ut, nonummy hendrerit mauris, vitae augue congue congue, vel et augue, eros at. Fringilla id donec libero mauris eleifend. Nulla nunc sit. Consequat sodales placerat faucibus mauris, urna lectus vitae, sit nisl laoreet libero at suscipit ut, neque laoreet dapibus sapien. Sodales sit ut metus commodo tellus, ultricies cursus, et faucibus vitae quam, sit ultrices rhoncus. Massa duis mauris arcu vulputate, iste orci porttitor a ac, quisque venenatis pellentesque in in velit sed, repellat lorem consectetur vero, urna tellus donec. Suscipit in, donec beatae, lectus bibendum morbi justo consectetuer ac, facilisis metus vel non sapien vel. Magna congue vitae quia nulla nulla, lorem enim urna augue et et, sem morbi lorem ornare velit neque morbi, erat id et blandit iaculis.</div>
</body>
</ul>
</html>
JavaScript
class ModifyParagraph {
constructor(div) {
this.myDIV = div;
}
toggleBoldStyle() {
// create the button.
var btn = document.createElement('button');
// give it some text/value.
btn.textContent = 'toggle Bold styling';
// add click event listener to the button.
btn.addEventListener('click', function() {
// if the font-weight is 800 make it 'normal' else if it's other than 800 make it 800'
// add the 'this' keyword in the addEventListener method references the button, to get the member myDIV we'll just call it without preceding it by 'this'(myDIV in place of this.myDIV).
myDIV.style.fontWeight = (myDIV.style.fontWeight === '800') ? 'normal':'800';
});
// append the button to the DOM
this.myDIV.appendChild(btn);
}
}
// testing...
var p = new ModifyParagraph(document.getElementById('myDIV'));
p.toggleBoldStyle();

Javascript and Html; get page from URL

I am creating a website for a client and they have given me some very strict limitations. The html must be coded in one document (index.html), with the javascript and css each in their own separate document. They also want me to use Angular or Node only if necessary (it has not been necessary so far).
Since they are requiring multiple “pages” on the website, I am using Javascript to hide or unhide different divs corresponding to each page. I also have the separate divs internally referenced. Therefore, when the maps “page” is open the URL displays as https:\\site.com\#maps . When the page gets reloaded, it ignores the #maps and simply returns to the main “page”.
I have tried using window.location to get the url when the page is loaded, then pass that to my function; however, that has not worked. I also briefly tried messing with cookies to save the page location, but wasnt able to get very far with it.
How can I get the function to load the page I want based on the url?
function openPage(evt, PageName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the link that opened the tab
document.getElementById(PageName).style.display = "block";
evt.currentTarget.className += " active";
//set the page cookie
var expiry = new Date();
expiry.setTime(expiry.getTime()+600000);
expires = "; expires=" + expiry.toUTCString();
document.cookie = "Page=" + PageName + expires + " ; path=/";
}
Well, each div element has to have the id attribute, this attribute identifies the page/div and will be set as value for the window.location.hash.
Than handle all click events which trigger the page change, for instance all a elements with href attribute set to these ids.
Then create function which will show/hide the desired page, and call this method when the whole html page is loaded.
Here is an example using jQuery (if you want there is no need to use jQuery, you can do it with vanilla javascript as well):
$(function() {
// Method wich show/hide pages
function showpage(target) {
// Target is the id of the page div
var $target = $(target);
// If there is not any page with that id do nothing
if(!$target.length) {
return;
}
// Hide all pages
$(".page").css("display", "none");
// Show the target page
$target.css("display", "block");
// Update the window has
window.location.hash = target;
}
// Handle clicks which show pages
$(document).on("click", "a[href^='#']", function (e) {
e.preventDefault();
showpage($(this).attr("href"));
});
showpage(window.location.hash);
});
.page {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul>
<li>
page1
</li>
<li>
page2
</li>
<li>
page3
</li>
<li>
page4
</li>
</ul>
<div id="page1" class="page">
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus interdum velit pretium porttitor aliquam. Proin a lectus nec ligula laoreet tempor. In ornare volutpat velit, non semper mauris accumsan nec. Aliquam nibh nisi, pellentesque eu mauris eu, fringilla faucibus leo. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vestibulum pretium, tortor eget scelerisque luctus, enim quam elementum diam, ac varius elit tortor eu tortor. Morbi molestie massa nec aliquam fringilla.
</div>
<div id="page2" class="page">
Maecenas sagittis convallis turpis, sed fermentum magna porttitor eget. Aenean et lectus eu velit interdum aliquet. Duis faucibus sollicitudin iaculis. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent suscipit pulvinar felis, at fermentum dolor ultrices non. Maecenas malesuada urna lorem, mollis lobortis nisi semper et. Quisque ac tellus interdum, hendrerit nisl eu, feugiat ante. Nullam tincidunt ex non metus venenatis suscipit. Duis rutrum convallis erat, quis ultrices nunc efficitur sed. Donec lacinia tellus eu neque tempus, eu bibendum odio sollicitudin. Nullam convallis ligula vitae sapien tristique, eget ullamcorper risus pulvinar. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Donec tincidunt, sapien vel eleifend laoreet, tortor dolor ultrices est, consequat suscipit neque metus a velit. Maecenas cursus nec arcu et varius. Nulla ex lorem, mollis eu risus quis, molestie dapibus nisl. Maecenas vel imperdiet mauris, ut pretium odio.
</div>
<div id="page3" class="page">
Donec mi mi, placerat tincidunt justo sit amet, facilisis congue sapien. Nunc lacinia lobortis turpis ac rhoncus. Donec tempus elit vitae pharetra congue. Nam at dolor at metus hendrerit pharetra nec et velit. Morbi iaculis ipsum non finibus hendrerit. Nunc eget ex non augue feugiat venenatis a sit amet nisl. Vestibulum elementum ipsum non enim pulvinar malesuada. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis et purus vitae libero lobortis gravida et eu lectus. Aenean dignissim molestie ante a iaculis.
</div>
<div id="page4" class="page">
Pellentesque iaculis diam a condimentum aliquam. Integer vestibulum interdum ligula, quis tempus felis aliquam at. Ut vel tincidunt purus, quis convallis ipsum. Pellentesque massa velit, varius gravida purus nec, consectetur suscipit nibh. Vivamus vel dui sit amet magna condimentum sodales ac a urna. Sed viverra, dolor sit amet facilisis commodo, tortor massa efficitur neque, sit amet sollicitudin lectus augue sed est. Nulla dapibus facilisis magna, vestibulum maximus dui gravida convallis. Sed sit amet tellus non velit tincidunt mollis vitae vitae purus. Donec sed molestie lacus. Morbi condimentum sapien nec odio scelerisque bibendum.
</div>
Use the onload property on your body tag:
<body onload="pageLoaded(window.location.hash)">
https://www.w3schools.com/jsref/event_onload.asp

Categories