ป้องกันร่างกายไม่ให้เลื่อนเมื่อเปิด modal


347

ฉันต้องการให้ร่างกายหยุดเลื่อนเมื่อใช้เมาส์วีลในขณะที่ Modal (จากhttp://twitter.github.com/bootstrap ) บนเว็บไซต์ของฉันเปิดขึ้น

ฉันพยายามโทรหาจาวาสคริปต์ด้านล่างเมื่อเปิดใช้งานโมดอล แต่ไม่สำเร็จ

$(window).scroll(function() { return false; });

และ

$(window).live('scroll', function() { return false; });

โปรดทราบว่าเว็บไซต์ของเราลดการสนับสนุนสำหรับ IE6, IE7 + ต้องเข้ากันได้

คำตอบ:


469

Bootstrap modalจะเพิ่มคลาสmodal-openให้กับเนื้อความโดยอัตโนมัติเมื่อมีการแสดงไดอะล็อก modal และลบออกเมื่อซ่อนกล่องโต้ตอบ คุณสามารถเพิ่มสิ่งต่อไปนี้ใน CSS ของคุณ:

body.modal-open {
    overflow: hidden;
}

คุณสามารถยืนยันว่ารหัสข้างต้นเป็นของรหัสฐาน Bootstrap CSS แต่นี่เป็นการแก้ไขที่ง่ายในการเพิ่มลงในเว็บไซต์ของคุณ

อัปเดตเมื่อวันที่ 8 กุมภาพันธ์ 2013
สิ่งนี้ได้หยุดทำงานใน Twitter Bootstrap v. 2.3.0 - พวกเขาไม่ได้เพิ่มmodal-openคลาสให้กับร่างกายอีกต่อไป

วิธีแก้ปัญหาคือการเพิ่มคลาสลงในเนื้อความเมื่อคำกริยากำลังจะถูกแสดงและลบออกเมื่อปิดคำกริยา:

$("#myModal").on("show", function () {
  $("body").addClass("modal-open");
}).on("hidden", function () {
  $("body").removeClass("modal-open")
});

อัปเดต 11 มีนาคม 2013 ดูเหมือนว่าmodal-openคลาสจะกลับมาใน Bootstrap 3.0 อย่างชัดเจนเพื่อวัตถุประสงค์ในการป้องกันการเลื่อน:

แนะนำ. modal-open บนตัวเครื่อง (เพื่อให้เราสามารถทำการเลื่อนได้)

ดูสิ่งนี้: https://github.com/twitter/bootstrap/pull/6342 - ดูที่หัวข้อModal


2
สิ่งนี้ไม่ทำงานอีกต่อไปใน bootstrap 2.2.2 หวังว่า. mod-open จะกลับมาอีกในอนาคต ... github.com/twitter/bootstrap/issues/5719
ppetrid

2
@pprid ฉันไม่คิดว่ามันจะกลับมา อ้างอิงจากการเขียนนี้: github.com/twitter/bootstrap/wiki/Upcoming-3.0-changes (ดูที่ด้านล่าง) ข้อความอ้างอิง: "ไม่มีการเลื่อนแบบโมดอลภายในอีกต่อไป แต่โมดอลจะเพิ่มเนื้อหาของพวกเขาและหน้าเลื่อนเพื่อกำหนดโมดอล"
MartinHN

2
@Bagata Cool - ความmodal-openประสงค์จะกลับมาใน Bootstrap 3 ดังนั้นเมื่อเปิดตัวมันควรจะปลอดภัยที่จะลบรหัสข้างต้น
MartinHN

2
นี่คือเหตุผลที่เราควรเลื่อนลงไปเรื่อย ๆ หากคำตอบที่เลือกไม่ตรงกับคุณมีโอกาสที่คุณจะพบอัญมณีเช่นนี้ ไม่ได้คาดหวังคำตอบที่ได้รับการโหวตกว่า 97+ ฝังไว้ใต้ความคิดเห็นที่คนอื่นชอบน้อยกว่า
Mohd Abdul Mujib

2
ปัญหานี้คือเพื่อป้องกันไม่ให้เอกสารเลื่อนไปด้านบนเมื่อมีการเปิด modal คุณจำเป็นต้องเพิ่ม body.modal-open {overflow: visible} โซลูชันของคุณใช้งานได้ในขณะนี้ด้วยข้อเสียที่เอกสารเลื่อนไปด้านบนเมื่อคำกริยาเปิดแล้ว
Patrick

120

คำตอบที่ยอมรับไม่สามารถใช้งานบนมือถือได้ (อย่างน้อย 7 iOS และ iOS 7 อย่างน้อย) และฉันไม่ต้องการให้ MOAR JavaScript ทำงานบนเว็บไซต์ของฉันเมื่อ CSS จะทำ

CSS นี้จะป้องกันไม่ให้หน้าพื้นหลังเลื่อนภายใต้คำกริยา:

body.modal-open {
    overflow: hidden;
    position: fixed;
}

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

ถ้าคุณรู้ว่าวิวพอร์ต ( ปลั๊กอินของฉันสำหรับการเพิ่มวิวพอร์ตไป<body> ) คุณก็สามารถเพิ่มสลับ CSS positionสำหรับ

body.modal-open {
    // block scroll for mobile;
    // causes underlying page to jump to top;
    // prevents scrolling on all screens
    overflow: hidden;
    position: fixed;
}
body.viewport-lg {
    // block scroll for desktop;
    // will not jump to top;
    // will not prevent scroll on mobile
    position: absolute; 
}

ฉันยังเพิ่มสิ่งนี้เพื่อป้องกันไม่ให้หน้าต้นแบบกระโดดไปทางซ้าย / ขวาเมื่อแสดง / ซ่อน modals

body {
    // STOP MOVING AROUND!
    overflow-x: hidden;
    overflow-y: scroll !important;
}

คำตอบนี้คือ x-post


7
ขอบคุณ! โทรศัพท์มือถือ (อย่างน้อยเบราว์เซอร์ของ iOS และ Android) ทำให้ฉันปวดหัวและไม่สามารถทำงานได้หากไม่มีposition: fixedร่างกาย
Raul Rene

ขอขอบคุณที่ใส่รหัสในการป้องกันไม่ให้หน้ากระโดดไปทางซ้าย / ขวาเมื่อแสดง / ซ่อน modals สิ่งนี้มีประโยชน์อย่างมากและฉันยืนยันว่าแก้ไขปัญหาที่ฉันพบบน Safari บน iPhone 5c ที่ใช้ iOS 9.2.1
Elijah Lofgren

6
เพื่อแก้ไขการเลื่อนไปด้านบนคุณสามารถบันทึกตำแหน่งก่อนเพิ่มคลาสจากนั้นหลังจากลบคลาสแล้วให้ทำ window.scroll ไปยังตำแหน่งที่บันทึก นี่คือวิธีที่ฉันคงมันสำหรับตัวเอง: pastebin.com/Vpsz07zd
เครื่องมือ

แม้ว่าฉันรู้สึกว่ามันจะพอดีกับความต้องการขั้นพื้นฐานมาก แต่มันก็เป็นวิธีแก้ไขที่มีประโยชน์ ขอบคุณ
Steve Benner

33

เพียงซ่อนร่างกายส่วนเกินและทำให้ร่างกายไม่ได้เลื่อน เมื่อคุณซ่อนโมดัลให้เปลี่ยนกลับเป็นอัตโนมัติ

นี่คือรหัส:

$('#adminModal').modal().on('shown', function(){
    $('body').css('overflow', 'hidden');
}).on('hidden', function(){
    $('body').css('overflow', 'auto');
})

ยอดเยี่ยม สิ่งนี้ช่วยฉันออก ขอบคุณ
pfcodes

21

คุณสามารถลองตั้งค่าขนาดตัวถังให้เป็นขนาดหน้าต่างที่มีการล้นได้: ซ่อนไว้เมื่อ modal เปิดอยู่


12
การทำเช่นนั้นจะย้ายหน้าจอทุกครั้งที่มีการเปิดคำกริยานั่นไม่สะดวกฉันแค่ต้องปิดการเลื่อนพื้นหลัง
xorinzor

ไม่แน่ใจว่าคุณสามารถแถบเลื่อนเป็นเบราว์เซอร์ที่เกี่ยวข้องและคุณไม่สามารถทำอะไรกับพวกเขาได้มากนัก
charlietfl

คุณสามารถตั้งค่ากิริยาเป็น "แก้ไข" ดังนั้นจะไม่ย้ายเมื่อเลื่อน
charlietfl

8
มันไม่เกี่ยวกับการหยุดคำกริยาจากการเลื่อนมันเกี่ยวกับการหยุดร่างกายในพื้นหลังจากการเลื่อน
xorinzor

1
มันคือหน้าต่างที่เลื่อนถ้าเนื้อความล้น ตัวอย่างเช่นแถบเลื่อนไม่ได้เป็นส่วนหนึ่งของเอกสาร
charlietfl

18

คุณต้องทำมากกว่าคำตอบของ @ charlietfl และบัญชีสำหรับแถบเลื่อนมิฉะนั้นคุณอาจเห็นเอกสาร reflow

การเปิดเป็นกิริยาช่วย:

  1. บันทึกbodyความกว้าง
  2. ตั้งค่าbodyโอเวอร์โฟลว์เป็นhidden
  3. ตั้งค่าความกว้างของร่างกายอย่างชัดเจนเป็นสิ่งที่อยู่ในขั้นตอนที่ 1

    var $body = $(document.body);
    var oldWidth = $body.innerWidth();
    $body.css("overflow", "hidden");
    $body.width(oldWidth);

การปิดตัวช่วย:

  1. ตั้งค่าbodyโอเวอร์โฟลว์เป็นauto
  2. ตั้งค่าbodyความกว้างเป็นauto

    var $body = $(document.body);
    $body.css("overflow", "auto");
    $body.width("auto");

แรงบันดาลใจจาก: http://jdsharp.us/jQuery/minute/calculate-scrollbar-width.php


ฉันได้รับหน้าจอ "น่ากลัว" สำหรับการขาดคำที่ดีกว่าและที่สำคัญสำหรับฉันที่นี่คือการติดตามการตั้งค่าความกว้าง ขอบคุณมาก
Hcabnettek

1
@Hcabnettek ใช่: "jumpy" == "reflow เอกสาร" ดีใจที่มันช่วยคุณ! :-)
jpap

