Làm thế nào để tắt cuộn tạm thời?


434

Tôi đang sử dụng plugin scrollTo jQuery và muốn biết liệu có thể tạm thời tắt tính năng cuộn trên phần tử cửa sổ thông qua Javascript không? Lý do tôi muốn tắt tính năng cuộn là khi bạn cuộn trong khi cuộn Để hoạt hình, nó sẽ rất xấu;)

Tất nhiên, tôi có thể thực hiện $("body").css("overflow", "hidden");và sau đó đặt nó trở lại tự động khi hoạt ảnh dừng lại, nhưng sẽ tốt hơn nếu thanh cuộn vẫn hiển thị nhưng không hoạt động.


12
Nếu nó vẫn hiển thị, thì người dùng được đào tạo để nghĩ rằng nó phải hoạt động. Nếu liều không di chuyển hoặc liều không đáp ứng, thì nó sẽ phá vỡ mô hình tinh thần của người dùng về cách trang của bạn hoạt động và dẫn đến nhầm lẫn. Tôi sẽ chỉ tìm một cách tốt hơn để xử lý việc cuộn trong khi hoạt hình, ví dụ như dừng hoạt hình.
Marcus Whybrow

Một giải pháp khác: stackoverflow.com/questions/9280258/
Khắc

Câu trả lời:


731

Sự scrollkiện không thể bị hủy bỏ. Nhưng bạn có thể làm điều đó bằng cách hủy các sự kiện tương tác này: Cuộn
chuột & Chạm và các nút liên quan đến cuộn.

[ Bản demo làm việc ]

// left: 37, up: 38, right: 39, down: 40,
// spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
var keys = {37: 1, 38: 1, 39: 1, 40: 1};

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

function preventDefaultForScrollKeys(e) {
  if (keys[e.keyCode]) {
    preventDefault(e);
    return false;
  }
}

// modern Chrome requires { passive: false } when adding event
var supportsPassive = false;
try {
  window.addEventListener("test", null, Object.defineProperty({}, 'passive', {
    get: function () { supportsPassive = true; } 
  }));
} catch(e) {}

var wheelOpt = supportsPassive ? { passive: false } : false;
var wheelEvent = 'onwheel' in document.createElement('div') ? 'wheel' : 'mousewheel';

// call this to Disable
function disableScroll() {
  window.addEventListener('DOMMouseScroll', preventDefault, false); // older FF
  window.addEventListener(wheelEvent, preventDefault, wheelOpt); // modern desktop
  window.addEventListener('touchmove', preventDefault, wheelOpt); // mobile
  window.addEventListener('keydown', preventDefaultForScrollKeys, false);
}

// call this to Enable
function enableScroll() {
  window.removeEventListener('DOMMouseScroll', preventDefault, false);
  window.removeEventListener(wheelEvent, preventDefault, wheelOpt); 
  window.removeEventListener('touchmove', preventDefault, wheelOpt);
  window.removeEventListener('keydown', preventDefaultForScrollKeys, false);
}

CẬP NHẬT: Đã sửa lỗi máy tính để bàn Chrome và trình duyệt di động hiện đại với trình nghe thụ động


114
Mẹo cho các nhà phát triển khác bị mắc kẹt trong bẫy này: Hãy đảm bảo bạn xóa bất kỳ và tất cả các cuộc gọi 'e.stopPropagation ()' khỏi các nỗ lực jQuery khác để dừng cuộn, bởi vì nó không chỉ không hoạt động, nó còn ngăn sự kiện sủi bọt vào mã NÀY Điều đó làm việc. Hy vọng 30 phút lãng phí của tôi sẽ giúp tiết kiệm thời gian của người khác :)
Dirk van Bergen

4
Bạn có thể thêm 32 (dấu cách) vào mảng phím bị tắt (hiển thị trong phần nhận xét mã).
gblazex

14
Tôi có thể cuộn cái này như tôi vẫn thường làm: sử dụng nhấn nút giữa và di chuyển chuột ... Do đó, mẹo này sẽ không ảnh hưởng đến những người dùng như tôi;)
Denis V

11
Thanh cuộn không bị vô hiệu hóa.
phán đoán

8
Điều này không còn hoạt động nữa trên Chrome
PerrierCitror

427

Làm điều đó đơn giản bằng cách thêm một lớp vào cơ thể:

.stop-scrolling {
  height: 100%;
  overflow: hidden;
}

Thêm lớp sau đó xóa khi bạn muốn bật lại cuộn, được thử nghiệm trong IE, FF, Safari và Chrome.

$('body').addClass('stop-scrolling')

Đối với thiết bị di động , bạn sẽ cần xử lý touchmovesự kiện:

$('body').bind('touchmove', function(e){e.preventDefault()})

Và hủy liên kết để kích hoạt lại cuộn. Đã thử nghiệm trong iOS6 và Android 2.3.3

$('body').unbind('touchmove')

4
Hiểu rồi! Bạn phải xử lý các touchmovesự kiện, như với $('body').bind('touchmove', function(e){e.preventDefault()}). Chỉnh sửa câu trả lời này để bao gồm giải pháp di động này.
MusikAnimal

