JS: Automati c прокрутка, когда мышь бездействует, палец не касается? - PullRequest
1 голос
/ 01 мая 2020

Я знаю, что люди будут жаловаться, что я не показываю код здесь, но я не вижу большой ценности, чтобы опубликовать мою попытку Jquery / JS. Единственная важная часть состоит в том, что я хотел бы сделать это в div

мои div теперь похожи на

#wrapper {overflow:hidden, width:100%; height:100%, position: absolute}
#content_inside_wrapper {width:100%; height:3000px}  //height is given, never auto

По сути, то, что я пытаюсь сделать, и мне нужна помощь, это иметь некоторый код JS, который автоматически прокручивает #content_inside_wrapper по вертикали только в одном направлении (скажем, сверху вниз), когда пользователь не взаимодействует с ним, но затем перезаписывает автопрокрутку, когда пользователь прокручивает колесо мыши или перетащите пальцами, а затем вернитесь к автомату c, когда мышь снова бездействует или пользователь перестает касаться.

Ответы [ 4 ]

1 голос

У меня есть решение:

ScrollRate = 100;

function scrollDiv_init() {
    DivElmnt = document.getElementById('content_inside_wrapper');
    ReachedMaxScroll = false;

    DivElmnt.scrollTop = 0;
    PreviousScrollTop = 0;

    ScrollInterval = setInterval('scrollDiv()', ScrollRate);
}

function scrollDiv() {

    if (!ReachedMaxScroll) {
        DivElmnt.scrollTop = PreviousScrollTop;
        PreviousScrollTop++;

        ReachedMaxScroll = DivElmnt.scrollTop >= (DivElmnt.scrollHeight - DivElmnt.offsetHeight);
    }
    else {
        ReachedMaxScroll = (DivElmnt.scrollTop == 0) ? false : true;

        DivElmnt.scrollTop = PreviousScrollTop;
        PreviousScrollTop--;
    }
}

function pauseDiv() {
    clearInterval(ScrollInterval);
}

function resumeDiv() {
    PreviousScrollTop = DivElmnt.scrollTop;
    ScrollInterval = setInterval('scrollDiv()', ScrollRate);
}
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Auto Scroll</title>
    <script src="app.js"></script>
    
</head>

<body onLoad="scrollDiv_init()">
    <div id="content_inside_wrapper" style="overflow:auto;width:50%;height:100px" onMouseOver="pauseDiv()"
        onMouseOut="resumeDiv()">
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
            Error provident suscipit cumque quaerat ex, quos neque modi iste.
            Quia veniam ipsa possimus expedita!
            Mollitia saepe repudiandae nobis dolorum expedita neque?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
            Error provident suscipit cumque quaerat ex, quos neque modi iste.
            Quia veniam ipsa possimus expedita!
            Mollitia saepe repudiandae nobis dolorum expedita neque?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
            Error provident suscipit cumque quaerat ex, quos neque modi iste.
            Quia veniam ipsa possimus expedita!
            Mollitia saepe repudiandae nobis dolorum expedita neque?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
            Error provident suscipit cumque quaerat ex, quos neque modi iste.
            Quia veniam ipsa possimus expedita!
            Mollitia saepe repudiandae nobis dolorum expedita neque?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
            Error provident suscipit cumque quaerat ex, quos neque modi iste.
            Quia veniam ipsa possimus expedita!
            Mollitia saepe repudiandae nobis dolorum expedita neque?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
            Error provident suscipit cumque quaerat ex, quos neque modi iste.
            Quia veniam ipsa possimus expedita!
            Mollitia saepe repudiandae nobis dolorum expedita neque?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
            Error provident suscipit cumque quaerat ex, quos neque modi iste.
            Quia veniam ipsa possimus expedita!
            Mollitia saepe repudiandae nobis dolorum expedita neque?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
            Error provident suscipit cumque quaerat ex, quos neque modi iste.
            Quia veniam ipsa possimus expedita!
            Mollitia saepe repudiandae nobis dolorum expedita neque?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
            Error provident suscipit cumque quaerat ex, quos neque modi iste.
            Quia veniam ipsa possimus expedita!
            Mollitia saepe repudiandae nobis dolorum expedita neque?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
            Error provident suscipit cumque quaerat ex, quos neque modi iste.
            Quia veniam ipsa possimus expedita!
            Mollitia saepe repudiandae nobis dolorum expedita neque?</p>
        <p>Lorem ipsum dolor sit amet consectetur adipisicing elit.
            Error provident suscipit cumque quaerat ex, quos neque modi iste.
            Quia veniam ipsa possimus expedita!
            Mollitia saepe repudiandae nobis dolorum expedita neque?</p>

    </div>

</body>

</html>
1 голос
/ 02 мая 2020

Вот мой взгляд на вашу проблему: мы можем использовать window.requestAnimationFrame, чтобы выполнить прокрутку для вас. Причина, по которой я выбираю не использовать window.setTimeout() или window.setInterval(), заключается в том, что он не очень надежен (подвержен дрейфу), поскольку выполнение его обратных вызовов выдвигается до конца стека вызовов. window.requestAnimationFrame будет прокручивать ваш элемент, как только браузер сможет снова перерисовать, что оптимизирует производительность.

