Sachin Jadhav
Sachin Jadhav

Reputation: 124

JavaScript not working in chrome but working in Firefox

I made a website in which content changes when the user clicks on a toggle switch, the price changes from monthly to annual, and vice versa when a user clicks on the toggle i.e. the h2 with the class monthly gets displayed when toggler is checked(true) and the h2 with class annual gets displayed when toggler is unchecked(false).

function refreshPage(){
    window.location.reload();
} 
const toggler = document.querySelector("#switch");
const annual = document.querySelectorAll(".annual");
const monthly = document.querySelectorAll(".monthly");
window.onload = function priceChange(){
    if (toggler.checked === false) {
        monthly.forEach(hideMonthly);
        function hideMonthly(item) {
            item.style.display = "none";
        }
    } else if (toggler.checked === true ) {
        annual.forEach(hideAnnual);
        function hideAnnual(item) {
            item.style.display = "none";
        }
    }
}
:root {
    --gradient: linear-gradient(to bottom right, hsl(236, 72%, 79%), hsl(237, 63%, 64%));
    --gradient-900: hsl(237, 63%, 64%);
    --neutral-grey-100: hsl(240, 78%, 98%);
    --neutral-grey-300: hsl(234, 14%, 74%);
    --neutral-grey-600: hsl(233, 13%, 49%);
    --neutral-grey-900: hsl(232, 13%, 33%);
    --neutral-100: #fff;
    --neutral-900: #000;
}

*,
*::after, 
*::before {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-size: 15px;
    font-family: 'Montserrat', sans-serif;
    background: #F6F6FE url("../images/bg-top.svg") no-repeat;
    background-position: top right -170px; 
    text-align: center;
}

.neutral-grey-100 {
    color: var(--neutral-grey-100);
}

.neutral-grey-300 {
    color: var(--neutral-grey-300);
}

.neutral-grey-600 {
    color: var(--neutral-grey-600);
}

.neutral-grey-900 {
    color: var(--neutral-grey-900);
}

h1 {
    font-size: 2em;
    margin-bottom: .8em;
}

h2 {
    font-size: 3em;
    margin: 1rem 0;
}

.container {
    width: 85%;
    margin: 0 auto;
}

.header {
    padding: 2.4em;
}

.card {
    display: flex;
    flex-direction: column;
    background-color: var(--neutral-100);
    border-radius: .8em;
    padding: 1em 2.6em;
    margin-bottom: 2.5em;
    box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
}

.card:nth-child(odd) {
    background: var(--gradient);
    color: var(--neutral-100);
}

.card > div:not(:last-child) {
    border-bottom: 1px solid rgba(183, 184, 194, 0.45);
}

.card-inverse > div:not(:last-child) {
    border-bottom: 1px solid rgba(255, 255, 255, 0.35);
}

section div {
    padding: 1em 0;
}

.button {
    text-transform: uppercase;
    padding: 1em 2em;
    margin: 2.6em 0 1.2em 0;
    background: var(--gradient);
    border: 1px solid var(--neutral-100);
    border-radius: 6px;
    text-decoration: none;
    color: var(--neutral-100);
}

.button:hover, .button:focus {
    background: var(--neutral-100);
    border: 1px solid hsl(237, 63%, 24%);
    color: var(--gradient-900);
    outline: none;
}

.button-inverse {
    background: var(--neutral-100);
    text-decoration: none;
    color: var(--gradient-900);
}

.button-inverse:hover, .button-inverse:focus {
    background: hsl(237, 63%, 64%);
    border: 1px solid var(--neutral-100);
    color: var(--neutral-100);
    outline: none;
}

.attribution { 
    font-size: 11px; 
    text-align: center; 
    margin-bottom: 1rem;
}

.attribution a { 
    color: hsl(228, 45%, 44%); 
}

/*-------- TOGGLER --------*/

 .toggle {
    display: flex;
    justify-content: center;
    align-items: center;
}

input[type=checkbox]{
    height: 0;
    width: 0;
    visibility: hidden;
}

label {
    cursor: pointer;
    text-indent: -9999px;
    width: 65px;
    height: 35px;
    background: var(--gradient);
    display: block;
    border-radius: 100px;
    position: relative;
    margin: 1.4em;
}

label:after {
    content: '';
    position: absolute;
    top: 4px;
    left: 4px;
    width: 27px;
    height: 27px;
    background: #fff;
    border-radius: 110px;
    -webkit-transition: all 350ms;
        -moz-transition: all 350ms;
            transition: all 350ms; 
}