3
Thật tuyệt, chỉ cần đảm bảo rằng bất kỳ cuộn bên trong nào cũng có thể hoạt động ở chế độ cho thiết bị cảm ứng. Có thể thực hiện một lớp phủ ngay bên dưới phương thức và ngăn chặn cảm ứng mặc định trên lớp phủ thay vì cơ thể.
ảo giác

63
Mặc dù giải pháp này không hoạt động, nhưng nó có tác dụng (có khả năng) không mong muốn là cuộn trở lại đầu trang.
Matt

3
Điều này không hiệu quả với tôi trừ khi người chọn của tôi là$('body,html')
PickYourPoison

22
Giải pháp này hoạt động nhưng thanh cuộn biến mất và tạo hiệu ứng 'vết sưng' (dưới cửa sổ os) khi bạn áp dụng lớp này cho cơ thể (ví dụ)
Georgio

57

Đây là một cách thực sự cơ bản để làm điều đó:

window.onscroll = function () { window.scrollTo(0, 0); };

Đó là loại tăng vọt trong IE6.


14
Không thực sự là vô hiệu hóa, giống như một snap để mặc định khi cuộn được thử.
Marcus Whybrow

11
@Marcus Tốt như nó sẽ nhận được với một sự kiện không thể hủy bỏ.
sdleihssirhc

3
Mặc dù nó không vô hiệu hóa nó thực sự, nhưng nó mô phỏng nó và nó đủ tốt cho tôi.
Chris Bier

11
IMHO - câu trả lời tốt nhất ở đây. Ngoài ra, bạn không phải khóa nó (0, 0), chỉ cần sử dụng vị trí cuộn hiện tại.
YemSalat

4
Nhưng làm thế nào để chúng tôi reenable nó?
Từ trường

41

Giải pháp sau đây là JavaScript cơ bản nhưng thuần túy (không có jQuery):

function disableScrolling(){
    var x=window.scrollX;
    var y=window.scrollY;
    window.onscroll=function(){window.scrollTo(x, y);};
}

function enableScrolling(){
    window.onscroll=function(){};
}

3
Jumpy trong Safari 7.1 và IE 11. Chrome, Firefox, Opera mới nhất ok.
Timo Kähkönen

Vẫn còn một chút giật gân trên Chrome mới nhất
Jason Allshorn

Hoạt động tốt, trong safari, chrome, nhưng nhấp nháy trong IE
Bhuvan Arora

Nếu giải pháp này không hoạt động đối với một số trình duyệt, thì đó là sự cố trình duyệt
Oto Shavadze

Như đã đề cập trên một câu trả lời khác, scroll-behavior: smoothbork này. Ngoài ra, tôi không đồng ý với Oto rằng đó là lỗi của trình duyệt. Về cơ bản, bạn đang cho rằng một cái gì đó sẽ xảy ra ngay lập tức khi trong thực tế nó không đồng bộ
Matt Fletcher

25

Giải pháp này sẽ duy trì vị trí cuộn hiện tại trong khi cuộn bị vô hiệu hóa, không giống như một số bước nhảy người dùng trở lại đầu trang.

Nó dựa trên câu trả lời của galambalazs , nhưng với sự hỗ trợ cho các thiết bị cảm ứng và được tái cấu trúc thành một đối tượng duy nhất với trình bao bọc plugin jquery.

Demo tại đây.

Trên github ở đây.

/**
 * $.disablescroll
 * Author: Josh Harrison - aloof.co
 *
 * Disables scroll events from mousewheels, touchmoves and keypresses.
 * Use while jQuery is animating the scroll position for a guaranteed super-smooth ride!
 */

;(function($) {

    "use strict";

    var instance, proto;

    function UserScrollDisabler($container, options) {
        // spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
        // left: 37, up: 38, right: 39, down: 40
        this.opts = $.extend({
            handleKeys : true,
            scrollEventKeys : [32, 33, 34, 35, 36, 37, 38, 39, 40]
        }, options);

        this.$container = $container;
        this.$document = $(document);
        this.lockToScrollPos = [0, 0];

        this.disable();
    }

    proto = UserScrollDisabler.prototype;

    proto.disable = function() {
        var t = this;

        t.lockToScrollPos = [
            t.$container.scrollLeft(),
            t.$container.scrollTop()
        ];

        t.$container.on(
            "mousewheel.disablescroll DOMMouseScroll.disablescroll touchmove.disablescroll",
            t._handleWheel
        );

        t.$container.on("scroll.disablescroll", function() {
            t._handleScrollbar.call(t);
        });

        if(t.opts.handleKeys) {
            t.$document.on("keydown.disablescroll", function(event) {
                t._handleKeydown.call(t, event);
            });
        }
    };

    proto.undo = function() {
        var t = this;
        t.$container.off(".disablescroll");
        if(t.opts.handleKeys) {
            t.$document.off(".disablescroll");
        }
    };

    proto._handleWheel = function(event) {
        event.preventDefault();
    };

    proto._handleScrollbar = function() {
        this.$container.scrollLeft(this.lockToScrollPos[0]);
        this.$container.scrollTop(this.lockToScrollPos[1]);
    };

    proto._handleKeydown = function(event) {
        for (var i = 0; i < this.opts.scrollEventKeys.length; i++) {
            if (event.keyCode === this.opts.scrollEventKeys[i]) {
                event.preventDefault();
                return;
            }
        }
    };


    // Plugin wrapper for object
    $.fn.disablescroll = function(method) {

        // If calling for the first time, instantiate the object and save
        // reference. The plugin can therefore only be instantiated once per
        // page. You can pass options object in through the method parameter.
        if( ! instance && (typeof method === "object" || ! method)) {
            instance = new UserScrollDisabler(this, method);
        }

        // Instance already created, and a method is being explicitly called,
        // e.g. .disablescroll('undo');
        else if(instance && instance[method]) {
            instance[method].call(instance);
        }

    };

    // Global access
    window.UserScrollDisabler = UserScrollDisabler;

})(jQuery);