มีวิธีแก้ปัญหา css นี้หรือไม่ ใช้ได้กับเบราว์เซอร์และมือถือทั้งหมดหรือไม่
Ruben

เพียงแค่พิมพ์ผิด: มันจะต้อง$body.css("overflow", "auto");อยู่ในขั้นตอนสุดท้าย :)
schneikai

โอ้ช่างเป็นความคิดที่ยอดเยี่ยมอะไร @jpap คุณช่วยฉันแก้ไขปัญหา reflow ของเอกสารที่กำลังดักฟังฉันเป็นเวลานาน
Goran Radulovic

17

คำเตือน:ตัวเลือกด้านล่างไม่เกี่ยวข้องกับ Bootstrap v3.0.x เนื่องจากการเลื่อนในเวอร์ชันเหล่านั้นได้รับการ จำกัด ไว้อย่างชัดเจนกับตัวช่วย หากคุณปิดใช้งานเหตุการณ์ล้อคุณอาจป้องกันไม่ให้ผู้ใช้บางคนดูเนื้อหาในรูปแบบที่มีความสูงมากกว่าความสูงวิวพอร์ต


อีกตัวเลือกหนึ่ง: กิจกรรมล้อ

เลื่อนเหตุการณ์ไม่เลิก แต่มันเป็นไปได้ที่จะยกเลิกเมาส์วีลและล้อเหตุการณ์ ข้อแม้ที่ยิ่งใหญ่คือเบราว์เซอร์ดั้งเดิมบางรุ่นไม่รองรับ Mozilla เท่านั้นที่เพิ่งเพิ่มการสนับสนุนสำหรับ Gecko 17.0 ในภายหลัง ฉันไม่ทราบว่ามีการแพร่กระจายเต็มรูปแบบ แต่ IE6 + และ Chrome สนับสนุนพวกเขา

