javascript 无法检测内容可编辑元素上的滚动事件

iugsix8n  于 2023-09-29  发布在  Java
关注(0)|答案(2)|浏览(96)

我已经尝试了几乎所有的方法来附加滚动事件的内容可编辑。无论如何,我的handleScrollToUpdateRect都不会触发。我已经尝试了wheel事件,它可以工作,但不如scroll事件响应快,因为我的目的是随着内容可编辑div的滚动而不断更新rect。
textField先前定义为:

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);
      };

当在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>
vngu2lb8

vngu2lb81#

这是因为<input type="text">是不可滚动的。
尝试使用textarea,同时确保文本区域可滚动。

HTML

<textarea type='text'>

</textarea>

JavaScript

textArea = document.activeElement;

textArea.addEventListener('scroll', handleScroll, true);

function handleScroll() {
    console.log('scroll');
}

Here is a demo

bkhjykvo

bkhjykvo2#

这是一个变通办法,我尝试使车轮事件模拟滚动事件。它为我的目的工作。
我为真实的的wheel事件添加一个侦听器,然后创建另一个侦听器,它触发一个间隔,该间隔持续快速地触发wheel事件(每10ms)。然后我设置了一个500ms的时间,这样它就不会永远运行。

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);
        }
      });

相关问题