Vui vì nó hữu ích. NB Tôi đã chỉnh sửa với một liên kết đến định dạng plugin jQuery này .
Josh Harrison

Có thể giúp nếu nút vô hiệu hóa thực sự hoạt động
cameronjonesweb

@ user1672694, nó hoạt động ở đây trong Chrome. Trình duyệt của bạn là gì và trang demo nào bạn đã tìm thấy lỗi trên? Bất kỳ lỗi JS trong giao diện điều khiển?
Josh Harrison

Trên Chrome (38, Windows 7), tôi vẫn có thể cuộn bằng cách nhấp và giữ nút giữa, sau đó kéo.
Sethi

1
Xin vui lòng bỏ qua, tôi thấy rằng ràng buộc nó mousewheelhoạt động một sự quyến rũ
adamj

17

Tôi rất tiếc khi trả lời một bài viết cũ nhưng tôi đang tìm kiếm một giải pháp và đã gặp câu hỏi này.

Có nhiều cách giải quyết cho vấn đề này vẫn hiển thị thanh cuộn, như cho container có chiều cao 100% và một overflow-y: scroll kiểu dáng.

Trong trường hợp của tôi, tôi vừa tạo một div bằng thanh cuộn mà tôi hiển thị trong khi thêm overflow: hiddenvào phần thân:

function disableScroll() {
    document.getElementById('scrollbar').style.display = 'block';
    document.body.style.overflow = 'hidden';
}

Thanh cuộn phần tử phải có kiểu này:

overflow-y: scroll; top: 0; right: 0; display: none; height: 100%; position: fixed;

Điều này cho thấy một thanh cuộn màu xám, hy vọng nó sẽ giúp khách truy cập trong tương lai.


8

Tôi đang tìm kiếm một giải pháp cho vấn đề này nhưng không hài lòng với bất kỳ giải pháp nào ở trên ( khi viết câu trả lời này ), vì vậy tôi đã đưa ra giải pháp này ..

CSS

.scrollDisabled {   
    position: fixed;
    margin-top: 0;// override by JS to use acc to curr $(window).scrollTop()
    width: 100%;
}

Mã não

var y_offsetWhenScrollDisabled=0;

function disableScrollOnBody(){
    y_offsetWhenScrollDisabled= $(window).scrollTop();
    $('body').addClass('scrollDisabled').css('margin-top', -y_offsetWhenScrollDisabled);
}
function enableScrollOnBody(){
    $('body').removeClass('scrollDisabled').css('margin-top', 0);
    $(window).scrollTop(y_offsetWhenScrollDisabled);
}

Tôi thấy điều này làm việc cho tôi nếu tôi đã thêm overflow-y: scrollvào .scrollDisabledphong cách. Mặt khác, có một bước nhảy nhỏ khi thanh cuộn ẩn mỗi lần. Tất nhiên, điều đó chỉ hoạt động với tôi vì trang của tôi đủ dài để cần một thanh cuộn ngay cả trên màn hình lớn nhất.
Andrew Miner

7

Theo bài đăng của galambalaz, tôi sẽ thêm hỗ trợ cho các thiết bị cảm ứng, cho phép chúng tôi chạm nhưng không cuộn lên hoặc xuống:

function disable_scroll() {
   ...
   document.ontouchmove = function(e){ 
        e.preventDefault(); 
   }
}

function enable_scroll() {
   ...
   document.ontouchmove = function(e){ 
     return true; 
   }
}

3
Bạn có chắc chắn rằng đó là một câu trả lời không chỉ là một nhận xét của câu trả lời khác?
IvanH

6

Kể từ Chrome 56 và các trình duyệt hiện đại khác, bạn phải thêm passive:falsevào addEventListenercuộc gọi để thực hiện preventDefaultcông việc. Vì vậy, tôi sử dụng điều này để dừng cuộn trên điện thoại di động:

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

function disableScroll(){
    document.body.addEventListener('touchmove', preventDefault, { passive: false });
}
function enableScroll(){
    document.body.removeEventListener('touchmove', preventDefault, { passive: false });
}

5

Không, tôi sẽ không xử lý sự kiện vì:

  • không phải tất cả các sự kiện được đảm bảo để đạt được cơ thể,

  • chọn văn bản và di chuyển xuống dưới thực sự cuộn tài liệu,

  • nếu ở giai đoạn của sự kiện tách sth đi sai bạn sẽ phải chịu số phận.