นี่คือวิธีการใช้ประโยชน์:

$('#myModal')
  .on('shown', function () {
    $('body').on('wheel.modal mousewheel.modal', function () {
      return false;
    });
  })
  .on('hidden', function () {
    $('body').off('wheel.modal mousewheel.modal');
  });

JSFiddle


JSFiddle ของคุณไม่ทำงานบน Firefox 24, Chrome 24 หรือบน IE9
AxeEffect

@AxeEffect ควรใช้งานได้แล้ว ปัญหาเดียวคือการอ้างอิงภายนอกไปยังไลบรารี Bootstrap มีการเปลี่ยนแปลง ขอบคุณสำหรับหัวขึ้น.
merv

2
สิ่งนี้ไม่ได้ป้องกันอุปกรณ์สัมผัสจากการเลื่อนอุปกรณ์overflow:hiddenจะดีกว่าในตอนนี้
Webinan

5
ทุกอย่างทำงานได้ แต่ไม่ใช่สำหรับอุปกรณ์มือถือ -__- ทดสอบ Android 4.1 และ Chrome
Tower Jimmy

@TowerJimmy คุณอาจต้องยกเลิกการแตะหรือลากเหตุการณ์สำหรับสิ่งนั้น (ถ้าทำได้)
xorinzor

9
/* =============================
 * Disable / Enable Page Scroll
 * when Bootstrap Modals are
 * shown / hidden
 * ============================= */

