0

I'm coding an app that has a custom text editor and I want an autosave function to trigger only after some seconds of idle time (no key presses) have passed.

My problem is that the amount of innerHTML to save (inside a contenteditable div) is usually massive. Like tens of thousands of <span> objects massive. And I also need to sanitize it before sending it back to the server, which is also CPU and memory heavy with these many elements. My idea is that, if I only autosave while on idle, the user experience will improve.

I'm having a hard time guessing how exactly should my logic be so the autoSave() triggers only after 15 seconds of idle time.

So here is my unsuccessful attempt: (Sorry for the mixture of jQuery and plain JS)

let idleTime = 0;

$(window).ready(function() {
    //Increment the idleTime counter every 15 seconds.
    setInterval(timerIncrement, 15000); 
    //Zero the idle timer on key press
    $(this).keyup(function(e) {
      idleTime = 0;
    });
});

function timerIncrement() {
  idleTime++;
  if (idleTime > 1) {
    autoSave();
  }
}

window.autoSave = function autoSave() {
    const form = $(".form");
    const method = form.attr("method").toLowerCase(); // "get" or "post"
    const action = form.attr("action"); // url to submit to 
    loadTextFull(); // load the text to the form's input
    $[method](action, form.serialize(), function(data) {});
};

loadTextFull = function loadTextFull() {
  let textContent = document.getElementById("content").innerHTML.trim();
  let cleanContent = DOMPurify.sanitize(transcriptContent, {
    ALLOWED_TAGS: ["span", "i", "p", "div", "select", "option"],
    ALLOWED_ATTR: [
      "id",
      "data-start-time",
      "data-paragraph-counter",
      "data-paragraph-speaker",
      "data-speaker",
      "contenteditable",
      "name",
      "onchange",
      "class"
    ]
  });
  document.getElementById("text_result_full").value = cleanContent;
};

My form, in case it matters, looks like this:

<form class="form" id="edit_text_65" action="/text/65" accept-charset="UTF-8" data-remote="true" method="post">
  <input type="hidden" name="_method" value="patch">
  <input type="hidden" value="" name="text[result_full]" id="text_result_full">
  <input type="submit" name="commit" value="Save" style="display:none" data-disable-with="Guardar">
</form>

I'd appreciate any help. Thanks in advance.

brobert
  • 43
  • 4
  • Look at cron-jobs – Beez Feb 25 '20 at 17:40
  • 1
    What you want to look into is creating a debounce function, that waits a certain time period before attempting to be executed again https://stackoverflow.com/questions/24004791/can-someone-explain-the-debounce-function-in-javascript – Mahatmasamatman Feb 25 '20 at 17:41
  • `var intervalId = setInterval(autoSave, 15000); $(this).keyup(function() { clearInterval(intervalId); intervalId = setInterval(autoSave, 15000) });` – freedomn-m Feb 25 '20 at 18:15

0 Answers0