rabbibotton / clog

CLOG - The Common Lisp Omnificent GUI
Other
1.48k stars 101 forks source link

load-script loading script not work will need to after page loaded #252

Closed janegwaww closed 1 year ago

janegwaww commented 1 year ago

I have a js file need to load in on-new-window, like:

document.addEventListener('DOMContentLoaded', () => {

  // Get all "navbar-burger" elements
  const $navbarBurgers = Array.prototype.slice.call(document.querySelectorAll('.navbar-burger'), 0);

  // Add a click event on each of them
  $navbarBurgers.forEach( el => {
    el.addEventListener('click', () => {

      // Get the target from the "data-target" attribute
      const target = el.dataset.target;
      const $target = document.getElementById(target);

      // Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
      el.classList.toggle('is-active');
      $target.classList.toggle('is-active');
      console.log("active");
    });
  });

});

then use load-script to load this script:

(defun on-new-window (body)
  "On new window handler."
  (setf (title (html-document body)) "English Learning Mine")
  (load-script (html-document body) "/js/navbar.js")
  (create-navbar body))

but this script will work only after page loaded.

So I expect there is a way to load script after page loaded?

rabbibotton commented 1 year ago

Not sure I understand, assuming on-new-index-page is used as an on-new-window handler then the page is already loaded (in CLOG pages are loaded before the websocket connection if made to the page and the on-new-window handler fired once all ready). If not working probably because your script is waiting for an event that already was fired, ie the DOMContentLoaded event.

Remove the "document.addEventListener('DOMContentLoaded', () => {" and the last "});" from your script file since already being called on loaded document and let me know if worked.

janegwaww commented 1 year ago

@rabbibotton hi, sorry for my poor English description,I found builder-tool render to lisp will automatically remove the data-target attribute in html element, and attach-as-child :new-id set to t like:

(setf (slot-value panel 'navbar-menu) (attach-as-child clog-obj "elm-app-navbar-menu" :clog-type 'CLOG:CLOG-DIV :new-id t))

automatically generated, how should I change it?

And just like you said remove the document.addEventListener('DOMContentLoaded', () => {" and the last "}); is worked, but load-script need at the bottom of on-new-window like:

(defun on-new-window (body)
  "On new window handler."
  (setf (title (html-document body)) "English Learning Mine")
  (create-navbar body)
  ...
  (load-script (html-document body) "/js/navbar.js"))
rabbibotton commented 1 year ago

I speak code also better than English, maybe send me a zip with sources to look out. david@botton.com

janegwaww commented 1 year ago

I speak code also better than English, maybe send me a zip with sources to look out. david@botton.com

https://github.com/janegwaww/elm-app/blob/dev/src/main.lisp

rabbibotton commented 1 year ago

Try replacing you navbar.js with:

// Add a click event on each of them
$navbarBurgers.forEach(el => {
  el.addEventListener('click', () => {

    // Get the target from the "data-target" attribute
    // const target = el.dataset.target;
    const $target = document.getElementById("elm-app-navbar-menu");

    // Toggle the "is-active" class on both the "navbar-burger" and the "navbar-menu"
    el.classList.toggle('is-active');
    $target.classList.toggle('is-active');
  });

Let me know if that worked

rabbibotton commented 1 year ago

Also, you can execute JS directly just use clog:js-execute

janegwaww commented 1 year ago

very thanks for answer, its really help.