function preventDefault(e) {
  e = e || window.event;
  if (e.preventDefault)
      e.preventDefault();
  e.returnValue = false;  
}

function theMouseWheel(e) {
  preventDefault(e);
}

function disable_scroll() {
  if (window.addEventListener) {
      window.addEventListener('DOMMouseScroll', theMouseWheel, false);
  }
  window.onmousewheel = document.onmousewheel = theMouseWheel;
}

function enable_scroll() {
    if (window.removeEventListener) {
        window.removeEventListener('DOMMouseScroll', theMouseWheel, false);
    }
    window.onmousewheel = document.onmousewheel = null;  
}

$(function () {
  // disable page scrolling when modal is shown
  $(".modal").on('show', function () { disable_scroll(); });
  // enable page scrolling when modal is hidden
  $(".modal").on('hide', function () { enable_scroll(); });
});

9

ไม่สามารถทำให้ Chrome ทำงานได้โดยเพียงแค่เปลี่ยน CSS เพราะฉันไม่ต้องการให้หน้าเลื่อนกลับไปด้านบน สิ่งนี้ทำงานได้ดี:

$("#myModal").on("show.bs.modal", function () {
  var top = $("body").scrollTop(); $("body").css('position','fixed').css('overflow','hidden').css('top',-top).css('width','100%').css('height',top+5000);
}).on("hide.bs.modal", function () {
  var top = $("body").position().top; $("body").css('position','relative').css('overflow','auto').css('top',0).scrollTop(-top);
});

1
นี่เป็นทางออกเดียวที่ทำงานกับฉันใน bootstrap 3.2
volx757

1
มีการข้ามไปยังปัญหาด้านบนด้วย sidenavs วัสดุเชิงมุม นี่เป็นคำตอบเดียวที่ดูเหมือนว่าจะทำงานได้ในทุกกรณี (เดสก์ท็อป / มือถือ + อนุญาตให้เลื่อนในโมดอล / sidenav + ออกจากตำแหน่งเลื่อนตัวถังได้โดยไม่ต้องกระโดด)
cYrixmorten

นี่เป็นเพียงวิธีการแก้ปัญหาที่ใช้งานได้จริงสำหรับฉัน tx
Deedz

9

ลองอันนี้:

.modal-open {
    overflow: hidden;
    position:fixed;
    width: 100%;
    height: 100%;
}

มันใช้งานได้สำหรับฉัน (รองรับ IE8)


4
งานนี้ position: fixedแต่ยังทำให้คุณสามารถข้ามไปด้านบนเมื่อคุณเปิดกิริยาเมื่อใช้
AlexioVay

8

สำหรับเงินทุนที่คุณอาจลองนี้ (ที่ทำงานเกี่ยวกับFirefox, ChromeและMicrosoft Edge):