input:checked + label {
    background: var(--gradient);
}

input + label:hover, input + label:focus-within {
    background: hsl(236, 72%, 81%)
}

input:checked + label:after {
    transform: translate3d(114%, 0, 0);
}

@media (min-width: 1440px) {
    body {
        font-size: 16px;
        background-image: url("../images/bg-top.svg"), url("../images/bg-bottom.svg");
        background-repeat: no-repeat, no-repeat;
        background-position: 100% 0%, 0% 130%; 
        background-size: 24%, 24%;
    }

    .container {
        display: grid;   
        grid-template-areas: 
            "header header header"
            "basic professional master"
            "attribution attribution attribution"; 
        align-items: center;
        width: 65%;
    }

    .header {
        grid-area: header;
    }

    h2 {
        font-size: 4em;
    }

    h3 {
        font-size: 1.3033333333333335em;
    }

    .card-inverse {
        padding: 3em 2em;
    }

    .card {
        margin-bottom: 0;
    }

    #basic {
        grid-area: basic;
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
    }
    
    #professional {
        grid-area: professional;
    }
    
    #master {
        grid-area: master;
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
    }

    .attribution {
        grid-area: attribution;
        margin-top: 4em;
    }
}
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- displays site properly based on user's device -->

    <link rel="icon" type="image/png" sizes="32x32" href="./images/favicon-32x32.png">
    <link rel="stylesheet" href="css/style.css">
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Montserrat:wght@700&display=swap" rel="stylesheet">
    <script defer src="js/script.js"></script>
    <title>Frontend Mentor | Pricing component with toggle</title>

</head>
<body>

    <div class="container">
        <section class="header">
            <h1 class="neutral-grey-900">Our Pricing</h1>
            <div class="toggle neutral-grey-300">
                Annually
                <input type="checkbox" id="switch" onClick="refreshPage()"/><label for="switch">Toggle</label>
                <!-- <label class="switch"><input type="checkbox" name="toggler" id="toggler" onClick="refreshPage()"/>    <figure></figure>
                </label> -->
                Monthly
            </div>
        </section>

        <section class="card" id="basic">
            <div>
                <h3 class="neutral-grey-600">Basic</h3>
            
                <h2 class="neutral-grey-900 monthly">&dollar;19.99</h2>
                <h2 class="neutral-grey-900 annual">&dollar;199.99</h2>
            </div>
            
            <div class="neutral-grey-600">500 GB Storage</div>
            
            <div class="neutral-grey-600">2 Users Allowed</div>
            
            <div class="neutral-grey-600">Send up to 3 GB</div>

            <a class="button button-main" href="">Learn More</a>
        </section>
        
        <section class="card card-inverse" id="professional">
            <div>
                <h3>Professional</h3>
            
                <h2 class="monthly">&dollar;24.99</h2>
                <h2 class="annual">&dollar;249.99</h2>
            </div>
            
            <div>1 TB Storage</div>
            
            <div>5 Users Allowed</div>
            
            <div>Send up to 10 GB</div>
            
            <a class="button button-inverse" href="">Learn More</a> 
        </section>

        <section class="card" id="master">
            <div>
                <h3 class="neutral-grey-600">Master</h3>
                
                <h2 class="neutral-grey-900 monthly">&dollar;39.99</h2>
                <h2 class="neutral-grey-900 annual">&dollar;399.99</h2>
            </div>

            <div class="neutral-grey-600">2 TB Storage</div>
            
            <div class="neutral-grey-600">10 Users Allowed</div>
            
            <div class="neutral-grey-600">Send up to 20 GB</div>
            
            <a class="button button-main" href="">Learn More</a> 
        </section>
        
        <div class="attribution">
            Challenge by <a href="https://www.frontendmentor.io?ref=challenge" target="_blank">Frontend Mentor</a>.
            Coded by <a href="#">Sachin Jadhav</a>.
        </div>
    </div>
</body>
</html>

The toggle is working in Firefox but not in Chrome, I am not able to figure out what's wrong with my javascript.

Upvotes: 0

Views: 227

Answers (2)

TheBlueOne
TheBlueOne

Reputation: 496

You set onClick="refreshPage()" on your switch. So the page always reloads when someone tries to change its value (en-/disable it).

The default behavior of chrome is to loose/forget all the data that was entered before a reload for a formular, while firefox normally asks (or if the user wants it without a popup, defaults) to reenter all the data the user entered after the reload.

