Home > Enterprise >  addEventListener to scroll in a div
addEventListener to scroll in a div

Time:10-09

I'm trying to target the scrolling of a div by class or id, but i cannot make it work. The console.log(scrolled) doesn't activate anything in the console. Can someone please help me out?

The JS i use is

document.getElementsByClassName('.site-content').addEventListener('scroll', () => {
  
  const scrolled = document.getElementsByClassName('.site-content').scrollY;
  
  console.log(scrolled);

});

And the CSS for my section is

.site-content{
width:100vh;
  height:100vw;
  overflow-x: hidden;
  overflow-y: scroll;
  transform: rotate(-90deg) translateX(-100vh);
  transform-origin: top left; 
  position:absolute;
  scrollbar-width:none;
  -ms-overflow-style:none;
}

CodePudding user response:

You must select the first element in HTMLCollection and there is no scrollY just maybe for window.scrollY Here is an example on how to get the scroll position on your example, i've added height: 300px to your css so it scrolls

document
  .getElementsByClassName("site-content")[0]
  .addEventListener("scroll", () => {
    const scrolled = document.getElementsByClassName("site-content")[0]
      .scrollTop;
    console.log(scrolled);
  });
.site-content {
  width: 100vh;
  height: 100vw;
  overflow-x: hidden;
  overflow-y: scroll;
  transform: rotate(-90deg) translateX(-100vh);
  transform-origin: top left;
  position: absolute;
  height: 300px;
  scrollbar-width: none;
  -ms-overflow-style: none;
}
<div id="content" class="site-content">

  <div id="primary" class="content-area grid">
    <main id="main" class="site-main">

      <article id="post-7" class="post-7 page type-page status-publish hentry">
        <header class="entry-header">
        </header><!-- .entry-header -->

        <div class="entry-content">
          <div data-elementor-type="wp-page" data-elementor-id="7" class="elementor elementor-7" data-elementor-settings="[]">
            <div class="elementor-section-wrap">
              <section class="elementor-section elementor-top-section elementor-element elementor-element-f7eb723 elementor-section-full_width elementor-section-height-full section elementor-section-height-default elementor-section-items-middle" data-id="f7eb723" data-element_type="section">
                <div class="elementor-container elementor-column-gap-no">
                  <div class="elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-f8514aa" data-id="f8514aa" data-element_type="column">
                    <div class="elementor-widget-wrap elementor-element-populated">
                      <div class="elementor-element elementor-element-2b50864 elementor-widget elementor-widget-image" data-id="2b50864" data-element_type="widget" data-widget_type="image.default">
                        <div class="elementor-widget-container">
                          <img src="https://jakobnatorp.com/wp-content/uploads/2021/10/LAVA-1-1024x512.png" class="attachment-large size-large" alt="" loading="lazy" srcset="https://jakobnatorp.com/wp-content/uploads/2021/10/LAVA-1-1024x512.png 1024w, https://jakobnatorp.com/wp-content/uploads/2021/10/LAVA-1-300x150.png 300w, https://jakobnatorp.com/wp-content/uploads/2021/10/LAVA-1-768x384.png 768w, https://jakobnatorp.com/wp-content/uploads/2021/10/LAVA-1-1536x768.png 1536w, https://jakobnatorp.com/wp-content/uploads/2021/10/LAVA-1-1000x500.png 1000w, https://jakobnatorp.com/wp-content/uploads/2021/10/LAVA-1.png 1920w" sizes="(max-width: 640px) 100vw, 640px" width="640" height="320">
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </section>
              <section class="elementor-section elementor-top-section elementor-element elementor-element-55da7b6 elementor-section-full_width elementor-section-height-full section elementor-section-height-default elementor-section-items-middle" data-id="55da7b6" data-element_type="section">
                <div class="elementor-container elementor-column-gap-no">
                  <div class="elementor-column elementor-col-100 elementor-top-column elementor-element elementor-element-fd3a999" data-id="fd3a999" data-element_type="column">
                    <div class="elementor-widget-wrap elementor-element-populated">
                      <div class="elementor-element elementor-element-2d0d5b0 elementor-widget elementor-widget-image" data-id="2d0d5b0" data-element_type="widget" data-widget_type="image.default">
                        <div class="elementor-widget-container">
                          <img src="https://jakobnatorp.com/wp-content/uploads/2021/10/FLAAET-1-1024x512.png" class="attachment-large size-large" alt="" loading="lazy" srcset="https://jakobnatorp.com/wp-content/uploads/2021/10/FLAAET-1-1024x512.png 1024w, https://jakobnatorp.com/wp-content/uploads/2021/10/FLAAET-1-300x150.png 300w, https://jakobnatorp.com/wp-content/uploads/2021/10/FLAAET-1-768x384.png 768w, https://jakobnatorp.com/wp-content/uploads/2021/10/FLAAET-1-1536x768.png 1536w, https://jakobnatorp.com/wp-content/uploads/2021/10/FLAAET-1-1000x500.png 1000w, https://jakobnatorp.com/wp-content/uploads/2021/10/FLAAET-1.png 1920w" sizes="(max-width: 640px) 100vw, 640px" width="640" height="320">
                        </div>
                      </div>
                    </div>
                  </div>
                </div>
              </section>
            </div>
          </div>
        </div><!-- .entry-content -->

      </article><!-- #post-7 -->

    </main><!-- #main -->
  </div><!-- #primary -->

</div>

CodePudding user response:

You have a few issues:

  1. getElementsByClassName() returns a HTMLCollection (which is similar to an array), not a single element, so you can't use addEventListener() on it. Instead, you can use querySelector() which will return a single element. Note that using querSelector() is a more optimized approach to obtaining a single element than .getElementsByClassName(class)[0] is. The .getElementsByClassName() method will search through the entire DOM tree for elements with the class, and then [0] is used to obtain the first element found after the search is complete (discarding everything else it found). Whereas querySelector() will search through the DOM for your element, and stop searchinng as soon as it finds the element matching the class, it doesn't continue looking for more elments like .getElementsByClassName() does.

  2. scrollY is not a property of an element that you get back from .querySelector(). Instead, you can use the .scrollTop property.

  3. Your script is running before your page had loaded, this means that your script won't be able to find the HTML elements that you're trying to grab with querySelector(). There are a few ways to solve this, one way is to move your <script></script> tag containing your code before the closing </body> tag so that it only runs once your HTML elements have loaded.

  4. Lastly, you're querying the DOM every time you use .querySelector(). That's once when you add your event listener, and then every time your scroll event occurs (that's a lot of times!). Since querying the DOM is an expensive operation, it's best to keep it to a minimum. You can instead query the DOM once to obtain your element, and use that element reference within your callback for your scroll event.

Fixing the above points:

const scrollContent = document.querySelector('.site-content'); // store in a variable so we can reference the element in multiple locations
scrollContent.addEventListener('scroll', () => {
  const scrolled = scrollContent.scrollTop; // reuse `scrollContent` innstead of querying the DOM again
  console.log(scrolled);
});
  • Related