Затем вы можете прервать рекурсивный вызов window.requestAnimationFrame при обнаружении определенного события (например, mousewheel или touchend), а затем установите тайм-аут для возобновления прокрутки.

См. пример проверки концепции ниже:

const scrollSpeedPerSecond = 150;
const scroller = document.getElementById('wrapper');
const timeToWaitBeforeResumeScrolling = 1000;
let previousTimestamp;
let allowScroll = true;

function scrollStep() {
  if (!previousTimestamp)
    previousTimestamp = new Date().getTime();
    
  const currentTimestamp = new Date().getTime();
  const elapsedTime = currentTimestamp - previousTimestamp;

  const scrollY = scrollSpeedPerSecond / 1000 * (currentTimestamp - previousTimestamp);

  scroller.scrollBy(0, scrollY);
  
  // Update previous timestamp, so we can diff the next "tick" and see how far we need to scroll on the next invocation
  previousTimestamp = new Date().getTime();

  // We want to only allow recursive calling of itself (basically like a setInterval, when:
  // 1. We have not scrolled to the end of the scroller
  // 2. The `allowScroll` flag is set to true
  if (
    // 1
    scroller.scrollTop < scroller.scrollHeight - scroller.clientHeight &&
    // 2
    allowScroll
  ) {
    window.requestAnimationFrame(scrollStep);
  }
}


// Call scrolling logic onload
window.requestAnimationFrame(scrollStep);

// Interrupt scrolling when certain events are detected
function pauseScrolling() {
  allowScroll = false;
  
  // After a fixed amount of time, we allow resuming of scrolling
  window.setTimeout(() => {
    allowScroll = true;
    previousTimestamp = new Date().getTime();
    window.requestAnimationFrame(scrollStep);
  }, timeToWaitBeforeResumeScrolling);
}

window.addEventListener('mousewheel', pauseScrolling);
document.addEventListener('touchend', pauseScrolling);
body {
  margin: 0;
  padding: 0;
}

#wrapper {
  overflow: hidden;
  width: 100vw;
  height: 100vh;
  position: absolute;
}

#content_inside_wrapper {
  width: 100%;
  height: 3000px;
  background-image:
    linear-gradient(0deg, rgba(255,255,255,0) 98%, rgba(255,255,255,1) 98%),
    linear-gradient(0deg, red, orange, yellow, green, blue, purple);
  background-size: 100% 50px, 100% 100%;
}
<div id="wrapper">
  <div id="content_inside_wrapper">
  </div>
</div>
1 голос
/ 02 мая 2020

Простое решение, которое работает как брелок:

const wrapper = document.getElementById("wrapper");

let timerId;

function initTimer() {
  timerId = setInterval(() => wrapper.scrollBy(0, 1), 50);
}
initTimer();

wrapper.addEventListener("touchstart", () => {clearInterval(timerId)}, {passive: true});
wrapper.addEventListener("touchend", initTimer, {passive: true});
body {overflow: hidden;}
#wrapper {overflow-y: scroll; width:100%; height:100%; position: absolute}
#content_inside_wrapper {width:100%; height:3000px}
<main id="wrapper">
<div id="content_inside_wrapper">Lorem<br>ipsum<br>dolor<br>sit<br>amet,<br>consectetur<br>adipiscing<br>elit.<br>Suspendisse<br>faucibus<br>nibh<br>quis<br>posuere<br>lobortis.<br>Nulla<br>elementum<br>ex<br>consequat<br>orci<br>mattis<br>pulvinar.<br>Suspendisse<br>potenti.<br>Donec<br>consectetur,<br>justo<br>vel<br>mollis<br>porttitor,<br>magna<br>ex<br>suscipit<br>nisi,<br>viverra<br>mollis<br>ante<br>ipsum<br>non<br>arcu.<br>Aenean<br>egestas<br>arcu<br>quis<br>augue<br>ultrices,<br>at<br>mollis<br>nulla<br>vehicula.<br>Quisque<br>vel<br>ipsum<br>vitae<br>neque<br>efficitur<br>malesuada.<br>Nam<br>ac<br>tristique<br>urna.<br>Sed<br>a<br>lacus<br>id<br>augue<br>dapibus<br>venenatis<br>nec<br>scelerisque<br>magna.</div>
</main>
0 голосов
/ 02 мая 2020

Вы можете решить эту проблему с помощью семафора, который по умолчанию имеет зеленый цвет. Если происходит прокрутка, то семафор устанавливается на false (красный), поэтому. Повторяющееся событие будет проверять семафор. Если это правда, тогда он будет выполнять прокрутку и в конце события установит для семафора значение true.

var semaphore = true;

setInterval(function() {
    if (semaphore) {
        window.scrollBy(0, 1);
    }
    semaphore = true;
}, 50);


window.addEventListener("scroll", function(event) {
    if (semaphore) semaphore = false;
});

Вы можете обрабатывать сенсорные события аналогично.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...