この質問はずっと前にここですでに尋ねられました:
ユーザーによるjqueryイベントトリガーの検出またはコードによる呼び出し
しかし、それは決定的に答えられたことはありません(または、おそらく私は単に適切に検索することができません)。
scroll
イベントがユーザーによってトリガーされたか、jQuery animate
関数によってトリガーされたかを検出することはできますか?
私はscroll
イベントが次のようなことをしている間に自分自身をトリガーするのを防ぎたいと思っています:
$(document).scroll(function(){
$("html").stop(true);
var number = 400; //some other stuff is happening here
clearTimeout(tout);
tout = setTimeout(function(){
if(top == $(document).scrollTop()){
$("html").animate({
scrollTop: (number),
easing: "easeInQuad",
duration: 110
});
}
},120);
});
このコードは適しているようです:
$('#scroller').scroll(function(e) {
if (e.originalEvent) {
console.log('scroll happen manual scroll');
} else {
console.log('scroll happen by call');
}
});
ただし、originalEvent
オブジェクトは、アニメーショントリガーを適切に検出できません。
これを行う他の方法はありますか?
多分 :animated
セレクターが役立ちます:
$('#scroller').scroll(function(e) {
if ($(this).is(':animated')) {
console.log('scroll happen by animate');
} else if (e.originalEvent) {
// scroll happen manual scroll
console.log('scroll happen manual scroll');
} else {
// scroll happen by call
console.log('scroll happen by call');
}
});
これがタッチスクリーンデバイスでどのように機能するかはわかりませんが、少なくともデスクトップでは機能します
$(window).on('mousewheel', function(){
//code that will only fire on manual scroll input
});
$(window).scroll(function(){
//code that will fire on both mouse scroll and code based scroll
});
アニメーションの巻物だけをターゲットにする方法はないと思います(受け入れられた答えは私にとってはうまくいきませんでした)。
更新:警告!
残念ながら、'mousewheel'
は、手動でスクロールバーをつかんでドラッグするユーザーや、スクロールバーの矢印ボタンを使用するユーザーをピックアップしないようです:(
タッチスクリーンデバイスでは、スワイプがマウススクロールとしてカウントされるように見えるため、これは問題なく動作します。ただし、これはデスクトップユーザーには最適なソリューションではありません。
@Tonyの受け入れられた回答と@DanielTononのコメントを使用して、次の解決策を思いつきました。
_ var animatedScroll = false;
var lastAnimatedScroll = false;
$(window).scroll(function(event){
lastAnimatedScroll = animatedScroll;
animatedScroll = $('html, body').is(':animated');
});
_
これにより、jqueryが.is(':animated')
を削除してから1ピクセル以上スクロールするという前述の問題が解決され、.is(':animated')
がfalseで終了するようになります。 .is(':animated')
の最後から2番目のバージョンを保存することで、スクロールがアニメーションであるかどうかを(さらに)確認できます。
スクロールがアニメーション化されているかどうかを知りたいときは、lastAnimatedScroll
変数を確認してください。
これは私によって徹底的にテストされていませんが、多くのページの更新で正しいため、十分に機能すると想定します。
この問題でさまざまなソリューションを実装しようとした後、私は自分にとってうまく機能している別のアプローチを思いつきました。
アニメーションが実行されているかどうかに手動のブール値を使用します。
var isRunningAnimation = false;
アニメーション化する直前にtrue
に設定し、jQuery false
コールバック関数でanimate
に設定します。
isRunningAnimation = true;
$('html').animate({
scrollLeft: 100,
scrollTop: 100
}, 400, 'swing', function() {
isRunningAnimation = false;
});
次に、スクロールリスナーでそのブール値を確認します。
$('scroll', function() {
if (!isRunningAnimation) {
// If we made it to here, the animation isn't running
}
});
もちろん、技術的には、ユーザーがアニメーション中に手動でスクロールすることを決定した場合、スクロール時のロジックもトリガーされませんが、これは心配する必要がないEdgeケースのように思えます。
まず、JavaScript関数を作成することをお勧めします
// Attaching scroll event when document/window is loaded
function OnFirstLoad() {
if (document.attachEvent) {
document.attachEvent('onscroll', scrollEvent);
} else if (document.addEventListener) {
document.addEventListener('scroll', scrollEvent, false);
}
}
次に、どちらかを使用します
window.onload = OnFirstLoad;
または
$(document).ready(function () {
OnFirstLoad();
});
このスクロールイベントは関数です
function scrollEvent(e) {
var body = document.body,
html = document.documentElement;
var docHeight = Math.max(body.scrollHeight, body.offsetHeight,
html.clientHeight, html.scrollHeight, html.offsetHeight);
var currentScroll = (document.documentElement && document.documentElement.scrollTop) || document.body.scrollTop;
// implement your logic according to requirement
}