body.modal-open {
    overflow: hidden;
    position:fixed;
    width: 100%;
}

หวังว่านี่จะช่วย ...


7

การเพิ่มคลาส 'is-modal-open' หรือการแก้ไขสไตล์ของแท็ก body ด้วย javascript นั้นไม่เป็นไรและมันจะทำงานได้ตามที่ควรจะเป็น แต่ปัญหาที่เราจะเผชิญคือเมื่อร่างกายล้น: ซ่อนไว้มันจะกระโดดขึ้นไปด้านบน (scrollTop จะกลายเป็น 0) นี่จะกลายเป็นปัญหาการใช้งานในภายหลัง

ในฐานะที่เป็นทางออกสำหรับปัญหานี้แทนที่จะเปลี่ยนแท็กเนื้อหาล้น: ซ่อนไว้เปลี่ยนในแท็ก html

$('#myModal').on('shown.bs.modal', function () {
  $('html').css('overflow','hidden');
}).on('hidden.bs.modal', function() {
  $('html').css('overflow','auto');
});

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

6

ฉันไม่แน่ใจเกี่ยวกับรหัสนี้ แต่มันก็คุ้มค่ากับการยิง

ใน jQuery:

$(document).ready(function() {
    $(/* Put in your "onModalDisplay" here */)./* whatever */(function() {
        $("#Modal").css("overflow", "hidden");
    });
});

อย่างที่ฉันพูดไปก่อนหน้านี้ฉันไม่แน่ใจ 100% แต่ลองต่อไป


1
สิ่งนี้ไม่ได้ป้องกันร่างกายจากการเลื่อนในขณะที่โม
ดั

@xorinzor คุณระบุไว้ในส่วนความเห็นของคำตอบของ charlietfl ว่าใช้งานได้ แต่คุณพูดว่า: สิ่งนี้ไม่ได้ป้องกันร่างกายจากการเลื่อนในขณะที่ modal เปิดอยู่
Anish Gupta

จริง แต่ตอนนี้มันเป็นทางออกเดียวที่ทำงานได้บางส่วนและฉันก็สบายดี เหตุผลที่ฉันทำเครื่องหมายคำตอบของเขาว่าเป็นคำตอบก็เพราะก่อนหน้านี้เขามีคำตอบ
xorinzor

@ xorinzor จริง ๆ ฉันคิดว่าฉันตอบก่อนเขา / เธออาจเป็นความผิดพลาดแปลก ๆ
มันดี

5

เมื่อวันที่พฤศจิกายน 2560 Chrome เปิดตัวคุณสมบัติ CSS ใหม่

overscroll-behavior: contain;

ซึ่งแก้ปัญหานี้ได้แม้ในขณะที่เขียนมีการสนับสนุนข้ามเบราว์เซอร์ จำกัด

ดูลิงค์ด้านล่างสำหรับรายละเอียดทั้งหมดและการสนับสนุนเบราว์เซอร์


4

ทางออกที่ดีที่สุดคือโซลูชัน css-only ที่body{overflow:hidden}ใช้โดยคำตอบส่วนใหญ่ คำตอบบางคำเสนอการแก้ไขที่ป้องกัน "กระโดด" ที่เกิดจากแถบเลื่อนที่หายไป; อย่างไรก็ตามไม่มีใครสง่างามเกินไป ดังนั้นฉันจึงเขียนฟังก์ชันทั้งสองนี้และดูเหมือนว่าจะทำงานได้ดี

var $body = $(window.document.body);

function bodyFreezeScroll() {
    var bodyWidth = $body.innerWidth();
    $body.css('overflow', 'hidden');
    $body.css('marginRight', ($body.css('marginRight') ? '+=' : '') + ($body.innerWidth() - bodyWidth))
}

function bodyUnfreezeScroll() {
    var bodyWidth = $body.innerWidth();
    $body.css('marginRight', '-=' + (bodyWidth - $body.innerWidth()))
    $body.css('overflow', 'auto');
}

ตรวจสอบjsFiddle นี้เพื่อดูว่ามีการใช้งานอยู่