Tôi đã bị cắn bởi điều này bằng cách thực hiện một hành động sao chép-dán với một vùng văn bản ẩn và đoán xem, cuộn trang bất cứ khi nào tôi tạo bản sao vì trong nội bộ tôi phải chọn vùng văn bản trước khi tôi gọi document.execCommand('copy').

Dù sao đó là con đường tôi đi, hãy chú ý setTimeout():

document.body.setAttribute('style','overflow:hidden;');
// do your thing...
setTimeout(function(){document.body.setAttribute('style','overflow:visible;');}, 500);

Một động lượng nhấp nháy tồn tại khi các thanh cuộn biến mất trong giây lát nhưng tôi chấp nhận được.


4

Tùy thuộc vào những gì bạn muốn đạt được với cuộn đã xóa, bạn chỉ có thể sửa phần tử mà bạn muốn xóa cuộn khỏi (khi nhấp hoặc bất kỳ trình kích hoạt nào khác mà bạn muốn tắt tạm thời cuộn)

Tôi đã tìm kiếm một giải pháp "tạm thời không cuộn" và theo nhu cầu của tôi, điều này đã giải quyết nó

làm một lớp

.fixed{
    position: fixed;
}

sau đó với Jquery

var someTrigger = $('#trigger'); //a trigger button
var contentContainer = $('#content'); //element I want to temporarily remove scroll from

contentContainer.addClass('notfixed'); //make sure that the element has the "notfixed" class

//Something to trigger the fixed positioning. In this case we chose a button.
someTrigger.on('click', function(){

    if(contentContainer.hasClass('notfixed')){
        contentContainer.removeClass('notfixed').addClass('fixed');

    }else if(contentContainer.hasClass('fixed')){
        contentContainer.removeClass('fixed').addClass('notfixed');
    };
});

Tôi thấy rằng đây là một giải pháp đủ đơn giản, hoạt động tốt trên tất cả các trình duyệt và cũng sử dụng đơn giản trên các thiết bị di động (ví dụ: iPhone, máy tính bảng, v.v.). Vì phần tử tạm thời được cố định, không có cuộn :)

GHI CHÚ! Tùy thuộc vào vị trí của phần tử "contentContainer" của bạn, bạn có thể cần điều chỉnh nó từ bên trái. Điều này có thể dễ dàng được thực hiện bằng cách thêm giá trị trái css vào phần tử đó khi lớp cố định được kích hoạt

contentContainer.css({
    'left': $(window).width() - contentContainer.width()/2 //This would result in a value that is the windows entire width minus the element we want to "center" divided by two (since it's only pushed from one side)
});

4

Giải pháp khác:

body {
    overflow-y: scroll;
    width: 100%;
    margin: 0 auto;
}

Bằng cách này, bạn luôn có một thanh cuộn dọc, nhưng vì hầu hết nội dung của tôi dài hơn chế độ xem, điều này là ổn đối với tôi. Nội dung được căn giữa với một div riêng biệt, nhưng không đặt lại lề trong nội dung, nội dung của tôi sẽ ở bên trái.

Đây là hai chức năng tôi sử dụng để hiển thị cửa sổ bật lên / phương thức của mình:

var popup_bodyTop = 0;
var popup_bodyLeft = 0;

function popupShow(id)
{
    $('#'+ id).effect('fade');
    $('#popup-overlay').effect('fade');

    // remember current scroll-position
    // because when setting/unsetting position: fixed to body
    // the body would scroll to 0,0
    popup_bodyLeft = $(document).scrollLeft();
    popup_bodyTop  = $(document).scrollTop();

    // invert position
    var x = - popup_bodyLeft;
    var y = - popup_bodyTop;

    $('body').css('position', 'fixed');
    $('body').css('top', y.toString() +'px');
    $('body').css('left', x.toString() +'px');
}

function popupHide(id)
{
    $('#'+ id).effect('fade');
    $('#popup-overlay').effect('fade');
    $('body').css('position', '');
    $('html, body').scrollTop(popup_bodyTop);
    $('html, body').scrollLeft(popup_bodyLeft);
}

Kết quả: nền không thể cuộn và không định vị lại nội dung vì thanh cuộn bên trái. Đã thử nghiệm với FF, Chrome và IE 10 hiện tại.


Điều này làm việc cho tôi và vấn đề cuộn lên trên cùng sau khi sử dụng vị trí: đã sửa. Cảm ơn!
Annia Martinez

3

Còn cái này thì sao? (Nếu bạn đang sử dụng jQuery)

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

window.onscroll = function() {
    var overlay = $body.children(".ui-widget-overlay").first();

    // Check if the overlay is visible and restore the previous scroll state
    if (overlay.is(":visible")) {
        var scrollPos = $body.data("scroll-pos") || { x: 0, y: 0 };
        window.scrollTo(scrollPos.x, scrollPos.y);
    }
    else {
        // Just store the scroll state
        $body.data("scroll-pos", { x: $window.scrollLeft(), y: $window.scrollTop() });
    }
};

một chút khó khăn, nhưng điều này hoạt động cho IE 7 (máy khách sử dụng nó). giải pháp khác thì không.
niki b

3

Tôi đang sử dụng showModalDialog , để hiển thị trang phụ dưới dạng hộp thoại phương thức.

