Utilize the native HTML attribute to capture the mouse wheel event

I'm interested in utilizing the mousewheel event in my project, but all the information I've found online relies on addEventListener(). I want to detect it using native HTML and CSS. In simpler terms, I'm hoping for something along the lines of:

<span id='fooBar' onmousewheel='alert("fooBar")'></span>

I am dynamically creating spans and inserting them into the DOM, and it would be more efficient if I could achieve this without running JavaScript code. I've managed to get other events working using native methods, but mousewheel seems to be a challenge. Is there a way to make it work without using JavaScript?

Answer №1

It seems that the reason you are encountering only references to addEventListener() is because it is considered the standard and correct method for event handling. In fact, the onmousewheel event may not even be supported in Firefox.

Although it is possible to make it work in browsers that do support it, using the code provided in your question (with the caveat that the span element should not be empty as it will not have any rendered size to initiate the event) I have included an example below. However, it is important to note that inline HTML event handling attributes are considered outdated and should be avoided in favor of the standard approach. You can find more information on this topic in another answer of mine here.

<span id='fooBar' onmousewheel='alert("fooBar")'>Use the mousewheel while mouse is over this</span>

Answer №2

Inline versus Delegation

Within the demonstration, side A utilizes the standard addEventListener and registers the wheel event, which serves as the replacement for the deprecated mousewheel event. Employing addEventListener is not only the norm but also the most efficient when event delegation is implemented.

While the usage of onwheel as an attribute event is restricted due to the unconventional and discouraged nature of any attribute event, side B is included, which employs the deprecated non-standard onmousewheel event as an inline event handler attribute. Given that it is coded awkwardly within a <span>, insertAdjacentHTML on a string containing all three types of quotes (i.e., ', ", `) was utilized. The inclusion of a string literal within a secondary level of nested quotes results in a messy implementation.

For insights on how Event Object properties are leveraged in event delegation, refer to this post.

Detailed explanations can be found within the demo

Demo

// Access the buttons  
const btnA = document.getElementById('addA');
const btnB = document.getElementById('addB');

// Access the parent nodes
const secA = document.querySelector('section:first-of-type');
const secB = document.querySelector('section:last-of-type');

// Register click event on buttons
btnA.addEventListener('click', addNodeA, false);
btnB.addEventListener('click', addNodeB, false);

/* Register wheel event on section A 
|| which serves as the parent node for wheeled
|| nodes. Event delegation entails a single
|| event handler for multiple event targets,
|| presenting a more efficient approach than multiple
|| inline event handlers.
*/
secA.addEventListener('wheel', markNode, false);

let cnt = 0;

/* Include node A within section A
|| ex. <span id="A1" class="A">A1</span>
*/
function addNodeA(e) {
  cnt++;
  var nodeA = document.createElement('span');
  nodeA.id = 'A' + cnt;
  nodeA.textContent = nodeA.id;
  nodeA.className = 'A';
  secA.appendChild(nodeA);
  return false;
}

/* Include node B within section B
|| ex. <span id="B3" class="B" onmousewheel="this.style.outline = `5px dashed red`">B3</span>
*/
function addNodeB(e) {
  cnt++;
  /* This string is enclosed within single quotes,
  || double quotes for the attributes values,
  || and backticks for the property value of
  || an attribute value. The implementation is messy,
  || confusing, and inefficient.
  */
  var nodeB = '<span id="B' + cnt + '" class="B" onmousewheel="this.style.outline = `5px dashed red`">B' + cnt + '</span>';

  // insertAdjacentHTML encompasses innerHTML
  secB.insertAdjacentHTML('beforeend', nodeB);
  return false;
}

function markNode(e) {

  /* If the wheeled node (i.e. e.target) does not match
  || the registered node (i.e. e.currentTarget), then...
  */
  if (e.target !== e.currentTarget) {
    var node = e.target;
    if (node.className === 'A') {
      node.style.outline = '5px dashed blue';
    } else {
      return false;
    }
  }
}
html,
body {
  width: 100%;
  width: 100%
}

fieldset {
  height: 10%;
}

main {
  border: 3px solid lime;
  height: 90%;
  min-height: 250px;
  display: flex;
}

section {
  width: 50%;
  min-height: 250px;
  outline: 3px dashed gold;
  padding: 10px 25px;
}

span {
  height: 50px;
  width: 50px;
  padding: 2px;
  text-align: center;
  font-size: 12px;
  margin: 5px;
  display: inline-block;
}

.A {
  background: rgba(0, 100, 200, .3);
}

.B {
  background: rgba(200, 100, 0, .3);
}

#addB {
  margin-left: 35%
}
<fieldset>
  <legend>addNode</legend>
  <button id='addA'>nodeA</button>
  <button id='addB'>nodeB</button>
