รับงาน mouse wheel ใน jQuery?


130

มีวิธีรับเหตุการณ์ล้อเมาส์ (ไม่พูดถึงscrollเหตุการณ์) ใน jQuery หรือไม่?


1
การค้นหาอย่างรวดเร็วทำให้ปลั๊กอินนี้อาจช่วยได้
Jerad Rose

วิธีนี้ใช้ได้กับฉัน: stackoverflow.com/questions/7154967/jquery-detect-scrolldown
bertie

@thejh โพสต์คำตอบใหม่เกี่ยวกับเรื่องนี้ด้วยเหตุการณ์ DOM3: stackoverflow.com/a/24707712/2256325
Sergio


หมายเหตุเกี่ยวกับเรื่องนี้ หากคุณเพียงแค่ต้องการตรวจจับการเปลี่ยนแปลงของอินพุตและไม่พบการเปลี่ยนแปลงผ่านล้อเลื่อนของเมาส์ลอง$(el).on('input', ...
rybo111

คำตอบ:



201
$(document).ready(function(){
    $('#foo').bind('mousewheel', function(e){
        if(e.originalEvent.wheelDelta /120 > 0) {
            console.log('scrolling up !');
        }
        else{
            console.log('scrolling down !');
        }
    });
});

51
DOMMouseScrollเหตุการณ์ถูกนำมาใช้ใน FF, เพื่อให้คุณได้ฟังทั้ง.bind('DOMMouseScroll mousewheel') {evetns developer.mozilla.org/en-US/docs/DOM/DOM_event_reference/...
mrzmyr

9
e.originalEvent.wheelDeltaไม่ได้กำหนดไว้ใน FF23
hofnarwillie

26
คุณไม่จำเป็นต้องหารด้วย 120 มันเป็นการสิ้นเปลือง CPU โดยเปล่าประโยชน์
venimus

6
ต้องได้รับคำตอบที่ดีที่สุด

2
แต่อย่างไรก็ตามทำไมคุณถึงต้องการหารด้วย 120? ค่าคงที่คืออะไร? (คุณไม่จำเป็นต้องทำตามที่ venimus ชี้ให้เห็น)
mshthn

145

ผูกพันกับทั้งคู่mousewheelและDOMMouseScrollลงเอยด้วยการทำงานได้ดีสำหรับฉัน:

$(window).bind('mousewheel DOMMouseScroll', function(event){
    if (event.originalEvent.wheelDelta > 0 || event.originalEvent.detail < 0) {
        // scroll up
    }
    else {
        // scroll down
    }
});

วิธีนี้ใช้ได้ใน IE9 +, Chrome 33 และ Firefox 27


แก้ไข - มี.ค. 2559

ฉันตัดสินใจที่จะทบทวนปัญหานี้อีกครั้งเนื่องจากผ่านมาระยะหนึ่งแล้ว หน้า MDN สำหรับเหตุการณ์การเลื่อนมีวิธีที่ดีในการดึงตำแหน่งการเลื่อนที่ใช้ประโยชน์requestAnimationFrameซึ่งเป็นที่นิยมอย่างมากกับวิธีการตรวจจับก่อนหน้าของฉัน ฉันแก้ไขรหัสเพื่อให้เข้ากันได้ดีขึ้นนอกเหนือจากทิศทางและตำแหน่งการเลื่อน:

(function() {
  var supportOffset = window.pageYOffset !== undefined,
    lastKnownPos = 0,
    ticking = false,
    scrollDir,
    currYPos;

  function doSomething(scrollPos, scrollDir) {
    // Your code goes here...
    console.log('scroll pos: ' + scrollPos + ' | scroll dir: ' + scrollDir);
  }

  window.addEventListener('wheel', function(e) {
    currYPos = supportOffset ? window.pageYOffset : document.body.scrollTop;
    scrollDir = lastKnownPos > currYPos ? 'up' : 'down';
    lastKnownPos = currYPos;

    if (!ticking) {
      window.requestAnimationFrame(function() {
        doSomething(lastKnownPos, scrollDir);
        ticking = false;
      });
    }
    ticking = true;
  });
})();

ดูปากกาวานิลลา JS ติดตามเลื่อนโดยเจส Dupuy ( @ blindside85 ) บนCodePen

รหัสนี้ใช้งานได้ในขณะนี้ Chrome v50, Firefox v44, Safari v9, and IE9+

อ้างอิง:


สิ่งนี้ได้ผลดีที่สุดสำหรับฉัน อย่างไรก็ตามสคริปต์นี้ทำงานต่อ "คลิก" ของล้อเลื่อน สิ่งนี้สามารถครอบงำสำหรับบางสคริปต์ที่จะใช้ มีวิธีปฏิบัติต่อเหตุการณ์การเลื่อนแต่ละครั้งเป็นหนึ่งกรณีแทนที่จะเรียกใช้สคริปต์ต่อการคลิกของล้อเลื่อน
ใบแจ้งหนี้

โดยเฉพาะอย่างยิ่ง จากสิ่งที่ฉันได้เห็นหลายคนอาจหลีกเลี่ยงการจัดการกับการติดตามการเลื่อนหรือจะใช้ตัวจับเวลาแทน (เช่นตรวจสอบตำแหน่งของผู้ใช้บนหน้าทุก ๆ x มิลลิวินาทีเป็นต้น) หากมีวิธีแก้ปัญหาที่มีประสิทธิภาพมากกว่านี้ฉันอยากรู้อย่างแน่นอน!
Jesse Dupuy

1
ฉันพบวิธีการดำเนินการนี้stackoverflow.com/questions/23919035/…
invot

1
ขอบคุณสำหรับการอัพเดท. คุณสามารถคัดลอกรหัสของคุณเป็นคำตอบของคุณได้หรือไม่? ไม่เคยรู้เลยว่าวันหนึ่ง codepen จะล่มหรือเปล่า มันเกิดขึ้นก่อน
JDB ยังคงจำ Monica

2
@JesseDupuy ฉันจะโหวตคำตอบนี้ แต่เวอร์ชันที่อัปเดตของคุณใช้ไม่ได้หากเอกสารเหมาะกับมุมมอง ("width: 100vh; height: 100vh") หรือมี "overflow: hidden;" "window.addEventListener ('scroll', callback)" ไม่ใช่คำตอบที่ถูกต้องสำหรับ "window.addEventListener ('mousewheel', callback)"
Daniel

45

ณ ตอนนี้ในปี 2017 คุณสามารถเขียนได้

$(window).on('wheel', function(event){

  // deltaY obviously records vertical scroll, deltaX and deltaZ exist too
  if(event.originalEvent.deltaY < 0){
    // wheeled up
  }
  else {
    // wheeled down
  }
});

ทำงานร่วมกับ Firefox 51, Chrome 56, IE9 + ในปัจจุบัน


37

คำตอบที่พูดถึงเหตุการณ์ "เมาส์วีล" กำลังอ้างอิงถึงเหตุการณ์ที่เลิกใช้งาน เหตุการณ์มาตรฐานเป็นเพียง "ล้อ" ดูhttps://developer.mozilla.org/en-US/docs/Web/Reference/Events/wheel


20
ฉันลองสิ่งเหล่านี้และพบว่า: "wheel" ใช้งานได้ใน Firefox และ IE แต่ไม่ใช่ Chrome "mousewheel" ทำงานใน Chrome และ IE แต่ไม่ใช่ Firefox "DOMMouseScroll" ทำงานได้เฉพาะใน Firefox
Curtis Yallop

1
โอ้โหช่วยประหยัดเวลาได้มากเลย ขอบคุณ!
gustavohenke

3
ดูเหมือนว่า Chrome จะเพิ่มการสนับสนุน "ล้อ" ในเดือนสิงหาคม 2013: code.google.com/p/chromium/issues/detail?id=227454
rstackhouse

2
Safari ยังไม่รองรับเหตุการณ์ล้อ
Thayne

ในฐานะที่เป็นเอกสารของคุณกล่าวว่าwheelเหตุการณ์ที่ได้รับการสนับสนุนในการEdge ไม่ได้IEซึ่งไม่ได้เป็นสิ่งเดียวกัน CanIuse
Alex

16

สิ่งนี้ใช้ได้ผลสำหรับฉัน :)

 //Firefox
 $('#elem').bind('DOMMouseScroll', function(e){
     if(e.originalEvent.detail > 0) {
         //scroll down
         console.log('Down');
     }else {
         //scroll up
         console.log('Up');
     }

     //prevent page fom scrolling
     return false;
 });

 //IE, Opera, Safari
 $('#elem').bind('mousewheel', function(e){
     if(e.originalEvent.wheelDelta < 0) {
         //scroll down
         console.log('Down');
     }else {
         //scroll up
         console.log('Up');
     }

     //prevent page fom scrolling
     return false;
 });

จาก stackoverflow


14

นี่คือสารละลายวานิลลา สามารถใช้ใน jQuery หากเหตุการณ์ส่งผ่านไปยังฟังก์ชันevent.originalEventซึ่ง jQuery ทำให้พร้อมใช้งานเป็นคุณสมบัติของเหตุการณ์ jQuery หรือถ้าอยู่ในcallbackฟังก์ชั่นข้างใต้เราเพิ่มก่อนบรรทัดแรก: event = event.originalEvent;.

รหัสนี้จะปรับความเร็ว / จำนวนล้อให้เป็นปกติและเป็นผลบวกสำหรับสิ่งที่จะเป็นการเลื่อนไปข้างหน้าในเมาส์ทั่วไปและเป็นค่าลบในการเคลื่อนที่ของล้อเมาส์ไปข้างหลัง

การสาธิต: http://jsfiddle.net/BXhzD/

var wheel = document.getElementById('wheel');

function report(ammout) {
    wheel.innerHTML = 'wheel ammout: ' + ammout;
}

function callback(event) {
    var normalized;
    if (event.wheelDelta) {
        normalized = (event.wheelDelta % 120 - 0) == -0 ? event.wheelDelta / 120 : event.wheelDelta / 12;
    } else {
        var rawAmmount = event.deltaY ? event.deltaY : event.detail;
        normalized = -(rawAmmount % 3 ? rawAmmount * 10 : rawAmmount / 3);
    }
    report(normalized);
}

var event = 'onwheel' in document ? 'wheel' : 'onmousewheel' in document ? 'mousewheel' : 'DOMMouseScroll';
window.addEventListener(event, callback);

นอกจากนี้ยังมีปลั๊กอินสำหรับ jQuery ซึ่งมีรายละเอียดมากกว่าในโค้ดและน้ำตาลเพิ่มเติม: https://github.com/brandonaaron/jquery-mousewheel


8

สิ่งนี้ใช้ได้ใน IE, Firefox และ Chrome เวอร์ชันล่าสุด

$(document).ready(function(){
        $('#whole').bind('DOMMouseScroll mousewheel', function(e){
            if(e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0) {
                alert("up");
            }
            else{
                alert("down");
            }
        });
    });

5

วันนี้ฉันติดปัญหานี้และพบว่ารหัสนี้ใช้งานได้ดีสำหรับฉัน

$('#content').on('mousewheel', function(event) {
    //console.log(event.deltaX, event.deltaY, event.deltaFactor);
    if(event.deltaY > 0) {
      console.log('scroll up');
    } else {
      console.log('scroll down');
    }
});


0

ชุดค่าผสมของฉันมีลักษณะเช่นนี้ มันจะจางหายไปและจางหายไปในแต่ละการเลื่อนลง / ขึ้น มิฉะนั้นคุณจะต้องเลื่อนขึ้นไปที่ส่วนหัวเพื่อให้ส่วนหัวจางลง

var header = $("#header");
$('#content-container').bind('mousewheel', function(e){
    if(e.originalEvent.wheelDelta > 0) {
        if (header.data('faded')) {
            header.data('faded', 0).stop(true).fadeTo(800, 1);
        }
    }
    else{
        if (!header.data('faded')) header.data('faded', 1).stop(true).fadeTo(800, 0);
    }
});

สิ่งที่กล่าวมาไม่เหมาะสำหรับการสัมผัส / มือถือฉันคิดว่าอันนี้ทำได้ดีกว่าสำหรับมือถือทั้งหมด:

var iScrollPos = 0;
var header = $("#header");
$('#content-container').scroll(function () {

    var iCurScrollPos = $(this).scrollTop();
    if (iCurScrollPos > iScrollPos) {
        if (!header.data('faded')) header.data('faded', 1).stop(true).fadeTo(800, 0);

    } else {
        //Scrolling Up
        if (header.data('faded')) {
            header.data('faded', 0).stop(true).fadeTo(800, 1);
        }
    }
    iScrollPos = iCurScrollPos;

});

0

ปลั๊กอินที่ @DarinDimitrov โพสต์jquery-mousewheel, เสียกับ jQuery 3+ ขอแนะนำให้ใช้jquery-wheelที่ทำงานร่วมกับ jQuery 3+

หากคุณไม่ต้องการไปเส้นทาง jQuery MDN ขอเตือนอย่างสูงในการใช้mousewheelเหตุการณ์นี้เนื่องจากไม่เป็นมาตรฐานและไม่ได้รับการสนับสนุนในหลาย ๆ ที่ แทนที่จะบอกว่าคุณควรใช้wheelเหตุการณ์เนื่องจากคุณมีความเฉพาะเจาะจงมากขึ้นว่าค่าที่คุณได้รับหมายถึงอะไร รองรับโดยเบราว์เซอร์หลัก ๆ ส่วนใหญ่


0

หากใช้ปลั๊กอิน jquery mousewheel ที่กล่าวถึงแล้วสิ่งที่จะใช้อาร์กิวเมนต์ที่ 2 ของฟังก์ชันตัวจัดการเหตุการณ์ - delta:

$('#my-element').on('mousewheel', function(event, delta) {
    if(delta > 0) {
    console.log('scroll up');
    } 
    else {
    console.log('scroll down');
    }
});

-3

ฉันพบปัญหาเดียวกันเมื่อเร็ว ๆ นี้ที่ $(window).mousewheelกำลังกลับมาundefined

สิ่งที่ฉันทำคือ $(window).on('mousewheel', function() {});

ในการประมวลผลฉันใช้:

function (event) {
    var direction = null,
        key;

    if (event.type === 'mousewheel') {
        if (yourFunctionForGetMouseWheelDirection(event) > 0) {
            direction = 'up';
        } else {
            direction = 'down';
        }
    }
}

คุณไม่ได้บอกว่ามีอะไร newUtilities.getMouseWheelDirection
ccsakuweb

คำถามนี้อยู่นอกเหนือขอบเขต ดังนั้นจึงไม่คัดลอกวางเว็บไซต์
Szymon Toda
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.