để ẩn thanh cuộn cửa sổ chính:

document.body.style.overflow = "hidden";

và khi đóng hộp thoại phương thức, hiển thị thanh cuộn cửa sổ chính:

document.body.style.overflow = "scroll";

để truy cập các phần tử trong cửa sổ chính từ hộp thoại:

parent.document.getElementById('dialog-close').click();

chỉ dành cho bất kỳ ai đang tìm kiếm về showModalDialog : (sau dòng 29 của mã gốc)

document.getElementById('dialog-body').contentWindow.dialogArguments = arg;
document.body.style.overflow = "hidden";//****
document.getElementById('dialog-close').addEventListener('click', function(e) {
    e.preventDefault();
    document.body.style.overflow = "scroll";//****
    dialog.close();
});

Điều này làm việc cho tôi trong React nơi jQuery không tồn tại và nơi React không có quyền truy cập để quản lý trạng thái của thẻ body.
Jon

3

Hủy bỏ sự kiện như trong câu trả lời được chấp nhận là một phương pháp khủng khiếp theo quan điểm của tôi: /

Thay vào đó tôi sử dụng position: fixed; top: -scrollTop();dưới đây.

Bản demo: https://jsfiddle.net/w9w9hthy/5/

Từ dự án bật lên jQuery của tôi: https://github.com/seahorsepip/jPopup

//Freeze page content scrolling
function freeze() {
    if($("html").css("position") != "fixed") {
        var top = $("html").scrollTop() ? $("html").scrollTop() : $("body").scrollTop();
        if(window.innerWidth > $("html").width()) {
            $("html").css("overflow-y", "scroll");
        }
        $("html").css({"width": "100%", "height": "100%", "position": "fixed", "top": -top});
    }
}

//Unfreeze page content scrolling
function unfreeze() {
    if($("html").css("position") == "fixed") {
        $("html").css("position", "static");
        $("html, body").scrollTop(-parseInt($("html").css("top")));
        $("html").css({"position": "", "width": "", "height": "", "top": "", "overflow-y": ""});
    }
}

Mã này có các vấn đề về chiều rộng, chiều cao, chiều cao, thanh cuộn và pagejump.

Các vấn đề có thể được giải quyết với mã trên:

  • chiều rộng, khi cài đặt vị trí cố định chiều rộng phần tử html có thể nhỏ hơn 100%
  • chiều cao, giống như trên
  • thanh cuộn, khi cài đặt vị trí cố định nội dung trang không còn có thanh cuộn ngay cả khi nó có thanh cuộn trước khi dẫn đến một trang bị lật ngang
  • pagejump, khi cài đặt vị trí cố định, cuộn trang không còn hiệu quả dẫn đến một pagejump dọc

Nếu bất cứ ai có bất kỳ cải tiến nào đối với mã đóng băng / giải phóng trang ở trên, hãy cho tôi biết để tôi có thể thêm những cải tiến đó vào dự án của mình.


3
var winX = null, winY = null;
window.addEventListener('scroll', function () {
    if (winX !== null && winY !== null) {
        window.scrollTo(winX, winY);
    }
});
function disableWindowScroll() {
    winX = window.scrollX;
    winY = window.scrollY;
};
function enableWindowScroll() {
    winX = null;
    winY = null;
};

1
Đây là giải pháp tốt nhất ở đây.
jfunk

@jfunk đồng ý, đơn giản và súc tích, mã nhỏ, hoàn hảo. Cảm ơn bạn
Florent Roques

2

Tôi có cùng một vấn đề, dưới đây là cách tôi xử lý nó.

/* file.js */
var body = document.getElementsByTagName('body')[0];
//if window dont scroll
body.classList.add("no-scroll");
//if window scroll
body.classList.remove("no-scroll");

/* file.css */
.no-scroll{
  position: fixed;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
}

hy vọng điều này giúp đỡ.


1

Dựa trên câu trả lời của Cheyenne Forbes, và một câu hỏi tôi tìm thấy ở đây thông qua fcalderan: Chỉ cần vô hiệu hóa cuộn không che giấu nó? và để khắc phục sự cố biến mất của thanh cuộn Hallodom

CSS:

.preventscroll{
    position: fixed;
    overflow-y:scroll;
}

JS:

whatever.onclick = function(){
    $('body').addClass('preventscroll');
}
whatevertoclose.onclick = function(){
    $('body').removeClass('preventscroll');
}

Mã này sẽ đưa bạn lên đầu trang, nhưng tôi nghĩ rằng mã của fcalderan có một cách giải quyết.


1

Tôi biết đây là một câu hỏi cũ, nhưng tôi đã phải làm một cái gì đó rất giống nhau, và sau một thời gian tìm kiếm một câu trả lời và thử các cách tiếp cận khác nhau, cuối cùng tôi đã sử dụng một giải pháp rất dễ dàng.

Vấn đề của tôi rất giống nhau, gần như giống hệt nhau, điểm khác biệt duy nhất là tôi không thực sự phải hiển thị thanh cuộn - tôi chỉ phải đảm bảo chiều rộng của nó vẫn được sử dụng, vì vậy chiều rộng của trang sẽ không thay đổi trong khi lớp phủ của tôi được hiển thị .

