Coordinate the toggling of classList and changing of innerHTML with a Javascript button

I am trying to create a toggle button that displays two different messages using innerHTML, along with applying CSS classes from Bootstrap 4 and toggling classes with classList.toggle.

The "Read more" message should be displayed on a blue button with an up arrow icon inside a circle, styled with the classes btn btn-primary. The "Read Less" message should appear on a green button with a down arrow icon inside a circle, styled with the classes btn btn-success.

Fontawesome icons are being used for the arrow icons.

It is essential to work with CSS classes as I am implementing Bootstrap styles for each button.

However, when I run this code, the result is not synchronous after clicking the button three times.

Thank you all for your help.

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css"/>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.2/js/bootstrap.min.js"></script>
    <script src='https://kit.fontawesome.com/a076d05399.js' crossorigin='anonymous'></script>
    <style>
        #more {
            display: none;
        }
    </style>
</head>
<body>
    <h2>Read More Read Less Button</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 type="button" class="btn btn-primary" onclick="myFunction()" id="myBtn">
        Read more <i class="fas fa-arrow-alt-circle-up"></i>
    </button>

    <script>
        function myFunction() {
            var dots = document.getElementById("dots");
            var moreText = document.getElementById("more");
            var btnText = document.getElementById("myBtn");
            var switchCss = document.getElementById("myBtn");

            if (dots.style.display === "none") {
                dots.style.display = "inline";
                btnText.innerHTML = "Read more <i class='fas fa-arrow-alt-circle-up'></i>";
                switchCss.classList.toggle("btn-primary");
                moreText.style.display = "none";
            } else {
                dots.style.display = "none";
                btnText.innerHTML = "Read less <i class='   fas fa-arrow-alt-circle-down'></i>";
                switchCss.classList.toggle("btn-success");
                moreText.style.display = "inline";
            }
        }
    </script>
</body>
</html>

Answer №1

To resolve the color issue, you can either make this modification or try a different approach by removing the previous class name and adding a new one to the button. This should prevent the problem of overwriting that occurs after the third click.

 if (dots.style.display === "none") {
                    dots.style.display = "inline";
                    btnText.innerHTML = "Read more <i class='fas fa-arrow-alt-circle-up'></i>";
                    switchCss.style.background="blue";
                    moreText.style.display = "none";
                } else {
                    dots.style.display = "none";
                    btnText.innerHTML = "Read less <i class='   fas fa-arrow-alt-circle-down'></i>";
                    switchCss.style.background="green";
                    moreText.style.display = "inline";
                }

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

jQuery command to display a div element when a button is clicked

Hey there, I'm trying to display a div element in jQuery mobile when the user touches the button. I have already created custom classes for both the button and div element but unfortunately, nothing seems to happen. Can anyone tell me which classes I ...

What is the best way to resize an iframe containing a video to match the size of its parent

When using CSS, it is possible to stretch and adjust the ratio of an image to fully cover its parent div. The image will also resize accordingly if the parent div is responsive. Is this same effect achievable with videos (iframe) as well? EDIT: I am conce ...

Column content merging in BS layout

Currently, I am exploring how to implement a two-column layout with the left column serving as a scrollable navbar. At this early stage of development, please excuse any imperfections in the code! One issue that arose involved using the .sidebar class wit ...

Is it possible to apply search filters within a child component in Angular?

I have a situation where I am passing data from a parent component to a child component using *ngFor / @input. The child component is created multiple times based on the number of objects in the pciData array. pciData consists of around 700 data objects, ...

Properly extending the functionality of an HTML widget

Understanding HTML and CSS layout is still a mystery to me, so any guidance on what I'm trying to achieve would be greatly appreciated. I am currently developing a JavaScript API for our company's "widget" so that users can integrate it into the ...

Frequent occurrence of unexpected 'Assertion failed' messages observed on Apple M1 chip

