Identifying the item being scrolled through

I have a question regarding the scroll behavior of div elements on my webpage. Currently, I have some divs set to overflow: scroll. How can I identify which specific element is currently being scrolled or if the scroll action is applied to the body itself? It seems that event.target only returns the element under the mouse cursor at the time of scrolling, not the actual target element.

https://i.sstatic.net/kuRTz.jpg

One possible solution I came up with involves using the window.onscroll event listener to log the target element. Here's an example of the code:

window.onscroll = function(e){

console.log(e.target);

}
body{
  background: white;
}

div{
  height: 50px;
  overflow: scroll;
  margin: 25px;
  background: black;
  color: white;
}

The above CSS code sets the background and styling for both the body and individual div elements on the page. The HTML snippet provided demonstrates how the div elements are structured for scrolling content.

Any insights or suggestions on efficiently detecting the scrolled element would be greatly appreciated. Thank you in advance!

Answer №1

Update: I have implemented a new function called isScrollable to handle cases where the scroller divs are not actually scrollable, such as on larger screens or when there is not enough content to require scrolling.

The solution involves traversing up through the ancestors of the target element until a scrollable one is found:

window.addEventListener('scroll', function(e) {
  var el = e.target;
  while (el && el !== document && !isScrollable(el)) {
  el = el.parent;
  }
  log('Scrolled element: '+ (el.className || 'document'));
}, true);

function isScrollable(el) {
  return el.scrollWidth > el.clientWidth || el.scrollHeight > el.clientHeight;
}

