JavaScript/jQuery trying to make a reset page function-ThrowExceptions

Exception or error:

I’m trying to make a function which can be called to reset the page into the state before modifications were made. Now the normal JS one worked but it broke my other function which provided answers for the quiz via div population.

I’ve tried

var originalState = $("health").clone();  

$(".reset").click(function() {
 console.log('called');
 console.log(originalState);
$("health").replaceWith(originalState.clone());
 console.log(originalState);
});

And with vanilla script

var container = document.getElementById("health");
var content = container.innerHTML;

//function reset() {
  //var container = document.getElementById("health");
  //container.innerHTML = html;
  //answers = [];
//}

var html;
window.onload = function() {
  html = document.getElementById("health").innerHTML;
};

This gets broken by the JS fix.

$(".correctKey").click(function() {
    $(".dropbox").each(function(index) {
        $(this).text(correctAnswers[index]);
        answers = correctAnswers.slice();
    });
});

HTML (Not sure if it’ll help)

<div class="container" id="health">
  <div class="row dropable-area">
    <div class="col-sm-12">
      <div class="row">
        <div class="col-sm-6">
          <div class="dropbox panel panel-default" ondrop="drop(event)" ondragover="allowDrop(event)">
          </div>
        </div>
        <div class="col-sm-6">
          <div class="dropbox panel panel-default" ondrop="drop(event)" ondragover="allowDrop(event)">
          </div>
        </div>
        <div class="col-sm-6">
          <div class="dropbox panel panel-default" ondrop="drop(event)" ondragover="allowDrop(event)">
          </div>
        </div>
        <div class="col-sm-6">
          <div class="dropbox panel panel-default" ondrop="drop(event)" ondragover="allowDrop(event)">
          </div>
        </div>
        <div class="col-sm-6">
          <div class="dropbox panel panel-default" ondrop="drop(event)" ondragover="allowDrop(event)">
          </div>
        </div>
        <div class="col-sm-6">
          <div class="dropbox panel panel-default" ondrop="drop(event)" ondragover="allowDrop(event)">
          </div>
        </div>
        <div class="col-sm-6">
          <div class="dropbox panel panel-default" ondrop="drop(event)" ondragover="allowDrop(event)">
          </div>
        </div>
        <div class="col-sm-6">
          <div class="dropbox panel panel-default" ondrop="drop(event)" ondragover="allowDrop(event)">
          </div>
        </div>
        <div class="col-sm-6">
          <div class="dropbox panel panel-default" ondrop="drop(event)" ondragover="allowDrop(event)">
          </div>
        </div>
        <div class="col-sm-6">
          <div class="dropbox panel panel-default" ondrop="drop(event)" ondragover="allowDrop(event)">
          </div>
        </div>
      </div>
    </div>
  </div>

How to solve:

Close… Close… Just missing concepts.
The “global variable” will stay as long as the page is loaded…
And as long as it isn’t changed.

var originalState = $("health").clone();   // Global variable holding
                                           // the "onload state" html.

$(".reset").click(function() {
  console.log('Reset called');
  $("health").replaceWith(originalState);  // HERE, originalState is the global variable.
                                           // Not the original element itself.
                                           // No need to re-clone it.

  answers = []:                            // Reset this variable too?
});

Then event delegation, as Alexander Staroselsky correctly mentionned, is needed to access elements “replaced”… Since the DOM “Document Object Model” will not be notifed of these changes, you have to care about how to access those “new” elements after an append(), prepend(), before(), after(), replaceWith(), etc…

You have to alway “attach” the function, particularly the one which are event triggered, to “static” elements, and delegate… Or starting from a “static” element, use find or eq to target them.

And there is the event.target trick also… For some uses.

$("#health").on("click", ".correctKey", function() {    // [event], [target], [function]
  $("#health").find(".dropbox").each(function(index) {  // Always start form a "static" element.
    $(this).text(correctAnswers[index]);

    answers = correctAnswers.slice();                   // I don't know what you do with this variable.
                                                        // But there a possible need to reset too...
  });
});

I think the code above should work.
No apparant big changes, as you can see.

But details matter.


«What’s not in DOM on load, is dynamic.»
«Static can become dynamic»
«Static element can hold dynamic elements/content… Think “wrapper”»

###

You would need to run ‘clone()’ with an optional flag to ensure event handlers are copies/cloned as well. By default the handlers are NOT copied which is most likely why events aren’t triggering after replace. Try the following:

$("#health").replaceWith(originalState.clone(true));

Otherwise you target an element that does not get removed and re-added to DOM and use event delegation to target the respective sub elements of #health for click events:

$("#health").on("click", ".subitemClass", function(event) {});

Hopefully that helps!

Leave a Reply

Your email address will not be published. Required fields are marked *