นี่ไม่ใช่เรื่องเก่า แต่ไม่มีสิ่งใดที่ใช้ได้เลยสำหรับฉันแม้แต่ซอฉันยังสามารถเลื่อนหน้าต่างฉันหายไปไหน
ลงจอด

เปิดและปิด modal สองสามครั้งและ DIV สีเขียวหลักจะย่อและหดตัว!
Webinan

@Webinan ฉันไม่เห็นสิ่งนี้ใน Chrome บน Win7 เบราว์เซอร์และขนาดวิวพอร์ตของคุณคืออะไร
Stephen M. Harris

1
@smhmic หลังจากเปิดประมาณ 20 ครั้งและปิดความกว้างของ div สีเขียวให้เท่ากับopen modalความกว้างของปุ่ม Chrome เมื่อวันที่ 8
Webinan

คล้ายกับคำตอบของ @ jpap ( stackoverflow.com/a/16451821/5516499 ) แต่มีข้อบกพร่องเพิ่มเติม :-(
Kivi Shapiro

4

หลายคนแนะนำ "ล้น: ซ่อน" ในร่างกายซึ่งจะไม่ทำงาน (ไม่ใช่ในกรณีของฉันอย่างน้อย) เนื่องจากจะทำให้เว็บไซต์เลื่อนไปด้านบน

นี่เป็นวิธีแก้ปัญหาที่เหมาะกับฉัน (ทั้งบนโทรศัพท์มือถือและคอมพิวเตอร์) โดยใช้ jQuery:

    $('.yourModalDiv').bind('mouseenter touchstart', function(e) {
        var current = $(window).scrollTop();
        $(window).scroll(function(event) {
            $(window).scrollTop(current);
        });
    });
    $('.yourModalDiv').bind('mouseleave touchend', function(e) {
        $(window).off('scroll');
    });

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


ดูเหมือนว่าโซลูชันนี้จะแก้ไขข้อบกพร่องของ iOS นี้เช่นกัน: hackernoon.com/…
Gotenks

3

คุณสามารถใช้ตรรกะต่อไปนี้ฉันทดสอบและใช้งานได้ (แม้ใน IE)

   <html>

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js"></script>
<script type="text/javascript">

var currentScroll=0;
function lockscroll(){
    $(window).scrollTop(currentScroll);
}


$(function(){

        $('#locker').click(function(){
            currentScroll=$(window).scrollTop();
            $(window).bind('scroll',lockscroll);

        })  


        $('#unlocker').click(function(){
            currentScroll=$(window).scrollTop();
            $(window).unbind('scroll');

        })
})

</script>

<div>

<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<button id="locker">lock</button>
<button id="unlocker">unlock</button>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>

</div>

2

ฉันไม่แน่ใจ 100% นี้จะทำงานร่วมกับเงินทุน แต่มูลค่าลอง - มันทำงานร่วมกับ Remodal.js ซึ่งสามารถพบได้บน GitHub: http://vodkabears.github.io/remodal/และมันจะทำให้ความรู้สึกของวิธีการ จะค่อนข้างคล้ายกัน

หากต้องการหยุดการข้ามหน้าไปยังด้านบนและยังป้องกันการเปลี่ยนเนื้อหาที่ถูกต้องให้เพิ่มคลาสbodyเมื่อโมเดอเรเตอร์เริ่มต้นและตั้งกฎ CSS เหล่านี้:

body.with-modal {
    position: static;
    height: auto;
    overflow-y: hidden;
}

มันเป็นposition:staticและheight:autoที่รวมกันเพื่อหยุดการกระโดดของเนื้อหาไปทางด้านขวา overflow-y:hidden;หยุดหน้าจากการถูกเลื่อนเบื้องหลังกิริยา


โซลูชันนี้ทำงานได้อย่างสมบูรณ์แบบสำหรับฉันใน Safari 11.1.1, Chrome 67.0.3396.99 และ Firefox 60.0.2 ขอบคุณ!
Dom

2

อิงตามซอนี้: http://jsfiddle.net/dh834zgw/1/

ตัวอย่างต่อไปนี้ (โดยใช้ jquery) จะปิดการใช้งานการเลื่อนหน้าต่าง:

 var curScrollTop = $(window).scrollTop();
 $('html').toggleClass('noscroll').css('top', '-' + curScrollTop + 'px');

และใน CSS ของคุณ:

html.noscroll{
    position: fixed;
    width: 100%;
    top:0;
    left: 0;
    height: 100%;
    overflow-y: scroll !important;
    z-index: 10;
 }

ตอนนี้เมื่อคุณลบโมดอลอย่าลืมลบคลาส noscroll บนแท็ก html:

$('html').toggleClass('noscroll');

ไม่ควรoverflowตั้งค่าเป็นhidden? +1 แม้ว่านี่จะเป็นผลสำหรับฉัน (โดยใช้hidden)
mhulse

2

ฉันมีแถบด้านข้างที่สร้างจากการแฮ็คกล่องกาเครื่องหมาย แต่แนวคิดหลักคือการบันทึกเอกสาร scrollTop และไม่เปลี่ยนระหว่างการเลื่อนหน้าต่าง

ฉันไม่ชอบหน้ากระโดดเมื่อร่างกายกลายเป็น 'ล้น: ซ่อนเร้น'

window.addEventListener('load', function() {
    let prevScrollTop = 0;
    let isSidebarVisible = false;

    document.getElementById('f-overlay-chkbx').addEventListener('change', (event) => {
        
        prevScrollTop = window.pageYOffset || document.documentElement.scrollTop;
        isSidebarVisible = event.target.checked;

        window.addEventListener('scroll', (event) => {
            if (isSidebarVisible) {
                window.scrollTo(0, prevScrollTop);
            }
        });
    })

});


2

น่าเศร้าที่ไม่มีคำตอบข้างต้นแก้ไขปัญหาของฉัน

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

จากนั้นฉันพยายามเพิ่ม.modal-open{overflow:auto;}(ซึ่งคนส่วนใหญ่แนะนำ) แน่นอนมันแก้ไขปัญหา: แถบเลื่อนปรากฏขึ้นหลังจากที่ฉันเปิดคำกริยา อย่างไรก็ตามผลข้างเคียงอื่นออกมาซึ่งก็คือ "พื้นหลังด้านล่างส่วนหัวจะย้ายไปทางซ้ายเล็กน้อยพร้อมกับอีกแถบยาวด้านหลังเป็นกิริยาช่วย"

แถบยาวด้านหลังเป็นกิริยาช่วย

โชคดีหลังจากที่ฉันเพิ่ม{padding-right: 0 !important;}ทุกอย่างได้รับการแก้ไขอย่างสมบูรณ์แบบ ทั้งพื้นหลังส่วนหัวและลำตัวไม่เคลื่อนไหวและโมดัลยังคงใช้แถบเลื่อน

ภาพคงที่

หวังว่าสิ่งนี้จะช่วยให้ผู้ที่ยังคงติดอยู่กับปัญหานี้ โชคดี!


1

ชิ้นส่วนใหญ่อยู่ที่นี่ แต่ฉันไม่เห็นคำตอบใด ๆ ที่รวมเข้าด้วยกัน

ปัญหาคือสามเท่า

(1) ป้องกันการเลื่อนของหน้าต้นแบบ

$('body').css('overflow', 'hidden')

(2) และลบแถบเลื่อน

var handler = function (e) { e.preventDefault() }
$('.modal').bind('mousewheel touchmove', handler)

(3) ทำความสะอาดเมื่อมีการยกเลิกคำกริยา

$('.modal').unbind('mousewheel touchmove', handler)
$('body').css('overflow', '')

หากโมดัลไม่เต็มหน้าจอให้ใช้การเชื่อมต่อ. modal กับการซ้อนทับแบบเต็มหน้าจอ


4
นอกจากนี้ยังป้องกันการเลื่อนภายในโมดอล
Daniel

ปัญหาเดียวกัน. คุณหาทางออกหรือไม่? @ Daniel
AlexioVay

@Vay เรียงจาก ลองดูนี่สิ: blog.christoffer.me/…
แดเนียล

1

โซลูชันของฉันสำหรับ Bootstrap 3:

.modal {
  overflow-y: hidden;
}
body.modal-open {
  margin-right: 0;
}

เพราะสำหรับฉันเพียงoverflow: hiddenในชั้นเรียนไม่ได้ป้องกันหน้าจากการขยับไปทางซ้ายเนื่องจากเดิมbody.modal-openmargin-right: 15px


1

ฉันเพิ่งทำแบบนี้ ...

$('body').css('overflow', 'hidden');

แต่เมื่อ scroller หายไปมันขยับทุกอย่างถูกต้อง 20px ดังนั้นฉันจึงเพิ่ม

$('body').css('margin-right', '20px');

ตรงหลังจากนั้น

ใช้งานได้สำหรับฉัน


ใช้งานได้เฉพาะถ้า modal มีขนาดเล็กกว่าขนาดหน้าจอ
Sergey

1

หากคำกริยามีความสูง / ความกว้าง 100% "mouseenter / leave" จะทำงานเพื่อเปิด / ปิดการเลื่อนได้อย่างง่ายดาย สิ่งนี้ได้ผลจริงสำหรับฉัน:

var currentScroll=0;
function lockscroll(){
    $(window).scrollTop(currentScroll);
} 
$("#myModal").mouseenter(function(){
    currentScroll=$(window).scrollTop();
    $(window).bind('scroll',lockscroll); 
}).mouseleave(function(){
    currentScroll=$(window).scrollTop();
    $(window).unbind('scroll',lockscroll); 
});

1

ทำงานให้ฉัน

$('#myModal').on({'mousewheel': function(e) 
    {
    if (e.target.id == 'el') return;
    e.preventDefault();
    e.stopPropagation();
   }
});

1

ทำไมไม่ทำอย่างที่ Bulma ทำ เมื่อโมดัลใช้งานได้แล้วเพิ่มใน html class. is-clipped ซึ่งเป็น overflow: hidden! important; และนั่นมัน

แก้ไข: Okey, Bulma มีข้อบกพร่องนี้ดังนั้นคุณต้องเพิ่มสิ่งอื่น ๆ เช่น

html.is-modal-active {
  overflow: hidden !important;
  position: fixed;
  width: 100%; 
}

1

เนื่องจากสำหรับฉันแล้วปัญหานี้นำเสนอเป็นส่วนใหญ่บน iOS ฉันให้รหัสเพื่อแก้ไขปัญหานั้นบน iOS เท่านั้น:

  if(!!navigator.platform && /iPad|iPhone|iPod/.test(navigator.platform)) {
    var $modalRep    = $('#modal-id'),
        startScrollY = null, 
        moveDiv;  

    $modalRep.on('touchmove', function(ev) {
      ev.preventDefault();
      moveDiv = startScrollY - ev.touches[0].clientY;
      startScrollY = ev.touches[0].clientY;
      var el = $(ev.target).parents('#div-that-scrolls');
      // #div-that-scrolls is a child of #modal-id
      el.scrollTop(el.scrollTop() + moveDiv);
    });

    $modalRep.on('touchstart', function(ev) {
      startScrollY = ev.touches[0].clientY;
    });
  }

1

คำตอบข้างต้นไม่เหมาะกับฉันอย่างสมบูรณ์ ดังนั้นฉันจึงพบวิธีอื่นที่ใช้งานได้ดี

เพียงเพิ่มscroll.(namespace)ฟังและการตั้งค่าscrollTopของdocumentล่าสุดของมูลค่าของมัน ...

และยังลบผู้ฟังในสคริปต์ปิดของคุณ

// in case of bootstrap modal example:
$('#myModal').on('shown.bs.modal', function () {

  var documentScrollTop = $(document).scrollTop();
  $(document).on('scroll.noScroll', function() {
     $(document).scrollTop(documentScrollTop);
     return false;
  });

}).on('hidden.bs.modal', function() {

  $(document).off('scroll.noScroll');

});

ปรับปรุง

ดูเหมือนว่านี่จะใช้งานไม่ได้กับ Chrome ข้อเสนอแนะใด ๆ ที่จะแก้ไขได้?



0

สำหรับผู้ที่สงสัยว่าจะได้รับเหตุการณ์การเลื่อนสำหรับ modal bootstrap 3 ได้อย่างไร:

$(".modal").scroll(function() {
    console.log("scrolling!);
});
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.