javascript - Identifiera window.scroll-händelsen när den utlöses av användaren ELLER av en kod som körs av en händelse


Har vi ett sätt att identifiera om window.scroll-händelsen har utlösts av en användarmus eller genom att anropa en funktion vid någon händelse. Jag använder ES6, TypeScript med Angular.

Jag ser att denna fråga har ställts tidigare gällande jQuery och den föreslagna lösningen, som klistrats in nedan, fungerar INTE längre. e.originalEvent finns alltid där oavsett hur scrollningen har utlösts.

$('#scroller').scroll(function(e) {
    if (e.originalEvent) {
        console.log('scroll happen manual scroll');
    } else {
        console.log('scroll happen by call');
    }
});

Svar #1

Du kan använda musens wheel event, onwheel, för att upptäcka om scrollningen initierades av musen eller inte.

Men detta är enbart begränsat till situationen när användaren skrollar med mushjulet medan markören är inne i den aktuella behållaren och kommer inte att åtgärda problemet när användaren tar tag i och flyttar rullningslisten eller när skrollningen utlöses av upp- eller nedåtpiltangenterna.

Ett bättre tillvägagångssätt kan vara att vända logiken för hur isWheel-flaggan hanteras i utdraget nedan, och använda en isNotWheel-flagga som sätts/avmarkeras av de handlare som triggas programmässigt och kommer att rulla innehållet i containern.

Observera att timer och Set/ClearTimeout används i exemplet för att tillräckligt stödja Firefox som endast avger wheel-händelsen en gång vid början av en mushjul-rullning, i kontrast till Chrome som avger både wheel-händelsen och scroll-händelsen under hela rullningsrörelsen.

$(() => {

  const main = document.getElementsByTagName('article')[0];
  const a = document.getElementsByTagName('a')[0];
  let isWheel = false;
  let timer = null;
  
  $(main).scroll( e => {
    clearTimeout(timer)
    timer = setTimeout(() => {
      isWheel = false;
    }, 100);
    
    if (isWheel) {
      console.log('Scroll triggered by mouse wheel');
    } else {
      console.log('Scroll NOT triggered by mouse wheel');
    } 
  });
  main.addEventListener('wheel', e => {
    isWheel = true;
  });
  
  $(a).click( e => {
    main.scrollTo(0, 0);
  });
  
})
.main {
  height: 150px;
  overflow-y: scroll;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<article class="main">
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
<div>
 scroll me
</div>
</article>
<a href="javascript:void(0);">Trigger scroll by "function"</a>