Khi tôi bắt đầu trượt lớp phủ của mình vào màn hình, tôi làm:

$('body').addClass('stop-scrolling').css('margin-right', 8);

và sau khi tôi trượt lớp phủ ra khỏi màn hình, tôi làm:

$('body').removeClass('stop-scrolling').css('margin-right', 0);

QUAN TRỌNG: điều này hoạt động hoàn hảo vì lớp phủ của tôi được định vị absolute, right: 0pxkhi nào visible.


1

Phương pháp đơn giản nhất là:

$("body").css("overflow", "hidden"); // Remove the scroll bar temporarily

Hoàn tác nó:

$("body").css("overflow", "auto");

Dễ thực hiện, nhưng nhược điểm duy nhất là:

  • Trang sẽ nhảy một chút sang trái nếu nó được căn giữa (theo chiều ngang).

Điều này là do thanh cuộn bị loại bỏ và khung nhìn trở nên rộng hơn một chút.


1
sẽ thiết lập lại vị trí cuộn
Angel David Calderaro Pacciott

@AngelDavidCalderaroPacciott Không, vị trí cuộn sẽ vẫn giữ nguyên chiều cao / khoảng cách.
Daan

@Daan nó sẽ đặt lại vị trí cuộn trên Chrome
Tom

@Tom Tôi chỉ kiểm tra nó, nó chỉ thực hiện một số lần (khi chiều cao cơ thể không liên quan đến con cái của nó). Hãy thử thay đổi bodyđể htmlthay thế.
Daan

Tôi cá là bạn đã không kiểm tra giải pháp của mình trong Iphone vì overflow:hiddennó không hoạt động ở đó
Shuvo

1

Đây là giải pháp của tôi để dừng cuộn (không có jQuery). Tôi sử dụng nó để vô hiệu hóa cuộn khi menu bên xuất hiện.

<button onClick="noscroll()" style="position:fixed; padding: 8px 16px;">Disable/Enable scroll</button>
<script>
var noscroll_var;
function noscroll(){
  if(noscroll_var){
    document.getElementsByTagName("html")[0].style.overflowY = "";
    document.body.style.paddingRight = "0";
    noscroll_var = false
  }else{
    document.getElementsByTagName("html")[0].setAttribute('style', 'overflow-y: hidden !important');
    document.body.style.paddingRight = "17px";
    noscroll_var = true
  }
}/*noscroll()*/
</script>

<!-- Just to fill the page -->
<script>
  for(var i=0; i <= 80; i++){
    document.write(i + "<hr>")
  }
</script>

Tôi đặt 17px của padding-right để bù cho sự biến mất của thanh cuộn. Nhưng điều này cũng có vấn đề, chủ yếu là cho các trình duyệt di động. Giải quyết bằng cách lấy chiều rộng thanh theo điều này .

Tất cả cùng nhau trong Bút này.



1

Đây là giải pháp đơn giản nhất tôi có được cho đến nay. Và tôi tin rằng tôi đã thử tất cả những người khác và đây là cách dễ nhất. Nó hoạt động rất tốt trên các thiết bị Windows , giúp đẩy trang từ bên phải để có chỗ cho thanh cuộn hệ thống và các thiết bị IOS không cần không gian cho thanh cuộn của chúng trong trình duyệt. Vì vậy, bằng cách sử dụng điều này, bạn sẽ không cần thêm phần đệm ở bên phải để trang không nhấp nháy khi bạn ẩn phần tràn của phần thân hoặc html bằng css .

Giải pháp khá đơn giản nếu bạn nghĩ về nó. Ý tưởng là cung cấp cho window.scrollTop () vị trí chính xác tương tự tại thời điểm cửa sổ bật lên được mở. Cũng thay đổi vị trí đó khi cửa sổ thay đổi kích thước (vì vị trí cuộn thay đổi một khi điều đó xảy ra).

Vì vậy, ở đây chúng tôi đi ...

Trước tiên, hãy tạo biến sẽ cho bạn biết rằng cửa sổ bật lên đang mở và gọi nó là stopWindowScroll . Nếu chúng tôi không làm điều này thì bạn sẽ gặp lỗi của một biến không xác định trên trang của bạn và đặt nó thành 0 - là không hoạt động.

$(document).ready(function(){
    stopWindowScroll = 0;
});

Bây giờ, hãy làm cho phù thủy chức năng bật mở có thể là bất kỳ chức năng nào trong mã của bạn kích hoạt bất kỳ cửa sổ bật lên nào bạn đang sử dụng làm plugin hoặc tùy chỉnh. Trong trường hợp này, nó sẽ là một cửa sổ bật lên tùy chỉnh đơn giản với một tài liệu đơn giản về chức năng nhấp chuột.

$(document).on('click','.open-popup', function(){
    // Saving the scroll position once opening the popup.
    stopWindowScrollPosition = $(window).scrollTop();
    // Setting the stopWindowScroll to 1 to know the popup is open.
    stopWindowScroll = 1;
    // Displaying your popup.
    $('.your-popup').fadeIn(300);
});

