0

So what I have are two divs - div1 and div2. div2 is higher in z-order than div1. div2 is not scrollable while div1 is scrollable. I am capturing the "wheel" event on the div2 element and dispatching them onto div1. I expect div1 to scroll after dispatching the "wheel" event but nothing really happens.

div2.addEventListener("wheel", ev => {
     var new_event = new ev.constructor(ev.type, ev)
     div1.dispatchEvent(new_event);
});

I don't want to manually scroll the div1 by calling div1.scrollBy(...) methods. Any help would be appreciated.

Vishwas
  • 506
  • 1
  • 5
  • 20

2 Answers2

2

Not sure why you want to do this but it's unfortunately not possible because an event dispatched by JavaScript code is not trusted.

See 3.4 Trusted events in the W3C UI Events Specification

Events that are generated by the user agent, either as a result of user interaction, or as a direct result of changes to the DOM, are trusted by the user agent with privileges that are not afforded to events generated by script through the DocumentEvent.createEvent("Event") method, modified using the Event.initEvent() method, or dispatched via the EventTarget.dispatchEvent() method. The isTrusted attribute of trusted events has a value of true, while untrusted events have a isTrusted attribute value of false.

Most untrusted events should not trigger default actions, with the exception of the click event. This event always triggers the default action, even if the isTrusted attribute is false (this behavior is retained for backward-compatibility). All other untrusted events must behave as if the Event.preventDefault() method had been called on that event.

This code demonstrates what happens when you cancel a trusted wheel event, and try to dispatch one with dispatchEvent:

const [container, overlay] = ['container', 'overlay'].map(x => document.getElementsByClassName(x)[0]);

overlay.addEventListener('wheel', e => {
  'use strict'; // Effectively throws an error when trying to assign isTrusted
  console.log(`Is the user event trusted? ${e.isTrusted}`); // true
  e.preventDefault(); // Stops the default behavior
  const newEvent = new e.constructor(e.type, e); // Clone the event
  console.log(`Is the generated event trusted? ${newEvent.isTrusted}`); // false
  try {
    newEvent.isTrusted = true;
  }
  catch (e) {
    console.error(e); // TypeError
  }
  container.dispatchEvent(newEvent);
});

container.addEventListener('wheel', e => {
  console.log(`Wheel event received by the container, is it trusted? ${e.isTrusted} Is it cancelled? ${e.defaultPrevented}`);
  
  // You have to implement the scroll behavior yourself because it won't happen otherwise
});
.container {
  overflow-y: scroll;
  height: 200px;
}

.content {
  height: 600px;
}
 
.overlay {
  position: static;
  width: 100vw;
  height: 100vh;
}
<div class="container">
  <div class="content">
  <div>
</div>

<div class="overlay">
</div>
Guerric P
  • 30,447
  • 6
  • 48
  • 86
0

got the idea from this answer

 const div1 = document.getElementById("div1");
    const div2 = document.getElementById("div2");

    div2.addEventListener("wheel", event => {
        const delta = Math.sign(event.deltaY);
        const evt = document.createEvent('MouseEvents');
        evt.initEvent(
            'wheel', // in DOMString typeArg,
            true,  // in boolean canBubbleArg,
            true  // in boolean cancelableArg,
        );
        evt.deltaY = event.deltaY;
        div1.dispatchEvent(evt);
    }, { passive: true });

    div1.addEventListener('wheel', function (e) {
        let scroll = div1.scrollTop + e.deltaY;
        div1.scrollTop = scroll;
    }, { passive: true });
 #div1 {
        z-index: 5;
        width: 110px;
        height: 110px;
        overflow: scroll;
    }

    #div2 {
        z-index: 1;
        width: 110px;
        border: solid red 1px;
    }
<div id="div1">
        1 Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
        dolore
        magna aliquam erat volutpat.
        Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet
        dolore
        magna aliquam erat volutpat.
    </div>
    <div id="div2">
        2 Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy

    </div>
ashen madusanka
  • 647
  • 1
  • 9
  • 15