Tony Chou
Tony Chou

Reputation: 604

Trigger event before change class

There are many buttons and links that would let me quit one page. Before leaving this page to another, I want to ask something to the user, and then, just quit this page.

In our app, the "leave this page" is just like <canvas class="show"></canvas> to <canvas class=""></canvas> and showing another canvas. Others has done this. My goal is to detect whether the class="show" is removed or not.

I have read this, this, and so on. I'm quite junior, do not understand what they really mean or just don't know how to implement it in my question.

Please help, the more specific example list below:

$('body').on('class_change_event', () => {
    swal({
        title: "Are you sure?",
        text: 'If you close without saving, your changes will discarded.',
        type: "warning",
        showCancelButton: true,
        confirmButtonText: "Save"
    })
    // After the user choose, do the original jobs
})
div.demo { 
    border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/sweetalert/dist/sweetalert.min.js"></script>

<div class="demo">
    <canvas class="load show"></canvas>
    <canvas class="load"></canvas>
    <canvas class="load"></canvas>
</div>

<a href="https://www.google.com">go to Google</a>
<a href="index.html">back to index</a>
<input type="button" value="Clear canvas" />

Note

Upvotes: 0

Views: 115

Answers (2)

Timur  Gilauri
Timur Gilauri

Reputation: 914

Ok. I got you. I guess that is what you need. We create observer that is looks for class changes in target elements. In all elements with class .load. See comments in script too.

let views = [...document.querySelectorAll(".load")];
views.forEach(view => {

  // create an observer instance that will look for class changes
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(mutation) {
      // we only need to detect class changes
      if (mutation.attributeName !== 'class') {
        return false;
      }
      // exact node which classList has been changed
      let el = mutation.target
      if (el.classList.contains("show")) {
        confirmLeave();
      }
    });
  });

  // configuration of the observer. We need to detect "class" attribute changes 
  var config = {
    attributes: true
  };

  // pass in the target node, as well as the observer options
  observer.observe(view, config);
})

// Let's test our observer
setTimeout(() => {
  document.querySelector('.load').classList.add('show')
}, 2000)

function confirmLeave() {
  // this string is just to check and show you can remove it later and use your script below
  document.querySelector('.text').textContent = 'Element got "show" class!';
  /*swal({
    title: "Are you sure?",
    text: 'If you close without saving, your changes will discarded.',
    type: "warning",
    showCancelButton: true,
    confirmButtonText: "Save"
  })*/
}
.load {
  width: 20px;
  height: 20px;
  border: 1px solid #333;
}

.load.show {
  background-color: red;
}

.text {
  margin-top: 10px;
}
<div class="load"></div>

<div class="text"></div>

Upvotes: 1

frodo2975
frodo2975

Reputation: 11793

If you want to prevent a user from leaving the page, you want to use the beforeunload event. This will cause the browser to prompt the user if they really want to leave the page. However, if you're using a SPA, you'll need to tie into your framework's routing to show a prompt when it changes routes.

window.addEventListener("beforeunload", function(e) { ... });

https://developer.mozilla.org/en-US/docs/Web/API/WindowEventHandlers/onbeforeunload

Upvotes: 1

Related Questions