</fieldset>
<main>
  <section></section>
  <section></section>
</main>

Answer №3

Creating elements with event listeners dynamically is a breeze once you have a solid grasp of the DOM structure and how to bind those listeners.

In the example below, we'll generate 10 spans and assign a listener to each one. Simply hover over a span and use the mouse wheel. The console will display the ID of the span you're interacting with.

// Generating 10 spans with a scroll listener
var count = 10;
for (var i = 0; i < count; i++) {
  var span = document.createElement('SPAN');
  span.id = 'foo-bar-' + i;
  span.innerHTML = 'Foo #' + i;
  addEventListener(span, 'mousewheel', handleEvent);
  document.body.appendChild(span);
}

// Event handler function
function handleEvent(e) {
  console.log(e.target.id);
}

// Support for IE 8+ via http://youmightnotneedjquery.com/
function addEventListener(el, eventName, handler) {
  if (el.addEventListener) {
    el.addEventListener(eventName, handler);
  } else {
    el.attachEvent('on' + eventName, function(){
      handler.call(el);
    });
  }
}
.as-console-wrapper { max-height: 5em !important; }

span[id^="foo-bar-"] {
  border: thin solid black;
  margin: 0.25em;
}

Answer №4

Give this a try:

::-webkit-scrollbar {
    width: 0px;  /* get rid of scrollbar */
    background: transparent;  /* you can also hide the scrollbar */
}
<!DOCTYPE HTML>
<html>
  <body style="overflow: auto;
max-height: 100vh;" onscroll="alert('hello')">
    <div style="height:2000px;width:100%"></div>
  </body>
</html>

Answer №5

The primary reason for only seeing examples of "addEventListener" is due to the necessity of ensuring cross-browser compatibility:

var supportedWheelEvent = "onwheel" in HTMLDivElement.prototype ? "wheel" : document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll";

Moreover, it is advisable to apply this to a single element only! Implement delegated event listener to manage this for all required elements.

Here is an example in HTML:

<div id="delegator">
   <div class="handleWheel">handle wheel event here</div>
   <div> no wheel event handled here </div>
   <div class="handleWheel">handle wheel event here</div>
   <div> no wheel event handled here </div>
</div>

Javascript code:

var supportedWheelEvent = "onwheel" in HTMLDivElement.prototype ? "wheel" : document.onmousewheel !== undefined ? "mousewheel" : "DOMMouseScroll";

function handler(e){
    if(e.target.classList.contains('handleWheel')){
        // handle the event here
    }
}

var d = document.getElementById('delegator');
d.addEventListener(supportedWheelEvent, handler);

Here is a functional codepen demo: https://codepen.io/Mchaov/pen/zwaMmM

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

Automatically redirect to a different page upon clicking the jquery popup button

I integrated a jQuery popup feature on my website to display messages. Now, I am looking to implement a redirect to another page when the user clicks a button within the jQuery popup. However, I am unsure of how to achieve this. <script type="text/ja ...

unique jquery plugin accesses function from external javascript file

As a beginner, I am attempting to create a custom jQuery plugin for which I have a simple HTML form: <form id="registerForm" action = "somepage" method="post" class="mb-sm"> <div class="form-group"> <div class="col-md-12"> ...

iPhone-compatible iFrame with adaptable webpage dimensions

While attempting to embed our page on a client's site, everything looks great in a browser and our media queries are functioning properly. However, we encountered an issue when viewing the embedded page inside an iframe on an iDevice. It seems that th ...

Having trouble understanding Responsive Frameworks such as Bootstrap?