Vì vậy, điều tiếp theo chúng ta làm là tạo chức năng bật lên gần, mà tôi lặp lại một lần nữa có thể là bất kỳ chức năng nào bạn đã tạo hoặc đang sử dụng trong một plugin. Điều quan trọng là chúng ta cần 2 hàm đó để đặt biến stopWindowScroll thành 1 hoặc 0 để biết khi nào nó mở hoặc đóng.

$(document).on('click','.open-popup', function(){
    // Setting the stopWindowScroll to 0 to know the popup is closed.
    stopWindowScroll = 0;
    // Hiding your popup
    $('.your-popup').fadeOut(300);
});

Sau đó, hãy tạo chức năng window.scroll để chúng ta có thể ngăn việc cuộn khi stopWindowScroll được đề cập ở trên được đặt thành 1 - là hoạt động.

$(window).scroll(function(){
    if(stopWindowScroll == 1) {
         // Giving the window scrollTop() function the position on which
         // the popup was opened, this way it will stay in its place.
         $(window).scrollTop(stopWindowScrollPosition);
    }
});

Đó là nó. Không yêu cầu CSS để làm việc này ngoại trừ các kiểu của riêng bạn cho trang. Điều này làm việc như một cơ duyên đối với tôi và tôi hy vọng nó sẽ giúp bạn và những người khác.

Đây là một ví dụ hoạt động trên JSFiddle:

Ví dụ về Fiddle

Hãy cho tôi biết nếu điều này đã giúp. Trân trọng.


1

Lưu trữ chiều dài cuộn trong một biến toàn cục và khôi phục nó khi cần thiết!

var sctollTop_length = 0;

function scroll_pause(){
  sctollTop_length = $(window).scrollTop();
  $("body").css("overflow", "hidden");
}

function scroll_resume(){
  $("body").css("overflow", "auto");
  $(window).scrollTop(sctollTop_length);
}

1

Mã này sẽ hoạt động trên Chrome 56 trở lên (câu trả lời ban đầu không còn hoạt động trên Chrome nữa).

Sử dụng DomUtils.enableScroll()để cho phép cuộn.

Sử dụng DomUtils.disableScroll()để vô hiệu hóa cuộn.

class DomUtils {
  // left: 37, up: 38, right: 39, down: 40,
  // spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36
  static keys = { 37: 1, 38: 1, 39: 1, 40: 1 };

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

  static preventDefaultForScrollKeys(e) {
    if (DomUtils.keys[e.keyCode]) {
      DomUtils.preventDefault(e);
      return false;
    }
  }

  static disableScroll() {
    document.addEventListener('wheel', DomUtils.preventDefault, {
      passive: false,
    }); // Disable scrolling in Chrome
    document.addEventListener('keydown', DomUtils.preventDefaultForScrollKeys, {
      passive: false,
    });
  }

  static enableScroll() {
    document.removeEventListener('wheel', DomUtils.preventDefault, {
      passive: false,
    }); // Enable scrolling in Chrome
    document.removeEventListener(
      'keydown',
      DomUtils.preventDefaultForScrollKeys,
      {
        passive: false,
      }
    ); // Enable scrolling in Chrome
  }
}

1

Để ngăn chặn cú nhảy, đây là những gì tôi đã sử dụng

export function toggleBodyScroll(disable) {
  if (!window.tempScrollTop) {
    window.tempScrollTop = window.pageYOffset; 
    // save the current position in a global variable so I can access again later

  }
  if (disable) {
    document.body.classList.add('disable-scroll');
    document.body.style.top = `-${window.tempScrollTop}px`;
  } else {
    document.body.classList.remove('disable-scroll');
    document.body.style.top = `0px`;
    window.scrollTo({top: window.tempScrollTop});
    window.tempScrollTop = 0;
  }
}

và trong css của tôi

.disable-scroll {
  height: 100%;
  overflow: hidden;
  width: 100%;
  position: fixed;
}

0

Tôi tìm thấy câu trả lời này trên một trang web khác :

Vô hiệu hóa cuộn:

$( ".popup").live({
    popupbeforeposition: function(event, ui) {
    $("body").on("touchmove", false);
}
});

Sau khi đóng cửa sổ phát hành bật lên:

$( ".popup" ).live({
    popupafterclose: function(event, ui) {
    $("body").unbind("touchmove");
}
});

Điều đó dường như chỉ dừng việc cuộn cảm ứng, nhưng cuộn chuột, phím mũi tên, phím lên xuống trang, v.v ... vẫn sẽ hoạt động. -1
markasoftware 22/07/13

Những "sự kiện" này là để cuộn cảm ứng, chỉ cần thay thế bất kỳ sự kiện nào bạn cần.
pennstump

1
Ngoài ra, điều này dường như được sử dụng trong một số tình huống rất cụ thể khác. cửa sổ bật lên? Cái đó được cho là gì? Điều này có liên quan gì đến việc vô hiệu hóa tạm thời cuộn? Ít nhất là làm cho nó phù hợp với tình huống này. Có vẻ như bạn đã sao chép điều này trực tiếp từ một trang web.
markasoftware 26/07/13

0

