Jump to content
Search Community

jquery $("#foh").on() vs. document.querySelector("#foo").addEventListener

chrisi51 test
Moderator Tag

Recommended Posts

Hey, i know, its not gsap related - well it is kind of gsap related, as i always got told, to replace jquery by native js and gsap 😃 

 

i have an approx 100kb big svg file with a lot of animations in it (svg nodes animated by gsap) and the following elements are all nodes of this svg file, which is just inlined into the html. "#textbox-..." is an overlay like small box with additional text and "#clicker-x" is the button to open it. So it should be possible to open the overlay by clicking the clicker and closing it by either clicking the clicker again or clicking the overlay directly.

 

i have the following jquery code:

  $("#clicker-7").on("click", function(){$("#textbox-7").fadeToggle()});
  $("#textbox-7").on("click", function(){$("#textbox-7").fadeToggle()});

  $("#clicker-6").on("click", function(){$("#textbox-6").fadeToggle()});
  $("#textbox-6").on("click", function(){$("#textbox-6").fadeToggle()});

  $("#clicker-5").on("click", function(){$("#textbox-5").fadeToggle()});
  $("#textbox-5").on("click", function(){$("#textbox-5").fadeToggle()});

  $("#clicker-4").on("click", function(){$("#textbox-4").fadeToggle()});
  $("#textbox-4").on("click", function(){$("#textbox-4").fadeToggle()});

  $("#clicker-3").on("click", function(){$("#textbox-3").fadeToggle()});
  $("#textbox-3").on("click", function(){$("#textbox-3").fadeToggle()});

  $("#clicker-2").on("click", function(){$("#textbox-2").fadeToggle()});
  $("#textbox-2").on("click", function(){$("#textbox-2").fadeToggle()});

This code is just working as intended. on each click on one of the opener elements or the opened element itself it just toggles its appearance - fading in or out.

 

Now i replaced this code with pure js and gsap:

      var overlayStateScene1 = gsap.timeline().to("#textbox-7",{autoAlpha:0});
      document.querySelectorAll("#clicker-7, #textbox-7").forEach(function(elem){
          elem.addEventListener("click", function() {
              overlayStateScene1.reversed(!overlayStateScene1.reversed());
          });
      });
      var overlayStateScene2_1 = gsap.timeline().to("#textbox-6",{autoAlpha:0});
      document.querySelectorAll("#clicker-6, #textbox-6").forEach(function(elem){
          elem.addEventListener("click", function() {
              overlayStateScene2_1.reversed(!overlayStateScene2_1.reversed());
          });
      });      
      var overlayStateScene2_2 = gsap.timeline().to("#textbox-5",{autoAlpha:0});
      document.querySelectorAll("#clicker-5, #textbox-5").forEach(function(elem){
          elem.addEventListener("click", function() {
              overlayStateScene2_2.reversed(!overlayStateScene2_2.reversed());
          });
      });      
      var overlayStateScene3 = gsap.timeline().to("#textbox-4",{autoAlpha:0});
      document.querySelectorAll("#clicker-4, #textbox-4").forEach(function(elem){
          elem.addEventListener("click", function() {
              overlayStateScene3.reversed(!overlayStateScene3.reversed());
          });
      });      
      var overlayStateScene4_1 = gsap.timeline().to("#textbox-3",{autoAlpha:0});
      document.querySelectorAll("#clicker-3, #textbox-3").forEach(function(elem){
          elem.addEventListener("click", function() {
              overlayStateScene4_1.reversed(!overlayStateScene4_1.reversed());
          });
      });      
      var overlayStateScene4_2 = gsap.timeline().to("#textbox-2",{autoAlpha:0});
      document.querySelectorAll("#clicker-2, #textbox-2").forEach(function(elem){
          elem.addEventListener("click", function() {
              overlayStateScene4_2.reversed(!overlayStateScene4_2.reversed());
          });
      });    

some more code but also working as intended. The only problem is, with each of those addEventListener Android (at least Android older v10) seems to extremly slow down the page rendering. it is freezing the whole phone and you have to multiple tap "wait" until chrome has finished the processing and the page is responding to any input.