Looking to dive into the world of responsive frameworks, but feeling overwhelmed by options like Bootstrap, Foundation, Gumby, UI Kit, and Semantic UI? You're not alone. With so many choices and comparisons out there, it's easy to get lost in the ...

Remove the active class from a list item using History.js

My goal is to add the active class to a link when clicked in my AJAX app, triggering statechange on History.js. I'm struggling with saving the current active link(s) with the state so that the active class is appropriately added or removed when naviga ...

Steps for Customizing the Font Style of a Certain List Item Tag <li>

I'm struggling to find the right CSS selector to specifically change the font of just one list item. Here's the current structure: <ul id="menu-applemain class="x-nav> <li>One</li> <li>Two</li> <li>Three</l ...

Tips on preventing the insertion of special characters into a form field with the help of jQuery

I'm implementing a feature to restrict users from using special characters in the text input field. While I have successfully prevented users from typing these characters, I am also looking to prevent the pasting of any special characters as well. FID ...

Utilizing numerous Nuxt vuetify textfield components as properties

Trying to create a dynamic form component that can utilize different v-models for requesting data. Component: <v-form> <v-container> <v-row> <v-col cols="12" md="4"> <v ...

Scrolling the Ionic framework to a position below zero

My ion scroll is synchronized with another component for scrolling. I achieve this by using the function scroll1.scrollTo(left, top, false); Unfortunately, this function does not allow scrolling to a negative position, such as scroll1.scrollTo(left, -50, ...

An issue with jQuery's :not selector and hash symbol syntax

I encountered a syntax error that is quite charming. It appears when attempting to select all anchor tags without an href attribute containing a placeholder URL, such as href="#". Here are the attempts I have made: $("a:not(href='#')"); // cha ...

What is the process for extracting values from a Proxy object and assigning them to a local variable?

Can anyone help guide me on how to retrieve a list of devices (video and input/output audio) using navigator.mediaDevices.enumerateDevices()? I created a function that returns the result, but when I try to display it with console.log(result), I only see a ...

The function .classList.remove() is effective when applied to one element, but fails to work on a different element

I am facing an issue where only one element is getting affected when trying to remove classes from multiple elements if certain email input requirements are met. Can someone help me understand why this is happening? Here is the code snippet: const emailI ...

You cannot convert a function to a string while utilizing axios get in nuxtServerInit

While attempting to connect my app to the backend using Udemy's Nuxt.js course, I encountered a GET http://localhost:3000/ 500 (Internal Server Error) on the client side with the following code: import Vuex from 'vuex'; import axios from &a ...

Querying MongoDB to locate books by the same author or those that are categorized in at least one similar category

Looking to discover books by the same author or with at least one matching category. This is how my Book Schema looks: const bookSchema = new Schema( { title: { type: String, required: true }, author:{ ...

Tips for creating a CSS selector for a button

<div class="test" data-credit-card-index="1"> <button class="test1 test">Delete</button> <button class="test1 test">Edit</button> I'm trying to create a CSS locator specifically for the Edit button within the [d ...

Concealing a Parent Container Using jQuery

I've been attempting to hide a certain div with a value of 9, but my current method doesn't seem to be working... The Hide Function I'm Using: <script> $('.hhpt-housebox').each(function() { if($(this).val() < 9 ...

Utilize the string module from a JavaScript file in your React or Next.js project

Within my project structure, I have a file named "test.js" located in the "/constants" directory. The content of this file is as follows: const test = "test!" export default test In another part of my project, specifically within the "/pages" folder, I w ...

Guide to aligning form data with Bootstrap

Struggling to align my form data in the center below. I have attempted various online solutions without success. The use of bootstrap and offset is causing issues with the title for the form and the actual form itself. Any suggestions would be highly appre ...

Error message when using Vue Global Filter: Value undefined is not defined

Trying to format currency, I initially attempted to use a global filter in Vue: Vue.filter('formatMoney', (val) => { if (!value) return '' val = val.toString() return val.replace(/\B(?=(\d{3})+(?!\d))/g, ",") ...

What is the best way to extract the body content from a Markdown file that includes Frontmatter

How can I retrieve the content of the body from my markdown file using front matter? Currently, it is displaying as undefined. What steps should I take to fix this issue? {latest.map(({ url, frontmatter }) => ( <PostCard url={url} content={frontmat ...