Giải pháp của galambalazs là tuyệt vời! Nó hoạt động hoàn hảo với tôi trong cả Chrome và Firefox. Và nó cũng có thể được mở rộng để ngăn chặn mọi sự kiện mặc định từ cửa sổ trình duyệt. Giả sử bạn đang làm một ứng dụng trên khung vẽ. Bạn có thể làm điều này:

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

  //spacebar: 32, pageup: 33, pagedown: 34, end: 35, home: 36,
  //left: 37, up: 38, right: 39, down: 40
  keys: [32, 33, 34, 35, 36, 37, 38, 39, 40],
  keydown: function(e) {
    for (var i = events.keys.length; i--;) {
      if (e.keyCode === events.keys[i]) {
        events.preventDefault(e);
        return;
      }
    }
  },

  wheel: function(e) {
    events.preventDefault(e);
  },

  disable: function() {
    if (window.addEventListener) {
      window.addEventListener('DOMMouseScroll', events.wheel, false);
    }
    window.onmousewheel = document.onmousewheel = events.wheel;
    document.onkeydown = helpers.events.keydown;
  },

  enable: function() {
    if (window.removeEventListener) {
      window.removeEventListener('DOMMouseScroll', events.wheel, false);
    }
    window.onmousewheel = document.onmousewheel = document.onkeydown = null;  
  }
}

Và sau đó trên ứng dụng của bạn, giả sử bạn sẽ xử lý các sự kiện của riêng mình, như chuột, bàn phím, chạm vào các sự kiện, v.v ... Bạn có thể tắt các sự kiện mặc định khi chuột vào trong khung vẽ và bật lại chúng khi chuột đi ra:

function setMouseEvents(canvas) {
  var useCapture = false;

  //Mouse enter event
  canvas.addEventListener('mouseenter', function(event) {
    events.disable();
  }, useCapture);

  //Mouse leave event
  canvas.addEventListener('mouseleave', function(event) {
    events.enable();
  }, useCapture);
}

Bạn thậm chí có thể vô hiệu hóa menu chuột phải với bản hack này:

function disableRightClickMenu(canvas) {
  var my_gradient = canvas.context.createLinearGradient(0, 0, 0, 225);
  my_gradient.addColorStop(0, "white");
  my_gradient.addColorStop(1, "white");
  canvas.context.fillStyle = my_gradient;
  canvas.context.fillRect(0, 0, canvas.width, canvas.height);
  canvas.oncontextmenu = function() { return false; };
}

0

Tôi gặp vấn đề về hoạt hình tương tự trên màn hình di động nhưng không phải trên máy tính xách tay, khi cố gắng làm động một div bằng lệnh animate của jquery. Vì vậy, tôi quyết định sử dụng bộ hẹn giờ khôi phục vị trí cuộn của cửa sổ thường xuyên đến mức bằng mắt thường, tài liệu sẽ xuất hiện tĩnh. Giải pháp này hoạt động hoàn hảo trên một thiết bị di động màn hình nhỏ như Samsung Galaxy-2 hoặc iphone-5.

Logic chính của phương pháp này : Bộ định thời gian để đặt vị trí cuộn của cửa sổ thành vị trí cuộn ban đầu nên được khởi động trước lệnh animate jquery, và sau đó khi hoạt ảnh hoàn thành, chúng ta cần xóa bộ hẹn giờ này (original scroll position là vị trí ngay trước khi bắt đầu hoạt hình).

Tôi nhận thấy sự ngạc nhiên thú vị của mình rằng tài liệu thực sự xuất hiện tĩnh trong suốt thời gian hoạt hình nếu khoảng thời gian hẹn giờ là 1 millisecond, đó là điều tôi đang hướng tới.

//get window scroll position prior to animation
//so we can keep this position during animation
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//NOTE:restoreTimer needs to be global variable
//start the restore timer
restoreTimer = setInterval(function() {
    window.scrollTo(xPosition, yPosition);
}, 1);

//animate the element emt
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //when animation completes, we stop the timer
    clearInterval(restoreTimer);
});

GIẢI PHÁP KHÁC đã hoạt động : Dựa trên câu trả lời của Mohammad Anini trong bài đăng này để bật / tắt cuộn, tôi cũng thấy rằng một phiên bản mã được sửa đổi như dưới đây đã hoạt động.

//get current scroll position
var xPosition = window.scrollX || window.pageXOffset || document.body.scrollLeft;
var yPosition = window.scrollY || window.pageYOffset || document.body.scrollTop;

//disable scrolling
window.onscroll = function() {
    window.scrollTo(xPosition, yPosition);
};

//animate and enable scrolling when animation is completed
emt.animate({
    left: "toggle",
    top: "toggle",
    width: "toggle",
    height: "toggle"
}, 500, function() {
    //enable scrolling when animation is done
    window.onscroll = function() {};
});

0

Một giải pháp đơn giản phù hợp với tôi (tạm thời vô hiệu hóa cuộn cửa sổ).

Dựa trên câu đố này: http://jsfiddle.net/dh834zgw/1/

đoạn mã sau (sử dụng jquery) sẽ vô hiệu hóa cuộn cửa sổ:

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

Và trong css của bạn:

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

Bây giờ khi bạn xóa phương thức, đừng quên xóa lớp noscroll trên thẻ html:

$('html').toggleClass('noscroll');
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.