Targeting Elements with JS (and using external Libraries)

Hi,

Is there a definitive guide somewhere on how to use JS to target “data-id” attributes (and the content within them) on Readymag?

I have tried and tried and tired, but cannot seem to get it to work.

For example - I have a text box widget with the id below I am trying to target, but even after ensuring that the content is loaded, I am still not getting there.

Is the syntax incorrect based on what ReadyMag wants?

This is in Before in a code widget.

<script type="text/javascript">

document.addEventListener("DOMContentLoaded", function () {
  const tbox1 = $('[data-id="642d77f785c0e300215466e1"] .text-viewer');

  if (tbox1) {
    tbox1.style.backgroundColor = "red";
    tbox1.style.left = 10;
    console.log("tbox1.textContent " + tbox1);
  } else {
    console.error("Could not find the target element");
  }
});
</script>

This is just the start of my journey towards attempting to use GSAP to animate certain parts of the site. Is this something that is even possible?

1 Like

I think the “DOMContentLoaded” isn´t firing like it should inside of readymag. Had problems with this too.

have you tried to delete it and just work with a timeout to wait 2 seconds before executing your code?

Ooof, that’s frustrating.

So is what you mean, instead of adding any listeners at all, just wrap the function in a setTimeout and wait 2 seconds? Have you thought of any failsafe methods to avoid any errors when, for example, the connection is particularly slow? (like, are any proper DOM listeners working?)

@Readymag can you advise on best practices here?

hey, yes. just a timeout. And I haven´t found another method than that.

But yeah, @Readymag pls let some light shine on this!

Or does anyone of you have the solution? @HEADLESS.HORSE @Misha @HuV

I couldn’t get the timeout working either.

Really feels like a crucial update (add id’s to any widget in Readymag) + a tutorial needs to be how to target in Readymag. JS events not firing in the custom code blocks make me think Readymag has designed these blocks in a way that prevents it from happening, but just hasn’t told us. @Readymag - any insight would be great.

on this side it everything works with the timeout method. even with slow connections. so maybe your code isn´t working properly?

Hey!
Readymag renders projects in async way. That’s why when you refer to element with ID it just doesn’t exist at the beginning. The onliest workaround is to use the timeout as you mentioned.

As for more stable resolution: Readymag will render projects on the server (SSR). We can’t provide you any details on the timeframes right now. Early stages of testing in process.

1 Like

hey, it would be really helpful if you would implement some function that fires if the dom/page is loaded and let us then fire our code.
Its always a bit hacky workaround to deal with this.

The integration of custom javascript is quite a pain without proper js events. I startet running intervals to check for dom changes. Slow connections or late initialization should not be a problem.

<script type="text/javascript">
window.onload = function () {
    // search for dom element
    var findElementTimeout = setInterval(findElement, 500); // every half second
    function findElement() {
        var element = document.getElementById("something");
        if ( element ) {
            clearInterval(findElementTimeout); // stop running interval
            initCustomCode(element);
        }
    }

    function initCustomCode(element) {
        // do something
    }
}
</script>
1 Like

I encountered the same problem, and found another approach that works for me: I add a global EventListener to the whole document, then, when the user clicks / hovers / scrolls, I identify the elements that require custom interactions:

document.addEventListener('click', function (event) {

    if (event.target.matches('[data-id]')) {
    	// get the data-id of this 
      var dataID = event.target.getAttribute('data-id');
      console.log(dataID);

     // Code that works for a Button element :
      if ( dataID == "DATA_ID_NUMBER1") {
      	// Do something... for example, play an audio/video somewhere on the page
        var audio1 = document.querySelector(" [data-id='DATA_ID_NUMBER2'] video ");
        audio1.currentTime = 0;
        audio1.play();
      }

  // Code that works for an Image element :
    } else if (event.target.matches('img')) {
      // the closest ancestor with a data-id
      console.log("target matches: img");
      var dataID = event.target.parentElement.getAttribute('data-id');
      
      if ( dataID == "DATA_ID_NUMBER3" ) {
      	// do something
        
      }
      
    }
    
});

Just adding that my method above doesn’t appear to work for “scroll” events. :roll_eyes: