0

The code detects a click outside an element and reloads the page. However, anytime a user clicks outside the page it keeps on reloading the page. How can I reload the page once when the user clicks outside the element?

The reason I want to do this is so when a user inputs text into a form and clicks away the other forms can be rendered with the updated contents. It wouldn't be ideal for the user to click outside the element and the page constantly reloading.

document.addEventListener("click", (evt) => {
    const flyoutElement = document.getElementById("flyout-example");
    let targetElement = evt.target; // clicked element

    do {
        if (targetElement == flyoutElement) {
            // This is a click inside. Do nothing, just return.
            document.getElementById("flyout-debug").textContent = "Clicked inside!";
            return;
        }
        // Go up the DOM
        targetElement = targetElement.parentNode;
    } while (targetElement);

    // This is a click outside.
    document.getElementById("flyout-debug").textContent = "Clicked outside!";
    location.reload();
});
body {
    font-family: "Arial", sans-serif;
}

h6 {
    margin: 0;
    font-size: .85rem;
    font-weight: normal;
    color: #999;
}

.flyout {
    position: absolute;
    top: 50px;
    left: 50px;
    padding: 1em;
    border: 1px solid rgba(16, 152, 173, .3);
    background: white;
    box-shadow: 0 .1rem .2rem rgba(0, 0, 0, .15);
}

.flyout-title {
    font-size: 1em;
    margin: 0 0 .5em 0;
}

.flyout-debug {
    min-height: 1.5em;
    margin: 0 0 .5em 0;
    font-size: .8em;
    color: #999;
}

.flyout-buttons {
    text-align: center;
}

.button {
    display: inline-block;
    box-sizing: border-box;
    margin: 0 .25em;
    padding: .5em 1em;
    border: .075rem solid rgba(0, 0, 0, .1);
    border-radius: .15em;
    background-color: #1098ad;
    background-image: linear-gradient(rgba(255, 255, 255, .2), rgba(255, 255, 255, 0));
    color: white;
    text-decoration: none;
    font-family: inherit;
    font-size: inherit;
    line-height: 1;
    box-shadow:
        0 .075rem .1rem rgba(0, 0, 0, .15),
        inset 0 .075rem rgba(255, 255, 255, .3);
}

.button:hover,
.button:focus {
    border-color: rgba(0, 0, 0, .5);
    background-image: linear-gradient(rgba(255, 255, 255, .1), rgba(0, 0, 0, .1));
}

.button:active {
    background-image: linear-gradient(rgba(0, 0, 0, .1), rgba(0, 0, 0, 0));
    box-shadow:
        inset 0 .075rem .1rem rgba(0, 0, 0, .2);
}

.button-outline {
    background-color: transparent;
    background-image: none;
    border-color: #1098ad;
    color: #1098ad;
    box-shadow: none;
}

.button-outline:hover,
.button-outline:focus {
    background-color: #1098ad;
    background-image: none;
    color: white;
}
<div class="flyout" id="flyout-example">
    <h5 class="flyout-title">This could be a flyout&hellip;</h5>
    <div class="flyout-debug" id="flyout-debug"></div>
    <div class="flyout-buttons">
        <button class="button button-outline" type="button">Cancel</button>
        <button class="button" type="button">Ok</button>
    </div>
</div>

3
  • 1
    Maybe you can set something in sessionStorage which checks if the outside has been clicked already? Commented Oct 19, 2020 at 17:17
  • The example reloads the page once. How do you mean it "keeps on reloading" the page? Commented Oct 19, 2020 at 17:30
  • 1
    @BenAston By "keeps on reloading page" I mean anytime I click outside the element the page reloads. I want the page to reload once when I click outside and the next time I click outside it shouldn't reload. Commented Oct 19, 2020 at 17:35

2 Answers 2

1

You can use session storage & add a key to maintain if the page was reloaded before.If the key exist in session storage,it mean it was loaded before. If not then add a key a reload it

document.addEventListener("click", (evt) => {
  const flyoutElement = document.getElementById("flyout-example");
  let targetElement = evt.target; // clicked element

  do {
    if (targetElement == flyoutElement) {
      // This is a click inside. Do nothing, just return.
      document.getElementById("flyout-debug").textContent = "Clicked inside!";
      return;
    }
    // Go up the DOM
    targetElement = targetElement.parentNode;
  } while (targetElement);

  // This is a click outside.
  yee = document.getElementById("flyout-debug").textContent = "Clicked outside!";
  const getIsFirstClick = sessionStorage.getItem('firstClick'); // change from here
  if (!getIsFirstClick) {
    sessionStorage.setItem('firstClick', true)
    location.reload()
  }

});
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the response! It seems the key is stored in session storage even though I have not clicked outside the element. So no reload is happening on the page.
looks like there was a syntax error, should be getItem. Working as intended now!
1

I'm not sure exactly what you're trying to do, but what I understood is that when you click within an area you don't want to reload, but if you click any outside, reload should happen, correct me if I'm wrong. Here's a script to do it:

document.addEventListener("click", (evt) => {
    const flyoutElement = "flyout-example";
    const targetElement = evt.target; // clicked element

     if (targetElement.id === flyoutElement) {
          // This is a click inside. Do nothing, just return.
         document.getElementById(flyoutElement).textContent = "Clicked inside!";
     } else {
       // This is a click outside.
       document.getElementById(flyoutElement).textContent = "Clicked outside!";
       const isReloaded = localStorage.getItem('reloaded');

       if (!isReloaded) {
         localStorage.setItem('reloaded', true);
         location.reload();
       }
     }
});

4 Comments

thanks for the response! So as of now anytime I click outside the element it reloads. What I am having trouble with is I want my page to reload only once after I have clicked outside the element. If I click outside the element a second time it shouldn't reload
Ah I got it now, you can use local storage, I'll update my answer and let me know if it works, well I'm sure it will lol
@anon here we go, this solution is much better as we don't need to iterate on anything, simple and clear, hope you find it useful
Please notice that I'm using localStorage here so it's persistent, not like sessionStorage which will expire once the tab is closed, it's up to you what you want to do, but bear this in mind.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.