ปิดใช้งานการเลื่อนปุ่มลูกศรในเบราว์เซอร์ของผู้ใช้


87

ฉันกำลังสร้างเกมโดยใช้ผ้าใบและจาวาสคริปต์

เมื่อหน้ายาวเกินหน้าจอ (แสดงความคิดเห็น ฯลฯ ) การกดลูกศรลงจะเลื่อนหน้าลงและทำให้เกมไม่สามารถเล่นได้

ฉันจะทำอย่างไรเพื่อป้องกันไม่ให้หน้าต่างเลื่อนเมื่อผู้เล่นต้องการเลื่อนลง

ฉันเดาว่าเป็นเกม Java และนี่ไม่ใช่ปัญหาตราบใดที่ผู้ใช้คลิกที่เกม

ฉันลองวิธีแก้ปัญหาจาก: วิธีปิดใช้งานการเลื่อนหน้าใน FF ด้วยปุ่มลูกศรแต่ฉันไม่สามารถใช้งานได้

คำตอบ:


165

สรุป

เพียงแค่ป้องกันการทำงานของเบราว์เซอร์เริ่มต้น :

window.addEventListener("keydown", function(e) {
    // space and arrow keys
    if([32, 37, 38, 39, 40].indexOf(e.keyCode) > -1) {
        e.preventDefault();
    }
}, false);

คำตอบเดิม

ฉันใช้ฟังก์ชันต่อไปนี้ในเกมของฉันเอง:

var keys = {};
window.addEventListener("keydown",
    function(e){
        keys[e.keyCode] = true;
        switch(e.keyCode){
            case 37: case 39: case 38:  case 40: // Arrow keys
            case 32: e.preventDefault(); break; // Space
            default: break; // do not block other keys
        }
    },
false);
window.addEventListener('keyup',
    function(e){
        keys[e.keyCode] = false;
    },
false);

e.preventDefault();ความมหัศจรรย์ที่เกิดขึ้นใน การดำเนินการนี้จะบล็อกการกระทำเริ่มต้นของเหตุการณ์ในกรณีนี้จะย้ายมุมมองของเบราว์เซอร์

หากคุณไม่ต้องการสถานะปุ่มปัจจุบันคุณสามารถปล่อยkeysและทิ้งการกระทำเริ่มต้นบนปุ่มลูกศร:

var arrow_keys_handler = function(e) {
    switch(e.keyCode){
        case 37: case 39: case 38:  case 40: // Arrow keys
        case 32: e.preventDefault(); break; // Space
        default: break; // do not block other keys
    }
};
window.addEventListener("keydown", arrow_keys_handler, false);

โปรดทราบว่าวิธีนี้ยังช่วยให้คุณสามารถลบตัวจัดการเหตุการณ์ได้ในภายหลังหากคุณต้องการเปิดใช้งานการเลื่อนแป้นลูกศรอีกครั้ง:

window.removeEventListener("keydown", arrow_keys_handler, false);

อ้างอิง


8
ฉันชอบโซลูชันนี้มาก แต่ดูเหมือนจะใช้ไม่ได้ใน chrome = /
Kaninepete

1
@Kaninepete: มีข้อผิดพลาดทางไวยากรณ์ฉันใช้lC.keysแทนkeysในตัวฟังคีย์อัพ แก้ไขปัญหานี้และทดสอบใน Firefox และ Chrome โปรดสังเกตว่าการเปลี่ยนแปลงทั้งหมดkeysเป็นทางเลือก แต่เนื่องจากคุณกำลังสร้างเกม ...
Zeta

ในเบราว์เซอร์รุ่นเก่า (มือถือ) บางตัวดูเหมือนว่าปุ่มลูกศรจะไม่ทำให้เหตุการณ์สำคัญ ๆ ด้วยซ้ำ ... :-(
Michael

1
หากคุณทำเช่นนี้และคุณมีข้อมูลป้อนข้อมูลในหน้าเว็บคุณจะไม่สามารถใช้แป้นเว้นวรรคหรือแป้นลูกศรเพื่อนำทางข้อความได้ ฉันพบข้อเสียเปรียบครั้งใหญ่
Single Entity

9
โปรดทราบว่าคุณจำเป็นต้องใช้keydownไม่ใช่keyupหรือ
Ludder

4

เพื่อความสามารถในการบำรุงรักษาฉันจะแนบตัวจัดการ "การบล็อก" ในองค์ประกอบนั้นเอง (ในกรณีของคุณคือผืนผ้าใบ)

theCanvas.onkeydown = function (e) {
    if (e.key === 'ArrowUp' || e.key === 'ArrowDown') {
        e.view.event.preventDefault();
    }
}

ทำไมไม่เพียงแค่ทำwindow.event.preventDefault()? รัฐMDN :

window.eventเป็นคุณสมบัติ Microsoft Internet Explorer ที่เป็นกรรมสิทธิ์ซึ่งจะพร้อมใช้งานในขณะที่มีการเรียกตัวจัดการเหตุการณ์ DOM เท่านั้น ค่าของมันคืออ็อบเจ็กต์เหตุการณ์ที่กำลังจัดการอยู่

อ่านเพิ่มเติม:


1

ฉันได้ลองใช้วิธีต่างๆในการปิดกั้นการเลื่อนเมื่อกดปุ่มลูกศรทั้ง jQuery และ Javascript ดั้งเดิมซึ่งทั้งหมดทำงานได้ดีใน Firefox แต่ใช้ไม่ได้กับ Chrome เวอร์ชันล่าสุด
แม้อย่างชัดเจน{passive: false}คุณสมบัติสำหรับการwindow.addEventListenerซึ่งเป็นที่แนะนำเป็นเพียงการแก้ปัญหาการทำงานเช่นที่นี่

ในท้ายที่สุดหลังจากลองหลายครั้งฉันก็พบวิธีที่เหมาะกับฉันทั้งใน Firefox และ Chrome:

window.addEventListener('keydown', (e) => {
    if (e.target.localName != 'input') {   // if you need to filter <input> elements
        switch (e.keyCode) {
            case 37: // left
            case 39: // right
                e.preventDefault();
                break;
            case 38: // up
            case 40: // down
                e.preventDefault();
                break;
            default:
                break;
        }
    }
}, {
    capture: true,   // this disables arrow key scrolling in modern Chrome
    passive: false   // this is optional, my code works without it
});

อ้างEventTarget.addEventListener()จากMDN

ตัวเลือกตัวเลือก
   ตัวเลือกวัตถุลักษณะที่ระบุเกี่ยวกับการฟังเหตุการณ์ ตัวเลือกที่มี ได้แก่ :

จับภาพ
   A ที่Booleanระบุว่าเหตุการณ์ประเภทนี้จะถูกส่งไปยังผู้ลงทะเบียนlistenerก่อนที่จะถูกส่งไปที่EventTargetด้านล่างในโครงสร้าง DOM
ครั้งเดียว
   ...
passive
   A Booleanที่ถ้าเป็นจริงแสดงว่าฟังก์ชันที่ระบุlistenerจะไม่เรียกpreventDefault()ใช้ หาก passive listener เรียกpreventDefault()ใช้ตัวแทนผู้ใช้จะไม่ทำอะไรเลยนอกจากสร้างคำเตือนคอนโซล ...

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