If i go back to the jquery code its instantly responding. 

 

Is there any i do wrong or what is bad practice? iphone is working without problems and also my newer devices with android 10 don't have a problem with the second code.

 

I can't reproduce it on a simple example so the codepen is not that helpful in this case.

 

Does anybody have an idea, whats going on here or where to place that question instead of gsap forum? 

See the Pen GRjZRoM by chrisi51 (@chrisi51) on CodePen

Link to comment
Share on other sites

8 minutes ago, ZachSaucier said:

With that being said, you can greatly improve your code by using loops. You should learn to animate efficiently!  

i dont know if its really the animations because as soon as i disable those 10 event listeners (or replace them with the jquery code), everything is fine so i thought something would have to be wrong with the event listeners in general and hoped for any experience with that. :) 

 

The clickers are a little animated too. ive updated the pen to show any possible sideeffects. the overlays are simplified in form of circles but in my real project there is just a path + some text.

Link to comment
Share on other sites

5 hours ago, Visual-Q said:

Are there any issues with running ES6 on android before 10? Maybe try replacing the foreach with es5 implementation.

i also tried to just put each eventlistener statically in the code like 

      var overlayStateScene1 = gsap.timeline().to("#textbox-7",{autoAlpha:0});
      document.querySelector("#clicker-7").addEventListener("click", function(event) {
            overlayStateScene1.reversed(!overlayStateScene1.reversed());

      });
      document.querySelector("#textbox-7").addEventListener("click", function(event) {
              overlayStateScene1.reversed(!overlayStateScene1.reversed());
      });

instead of using any form of loops. And its exactly the same problem :(

i also have the following polyfill for IE11, so if old Android got problems it should be handled here

    if (window.NodeList && !NodeList.prototype.forEach) {
        NodeList.prototype.forEach = function (callback, thisArg) {
            thisArg = thisArg || window;
            for (var i = 0; i < this.length; i++) {
                callback.call(thisArg, this[i], i, this);
            }
        };
    }      

 

5 hours ago, Visual-Q said:

Also are you talking about in a specific browser?

Actually i dont have a big amount of devices and the most of them are Sony 5 years old ones with almost same android version (7). And the browser was always google chrome.

 

on my Android 10 devices its working with chrome and the built in default browser what ever that is :) But those devices also have much hardware.

 

btw: i turned off any animations and the problem is still appearing. So the only things comming together here are:

 

- massive svg element with a lot of nodes in it

- some regular event listeners

 

i made a copy and deleted ALL js except of those handlers and it still have the same problem ....

 

than i dropped content out of the svg ... part after part and it was not changing a lot ... for some reason i saw some unoptimized text elements (the overlays) where the text had lot of tspan with single characters special positioned ... i fixed that before by changing the distance between 2 characters from auto to 0 in illustrator but there was a text correction recently and seems like the setting was gone. so i just fixed that on the fly and .... wow ... THAT was the problem!?

 

i dunno why and how this can affect such a behavior but after i fixed those 5 textboxes, everything is fine again. it dropped approx 10kb from my 115kb svg so its not the main part or something like but probably it was the animation to fade them out at the beginning as this was always enabled when i did not used the jquery way. 

 

 

Link to comment
Share on other sites

@ZachSaucier now i got you ... and i came to this:

        gsap.utils.toArray(".clicker-wrap").forEach(function(clickerwrap){
            let textbox = clickerwrap.querySelector(".textbox");
            let clicker = clickerwrap.querySelector(".clicker");
            bbox = clicker.getBBox();
            clicker.style.transformOrigin = (bbox.x+bbox.width/2)+"px "+(bbox.y+bbox.height/2)+"px";
            
            let tl = gsap.timeline({ })
                .to(textbox,{autoAlpha:0});

            clickerwrap.addEventListener("click", function() {
              tl.reversed(!tl.reversed());
            });
        });   

the problem at all is that illustrator dont have a workflow to handle class names without letting other tools manipulate the exported svg. 

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...