Thats why the reload is resetting the value in chrome and keeping it in firefox.

I would recommend to just not reload the page. That also brings better usablity.

Upvotes: 1

T.J. Crowder
T.J. Crowder

Reputation: 1074809

Your code is relying on Firefox remembering the state of the input and restoring it before the load handler fires on subsequent page loads. That's not something you can rely on cross-browser.

Instead, just handle the toggle without refreshing. And instead of manually looping the items, you can use a class on their container (or even body) to control them:

toggler.addEventListener("click", () => {
    document.body.classList.toggle("show-monthly", toggler.checked);
});

(And removing refreshPage entirely.)

With this additional CSS:

body .monthly {
    display: none;
}
body.show-monthly .monthly {
    display: block;
}
body.show-monthly .annual {
    display: none;
}

(Note that the second argument of classList.toggle doesn't work on obsolete browsers like IE, so you may need an if/else for those.)

const toggler = document.querySelector("#switch");
const annual = document.querySelectorAll(".annual");
const monthly = document.querySelectorAll(".monthly");
toggler.addEventListener("click", () => {
    document.body.classList.toggle("show-monthly", toggler.checked);
});
body .monthly {
    display: none;
}
body.show-monthly .monthly {
    display: block;
}
body.show-monthly .annual {
    display: none;
}

:root {
    --gradient: linear-gradient(to bottom right, hsl(236, 72%, 79%), hsl(237, 63%, 64%));
    --gradient-900: hsl(237, 63%, 64%);
    --neutral-grey-100: hsl(240, 78%, 98%);
    --neutral-grey-300: hsl(234, 14%, 74%);
    --neutral-grey-600: hsl(233, 13%, 49%);
    --neutral-grey-900: hsl(232, 13%, 33%);
    --neutral-100: #fff;
    --neutral-900: #000;
}

*,
*::after, 
*::before {
    margin: 0;
    padding: 0;
    box-sizing: border-box;
}

body {
    font-size: 15px;
    font-family: 'Montserrat', sans-serif;
    background: #F6F6FE url("../images/bg-top.svg") no-repeat;
    background-position: top right -170px; 
    text-align: center;
}

.neutral-grey-100 {
    color: var(--neutral-grey-100);
}

.neutral-grey-300 {
    color: var(--neutral-grey-300);
}

.neutral-grey-600 {
    color: var(--neutral-grey-600);
}

.neutral-grey-900 {
    color: var(--neutral-grey-900);
}

h1 {
    font-size: 2em;
    margin-bottom: .8em;
}

h2 {
    font-size: 3em;
    margin: 1rem 0;
}

.container {
    width: 85%;
    margin: 0 auto;
}

.header {
    padding: 2.4em;
}

.card {
    display: flex;
    flex-direction: column;
    background-color: var(--neutral-100);
    border-radius: .8em;
    padding: 1em 2.6em;
    margin-bottom: 2.5em;
    box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
}

.card:nth-child(odd) {
    background: var(--gradient);
    color: var(--neutral-100);
}

.card > div:not(:last-child) {
    border-bottom: 1px solid rgba(183, 184, 194, 0.45);
}

.card-inverse > div:not(:last-child) {
    border-bottom: 1px solid rgba(255, 255, 255, 0.35);
}

section div {
    padding: 1em 0;
}

.button {
    text-transform: uppercase;
    padding: 1em 2em;
    margin: 2.6em 0 1.2em 0;
    background: var(--gradient);
    border: 1px solid var(--neutral-100);
    border-radius: 6px;
    text-decoration: none;
    color: var(--neutral-100);
}

.button:hover, .button:focus {
    background: var(--neutral-100);
    border: 1px solid hsl(237, 63%, 24%);
    color: var(--gradient-900);
    outline: none;
}

.button-inverse {
    background: var(--neutral-100);
    text-decoration: none;
    color: var(--gradient-900);
}

.button-inverse:hover, .button-inverse:focus {
    background: hsl(237, 63%, 64%);
    border: 1px solid var(--neutral-100);
    color: var(--neutral-100);
    outline: none;
}

.attribution { 
    font-size: 11px; 
    text-align: center; 
    margin-bottom: 1rem;
}

.attribution a { 
    color: hsl(228, 45%, 44%); 
}

/*-------- TOGGLER --------*/

 .toggle {
    display: flex;
    justify-content: center;
    align-items: center;
}

input[type=checkbox]{
    height: 0;
    width: 0;
    visibility: hidden;
}

label {
    cursor: pointer;
    text-indent: -9999px;
    width: 65px;
    height: 35px;
    background: var(--gradient);
    display: block;
    border-radius: 100px;
    position: relative;
    margin: 1.4em;
}

label:after {
    content: '';
    position: absolute;
    top: 4px;
    left: 4px;
    width: 27px;
    height: 27px;
    background: #fff;
    border-radius: 110px;
    -webkit-transition: all 350ms;
        -moz-transition: all 350ms;
            transition: all 350ms; 
}

input:checked + label {
    background: var(--gradient);
}

input + label:hover, input + label:focus-within {
    background: hsl(236, 72%, 81%)
}

input:checked + label:after {
    transform: translate3d(114%, 0, 0);
}

@media (min-width: 1440px) {
    body {
        font-size: 16px;
        background-image: url("../images/bg-top.svg"), url("../images/bg-bottom.svg");
        background-repeat: no-repeat, no-repeat;
        background-position: 100% 0%, 0% 130%; 
        background-size: 24%, 24%;
    }

    .container {
        display: grid;   
        grid-template-areas: 
            "header header header"
            "basic professional master"
            "attribution attribution attribution"; 
        align-items: center;
        width: 65%;
    }

    .header {
        grid-area: header;
    }

    h2 {
        font-size: 4em;
    }

    h3 {
        font-size: 1.3033333333333335em;
    }

    .card-inverse {
        padding: 3em 2em;
    }

    .card {
        margin-bottom: 0;
    }

    #basic {
        grid-area: basic;
        border-top-right-radius: 0;
        border-bottom-right-radius: 0;
    }
    
    #professional {
        grid-area: professional;
    }
    
    #master {
        grid-area: master;
        border-top-left-radius: 0;
        border-bottom-left-radius: 0;
    }

    .attribution {
        grid-area: attribution;
        margin-top: 4em;
    }
}
<div class="container">
    <section class="header">
        <h1 class="neutral-grey-900">Our Pricing</h1>
        <div class="toggle neutral-grey-300">
            Annually
            <input type="checkbox" id="switch"/><label for="switch">Toggle</label>
            <!-- <label class="switch"><input type="checkbox" name="toggler" id="toggler" onClick="refreshPage()"/>    <figure></figure>
            </label> -->
            Monthly
        </div>
    </section>

    <section class="card" id="basic">
        <div>
            <h3 class="neutral-grey-600">Basic</h3>

            <h2 class="neutral-grey-900 monthly">&dollar;19.99</h2>
            <h2 class="neutral-grey-900 annual">&dollar;199.99</h2>
        </div>

        <div class="neutral-grey-600">500 GB Storage</div>

        <div class="neutral-grey-600">2 Users Allowed</div>

        <div class="neutral-grey-600">Send up to 3 GB</div>

        <a class="button button-main" href="">Learn More</a>
    </section>

    <section class="card card-inverse" id="professional">
        <div>
            <h3>Professional</h3>

            <h2 class="monthly">&dollar;24.99</h2>
            <h2 class="annual">&dollar;249.99</h2>
        </div>

        <div>1 TB Storage</div>

        <div>5 Users Allowed</div>

        <div>Send up to 10 GB</div>

        <a class="button button-inverse" href="">Learn More</a> 
    </section>

    <section class="card" id="master">
        <div>
            <h3 class="neutral-grey-600">Master</h3>

            <h2 class="neutral-grey-900 monthly">&dollar;39.99</h2>
            <h2 class="neutral-grey-900 annual">&dollar;399.99</h2>
        </div>

        <div class="neutral-grey-600">2 TB Storage</div>

        <div class="neutral-grey-600">10 Users Allowed</div>

        <div class="neutral-grey-600">Send up to 20 GB</div>

        <a class="button button-main" href="">Learn More</a> 
    </section>

    <div class="attribution">
        Challenge by <a href="https://www.frontendmentor.io?ref=challenge" target="_blank">Frontend Mentor</a>.
        Coded by <a href="#">Sachin Jadhav</a>.
    </div>
</div>

If you want to remember the setting for future visits, store it in localStorage and use it when loading the page:

const updatePriceDisplay = () => {
    document.body.classList.toggle("show-monthly", toggler.checked);
};
toggler.checked = localStorage.getItem("show-monthly") === "Y";
updatePriceDisplay();
toggler.addEventListener("click", () => {
    updatePriceDisplay();
    localStorage.setItem("show-monthly", toggler.checked ? "Y" : "N");
});

Upvotes: 1

Related Questions