function log(x) {
  document.querySelector('h2').innerHTML = x;
}
/* Some CSS for the demo... */.scroller{width:6em;height:6em;float:left;overflow:scroll;border:4px solid #ddd;margin:.5em;position: relative}.inside{content:"";display:block;width:100em;height:100em;background:url(https://cms-assets.tutsplus.com/uploads/users/1604/posts/28343/image/WatermelonOrangePatternFinal.png)}.scroller.d .inside{width:100%;height:100%;opacity:.5}.scroller.d::before{position: absolute;z-index:5;content:"Not scrollable (not enough content)";font-size:.8em;}body{color:#fff;font-family:Arial,Helvetica,sans-serif}body::after{content:"";display:block;width:100em;height:100em;background:url(https://365psd.com/images/previews/b0c/icon-pattern-backgrounds-53906.jpg)}h2{position:fixed;bottom:.2em;left:0;width:100%;text-align:center}
<div class="scroller a"><div class="inside"></div></div>
<div class="scroller b"><div class="inside"></div></div>
<div class="scroller c"><div class="inside"></div></div>
<div class="scroller d"><div class="inside"></div></div>
<h2>Try scrolling</h2>

Answer №2

To optimize your event binding, consider directly binding the scroll events to the div elements themselves. If a div does not have overflow enabled, it will not trigger the scroll event.

// Iterate through all scrollable divs
document.querySelectorAll("div").forEach(function(div){

  // Attach a scroll event listener to each div
  div.addEventListener("scroll", function(){
  console.log(this.id);
  });

});
body{
  background: white;
}

div{
  height: 50px;
  overflow: scroll;
  margin: 25px;
  background: black;
  color: white;
}
<div id="something">
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
</div>

<div>Not enough here for scroll event</div>

<div id="something else">
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
Scroll<br>
</div>

Scroll<br>
... (more content) ...<br>
Scroll<br>
Scroll<br>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The communication layer connecting MVC and an HTML page, utilizing AJAX functionality

I have developed a web application and believe that all components are complete. However, I am unsure about how to establish connections within it. The HTML page consists of one field where users can input a word, and my program should parse the top 5 resu ...

Passing data between multiple components in Vue.js and Laravel: Best practices

require('./bootstrap'); window.Vue = require('vue'); Vue.component('exampleComponent1', require('./components/exampleComponent1.vue')); Vue.component('exampleComponent2', require('./components/exampl ...

Discovering the specific marker that was clicked from a group of Google map markers

I have a collection of marker objects named markers. I am currently utilizing a for loop to assign event listeners to each one. However, I am encountering difficulty in determining which specific marker was clicked. This is the current code snippet I have ...

Tips for showcasing an image using the ajax success callback?

I have implemented an AJAX function with dynamic value retrieval to display images based on the returned value. In the success function, I aim to showcase the image within a specific div element. var num=document.getElementById('number').value; ...

Align content vertically within a div container

I have encountered an issue where I am trying to center vertically the content within a div. Here is an example of the structure: <div class="container-fluid"> <div class="row restaurant"> <div class="col-md-6"> & ...

Text displaying as actionable icons

In my React project, I am utilizing material-table (https://material-table.com/#/) and have successfully imported the necessary icons. However, when viewing the action bar, the icons are displaying as plain text instead of the Material Icon. import React, ...

Safari's flexbox wraps the final column on the top row

When viewed in Safari and some other iOS based browsers, the last column of the first row wraps to the next line. Safari: https://i.sstatic.net/FhYyn.jpg Chrome / Others: https://i.sstatic.net/Vkvr0.jpg Code: .flexthis { display: -webkit-box; d ...

Can Angular 4 experience race conditions?

Here is a snippet of my Angular 4 Service code: @Injectable() export class MyService { private myArray: string[] = []; constructor() { } private calculate(result): void { myArray.length = 0; // Perform calculations and add results to myAr ...

Issue with React router not functioning correctly when dealing with dynamically created anchor tags utilizing jquery

As a newcomer to React.js, I have incorporated jQuery into my project to handle mouse and click events for cloning navigation elements, specifically <li> tags within <a> tags. The cloned elements are displayed in a targeted div ID successfully. ...

Concealing specific HTML elements with ng-view in AngularJS

I recently started a project in AngularJS and I'm utilizing ng-view with $routeProvider for templating. However, I've encountered a minor issue where I don't want the navbar to display on specific pages like the landing, login, and registrat ...

Position an element to the right within a div using the float property

My product page features a range of attributes that can vary from 1 to 4, each sharing a common fieldset class name. I am attempting to position two of the fieldsets side by side and the remaining ones below them in a similar layout. However, achieving thi ...

Picture is unavailable for viewing - (Express, Pugjs)

I'm having trouble getting an image to display on my page using a pug template. Despite following the setup and files correctly, the image still isn't showing up. Here is what I have: index.js app.use('/images', express.static(path.r ...

Text that spans across multiple lines

I have a multi-line text that I need to adapt to a div. For example: https://i.stack.imgur.com/mtZmf.png Is there a way to adjust the text within the div? Can we prevent the blue spacing after the word "text" using CSS? If I have various texts of differ ...

The SimpleHTTPServer is causing Google Maps Places Autocomplete feature to malfunction

Currently, I am implementing a location search feature along with form auto-fill using the google.maps.places.Autocomplete functionality. While accessing the HTML file directly (file:///location.html), everything is functioning as expected. However, when ...

Is it possible to transfer the data from the previous row's input to the input of a new row?

Greetings to the StackOverflow community, I am currently utilizing a table form with a specific query: Here is an abridged version of my form structure: <script> $('#addrowbutton').click(function() { $('tr:hidden:first').show(); ...

Altering the background color of an individual mat-card component in an Angular application

Here is the representation of my mat-card list in my Angular application: <div [ngClass]="verticalResultsBarStyle"> <div class="innerDiv"> <mat-card [ngClass]="barStyle" *ngFor="let card of obs | async | paginate: { id: 'paginato ...

Executing two nested loops with a delay in jQuery

I am currently working on a script that sends an ajax post to another page. I need to run two for loops before sending the ajax request with a timeout. The first loop is successful, but when I try to run the second loop, all requests are sent at the same ...

javascript obtain a query string for submission by a form

Suppose you have a form, such as <form id='testform' method="post" action="/" /> <input name="test1" value="yes" type="text"> <input name="test2" value="no" type="text"> </form> Is there a way to retrieve the query s ...

`How can I stop typescript from converting dynamic imports to require()?`

Currently, I am in the process of creating a Discord bot using discord.js. Interestingly, discord.js does not seem to be compatible with ESM modules, which has been causing some complications in my project. As a result, I have resorted to utilizing CommonJ ...

The extent of the modal window (AngularJS directive)

I've been experimenting with a modal window feature using Angular UI Bootstrap. Within the parent controller, I've defined the following function: $scope.open = function () { var modalInstance = $modal.open({ templateUr ...