skip to Main Content

I have tried almost every way to attach the scroll event to the content editable. No matter what, my handleScrollToUpdateRect does not trigger. I have tried the wheel event, which works but is not as responsive as the scroll event for my purpose to continuously update a rect as the content editable div is scrolled.

textField was defined previously with:

textField = document.activeElement;
$(textField).on('scroll click keyup', handleScrollToUpdateRect);
$('[contenteditable]').on('scroll keyup click', handleScrollToUpdateRect);
      
$(textField).on('mousemove scroll keyup click', handleScrollToUpdateRect);
      
textField.addEventListener('scroll', function () {
        setTimeout(() => {
          handleScrollToUpdateRect();
        }, 0);
      });
      
textField.addEventListener('scroll', handleScrollToUpdateRect, true);
Array.from(textField.children).forEach(function (child) {
        child.addEventListener('scroll', handleScrollToUpdateRect);
      });
      
textField.onscroll = function (e) {
        //console.log('scrolling');
        handleScrollToUpdateRect(e);
      };
     

Function to be triggered and console log does noting when scrolling inside and content editable div

  function handleScrollToUpdateRect(e) {

    requestAnimationFrame(() => {
      updateRect('rect-before-prompt');
      updateRect('rect-after-prompt');
      checkRectWithinTextField('rect-before-prompt');
      checkRectWithinTextField('rect-after-prompt');
    });
    console.log(' scrolling update rect');
  }

HTML

<div contenteditable="true" aria-multiline="true" role="textbox" class="notranslate IZ65Hb-YPqjbf fmcmS-x3Eknd h1U9Be-YPqjbf" tabindex="0" spellcheck="true" dir="ltr">"..."</div>

2

Answers


  1. Chosen as BEST ANSWER

    This is a workaround I have tried to make the wheel event simulate the scroll event. It works for my purpose.

    I add a listener for the real wheel event, then I create another listener which triggers an interval that continuously fires the wheel event rapidly (every 10ms). Then I set a time out of 500ms so it doesn't run forever.

    let intervalId = null;
          let timeoutId = null;
    
          textField.addEventListener('wheel', function (e) {
            if (!e.isProgrammatic) {
              // Clear any existing interval and timeout
              if (intervalId) clearInterval(intervalId);
              if (timeoutId) clearTimeout(timeoutId);
    
              let counter = 0;
              intervalId = setInterval(function () {
                if (counter < 50) {
                  // total of 100 events
                  var wheelEvent = new WheelEvent('wheel', {
                    bubbles: true,
                    cancelable: true,
                    view: window,
                    deltaX: 0,
                    deltaY: 0,
                    deltaZ: 0,
                  });
    
                  wheelEvent.isProgrammatic = true;
                  textField.dispatchEvent(wheelEvent);
                  counter++;
                } else {
                  clearInterval(intervalId); // Stop after 100 events
                }
              }, 10); // fires every 10ms
    
              // Set a timeout to stop the interval 1 second after the last real wheel event
              timeoutId = setTimeout(function () {
                clearInterval(intervalId);
              }, 500);
            }
          });
    
          // This will handle the programmatic wheel event
          textField.addEventListener('wheel', function (e) {
            if (e.isProgrammatic) {
              setTimeout(() => {
                handleScrollToUpdateRect();
              }, 0);
            }
          });


  2. This is because <input type="text"> is not scrollable.

    Try using a textarea while making sure that the textarea is scrollable.

    HTML

    <textarea type='text'>
    
    
    </textarea>
    

    Javascript

    textArea = document.activeElement;
    
    textArea.addEventListener('scroll', handleScroll, true);
    
    function handleScroll() {
        console.log('scroll');
    }
    

    Here is a demo

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search