After making the switch from Windows 10 to Mac OS with the latest Apple M1 Silicon, I embarked on my first project on the Mac. I decided to use homebrew to install both node and yarn: brew install node brew install yarn yarn global add @vue/cli My Vue pro ...

Webview displaying a blank screen following the most recent Chrome update

I am encountering a problem that has been asked previously, but I am struggling to find a solution. The issue arises when I try to play an embedded video URL on the Webview and filter out other undesirable URLs using shouldOverrideUrlLoading. Whenever I cl ...

What is the best way to convert a dynamic HTML table with input fields into an Excel spreadsheet?

I have developed a JavaScript function to convert an HTML table into an Excel sheet. However, I am facing an issue where some fields in the table are enclosed in input tags instead of td tags, causing them to not appear in the Excel sheet. function expo ...

Exploring the seamless integration of Material UI with React version 18

I am having an issue with my background not turning black in React version 18.2.0 when using makeStyles from Material UI version 4. Despite no errors in the code, the background remains unchanged. How can I fix this problem? import './App.css'; i ...

Personalized AJAX characteristic inside AngularJs Service

Let's consider a very simple scenario: Here is the code snippet: $.ajax({ type: "GET/POST", url: 'http://somewhere.net/', data: data, beforeSend: '', // custom property }).done().fail(); My main goal is to find a ...

The functionality of "perfect-scrollbar" (jQuery plugin) may not be properly initialized when the container it is in is being populated by Angular.js

I have a unique setup on my website where I dynamically generate food and drinks menus using a json file with Angular.js. The issue arises with the implementation of "perfect-scrollbar", which seems to require a scroll-wheel event to work properly on these ...

An error occurred due to an unexpected token at the position of `>` of a `<>

I'm in the process of learning how to create a Tic-Tac-Toe game using React by following the tutorial found here. However, I encountered a syntax error when trying to run npm start, specifically around the use of <>. Steps to Recreate the Error ...

Ways to create distance between columns in Bootstrap 5

screenshot i want like this Looking at the image provided, there seems to be an issue with spacing between the red and blue columns. Despite trying various Bootstrap classes, the desired result has not been achieved. Adding m-4 to the Navbar, Header, and ...

Tips for formatting HTML to showcase two data cards when printing a page

My XML data input document can be neatly transformed into printable data cards, whether it's 2 to a page, 4 to a page, 9 to a page, or any other configuration. What is the most effective method for styling the data to fit the printing layout? How can ...

What is the best way to use checkboxes to highlight table rows in Jquery Mobile?

I have a Jquery Mobile site with a table. Each table row contains checkboxes in the first cell. I am trying to achieve the following: a) Highlight a row when the user clicks on it b) Highlight a row when the user checks the checkbox I have made progr ...

Complete view of OpenLayers map in the UI window

I am currently working on an angularjs app with Angular Material built using the yeoman fullstack generator. In my index.html file, I have a navbar and a ui-view that displays the site's content. <!-- index.html --!> <!-- Add your site or ap ...

Exploring the benefits of incorporating the vendor folder in website development

I'm embarking on the journey of creating a website from scratch with python, django, and bootstrap. I've noticed that it's common practice to store js, css, img, and fonts in a folder named vendor, like this: /static/js/vendor/bootstrap/boo ...

Filtering an array of objects in React based on user input

(React Challenge) Imagine we have an array of objects structured like this: const books = [ { author: "Marcel Proust", title: "In Search of Lost Time", pageNumber: 123, }, { author: ...

How to override the styling of a parent element in CSS

I'm encountering an issue with my website's sidebar. I've set the background color to yellow for elements with the currentPage class. This works fine for the 'Home' tab, but when I try to do the same for a nested tab like 'tag ...

What could be the reason for sending XmlHttpRequest even if ClientValidation has failed?

Having multiple AJAX forms on my page poses a challenge when I need to submit them all on button click. Simply iterating over the forms with forms.each(function (index, form) { $(form).submit();} won't work as expected because only the last form gets ...