it-swarm.com.de

Einfach blättern deaktivieren, nicht verstecken?

Ich versuche, die HTML/Body-Bildlaufleiste des übergeordneten Elements zu deaktivieren, während ich einen Leuchtkasten verwende. Das Hauptwort hier ist disable . Ich will nicht will es mit overflow: hidden; verstecken.

Der Grund dafür ist, dass overflow: hidden die Site springt und den Bereich aufnimmt, in dem sich der Bildlauf befand.

Ich möchte wissen, ob es möglich ist, eine Bildlaufleiste zu deaktivieren, während sie noch angezeigt wird.

166
Dejan.S

Wenn die Seite unter der Überlagerung oben fixiert werden kann, können Sie beim Öffnen der Überlagerung festlegen

body { position: fixed; overflow-y:scroll }

sie sollten immer noch die rechte Bildlaufleiste sehen, der Inhalt kann jedoch nicht gescrollt werden. Wenn Sie die Überlagerung schließen, setzen Sie diese Eigenschaften einfach mit zurück

body { position: static; overflow-y:auto }

Ich habe diesen Weg nur vorgeschlagen, weil Sie kein Bildlaufereignis ändern müssen

Update

Sie können auch eine geringfügige Verbesserung vornehmen: Wenn Sie die document.documentElement.scrollTop -Eigenschaft über Javascript direkt vor dem Öffnen der Ebene erhalten, können Sie diesen Wert dynamisch als top -Eigenschaft des body-Elements zuweisen Sie sind oben oder wenn Sie bereits gescrollt haben. 

Css

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

JS

$('body').css('top', -(document.documentElement.scrollTop) + 'px')
         .addClass('noscroll');
145
fcalderan

Vier kleine Ergänzungen zur ausgewählten Lösung:

  1. Wenden Sie 'noscroll' auf html anstelle von body an, um doppelte Bildlaufleisten im IE zu verhindern
  2. Um zu überprüfen, ob es tatsächlich eine Bildlaufleiste gibt, bevor die Klasse 'noscroll' hinzugefügt wird. Andernfalls springt die Site auch durch die neue nicht scrollbare Bildlaufleiste.
  3. Um alle möglichen scrollTop -Reihen beizubehalten, damit die gesamte Seite nicht an den Anfang zurückkehrt (wie Fabrizios Update, aber Sie müssen den Wert vor dem Hinzufügen der 'noscroll'-Klasse verwenden)
  4. Nicht alle Browser behandeln scrollTop genauso wie unter http://help.dottoro.com/ljnvjiow.php dokumentiert.

Komplette Lösung, die für die meisten Browser zu funktionieren scheint:

CSS

html.noscroll {
    position: fixed; 
    overflow-y: scroll;
    width: 100%;
}

Scroll deaktivieren

if ($(document).height() > $(window).height()) {
     var scrollTop = ($('html').scrollTop()) ? $('html').scrollTop() : $('body').scrollTop(); // Works for Chrome, Firefox, IE...
     $('html').addClass('noscroll').css('top',-scrollTop);         
}

Scroll aktivieren

var scrollTop = parseInt($('html').css('top'));
$('html').removeClass('noscroll');
$('html,body').scrollTop(-scrollTop);

Vielen Dank an Fabrizio und Dejan, die mich auf den richtigen Weg gebracht haben, und an Brodingo für die Lösung für die doppelte Bildlaufleiste

73
Mike Garcia

Mit jQuery enthalten:


deaktivieren

$.fn.disableScroll = function() {
    window.oldScrollPos = $(window).scrollTop();

    $(window).on('scroll.scrolldisabler',function ( event ) {
       $(window).scrollTop( window.oldScrollPos );
       event.preventDefault();
    });
};

aktivieren

$.fn.enableScroll = function() {
    $(window).off('scroll.scrolldisabler');
};

verwendungszweck

//disable
$("#selector").disableScroll();
//enable
$("#selector").enableScroll();
30
ceed

Das hat wirklich gut für mich funktioniert ....

// disable scrolling
$('body').bind('mousewheel touchmove', lockScroll);

// enable scrolling
$('body').unbind('mousewheel touchmove', lockScroll);


// lock window scrolling
function lockScroll(e) {
    e.preventDefault();
}

umhüllen Sie diese beiden Codezeilen einfach mit der Entscheidung, wann Sie das Scrollen blockieren möchten.

z.B.

$('button').on('click', function() {
     $('body').bind('mousewheel touchmove', lockScroll);
});
7
dmackenz

Sie können das Bildlaufereignis nicht deaktivieren, aber Sie können die verwandten Aktionen, die zu einem Bildlauf führen, wie Mausrad und Touchmove, deaktivieren:

$('body').on('mousewheel touchmove', function(e) {
      e.preventDefault();
});
6
tocqueville

Ich bin die OP

Mit Hilfe von answer von fcalderan konnte ich eine Lösung finden. Ich lasse meine Lösung hier, da sie Klarheit in der Verwendung bringt und ein sehr wichtiges Detail hinzufügt. width: 100%;

Ich füge diese Klasse hinzu

body.noscroll
{
    position: fixed; 
    overflow-y: scroll;
    width: 100%;
}

das funktionierte für mich und ich verwendete Fancyapp.

5
Dejan.S

Alternativ können Sie die Bildlaufleiste des Körpers mit overflow: hidden ausblenden und gleichzeitig einen Rand festlegen, damit der Inhalt nicht springt:

let marginRightPx = 0;
if(window.getComputedStyle) {
    let bodyStyle = window.getComputedStyle(document.body);
    if(bodyStyle) {
        marginRightPx = parseInt(bodyStyle.marginRight, 10);
    }
}

let scrollbarWidthPx = window.innerWidth - document.body.clientWidth;
Object.assign(document.body.style, {
    overflow: 'hidden',
    marginRight: `${marginRightPx + scrollbarWidthPx}px`
});

Und dann können Sie der Seite eine deaktivierte Bildlaufleiste hinzufügen, um die Lücke zu füllen:

textarea {
  overflow-y: scroll;
  overflow-x: hidden;
  width: 11px;
  outline: none;
  resize: none;
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  border: 0;
}
<textarea></textarea>

Genau das habe ich für meine eigene Lightbox-Implementierung gemacht. Scheint so gut zu funktionieren.

3
mpen

Dies ist die Lösung, mit der wir gegangen sind. Speichern Sie einfach die Bildlaufposition, wenn die Überlagerung geöffnet ist, blättern Sie bei jedem Versuch des Benutzers, die Seite zu scrollen, zurück zur gespeicherten Position, und schalten Sie den Listener aus, wenn die Überlagerung geschlossen wird.

Es ist ein wenig nervös im IE, funktioniert aber wie ein Zauber in Firefox/Chrome.

var body = $("body"),
  overlay = $("#overlay"),
  overlayShown = false,
  overlayScrollListener = null,
  overlaySavedScrollTop = 0,
  overlaySavedScrollLeft = 0;

function showOverlay() {
  overlayShown = true;

  // Show overlay
  overlay.addClass("overlay-shown");

  // Save scroll position
  overlaySavedScrollTop = body.scrollTop();
  overlaySavedScrollLeft = body.scrollLeft();

  // Listen for scroll event
  overlayScrollListener = body.scroll(function() {
    // Scroll back to saved position
    body.scrollTop(overlaySavedScrollTop);
    body.scrollLeft(overlaySavedScrollLeft);
  });
}

function hideOverlay() {
  overlayShown = false;

  // Hide overlay
  overlay.removeClass("overlay-shown");

  // Turn scroll listener off
  if (overlayScrollListener) {
    overlayScrollListener.off();
    overlayScrollListener = null;
  }
}

// Click toggles overlay
$(window).click(function() {
  if (!overlayShown) {
    showOverlay();
  } else {
    hideOverlay();
  }
});
/* Required */
html, body { margin: 0; padding: 0; height: 100%; background: #fff; }
html { overflow: hidden; }
body { overflow-y: scroll; }

/* Just for looks */
.spacer { height: 300%; background: orange; background: linear-gradient(#ff0, #f0f); }
.overlay { position: fixed; top: 20px; bottom: 20px; left: 20px; right: 20px; z-index: -1; background: #fff; box-shadow: 0 0 5px rgba(0, 0, 0, .3); overflow: auto; }
.overlay .spacer { background: linear-gradient(#88f, #0ff); }
.overlay-shown { z-index: 1; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

<h1>Top of page</h1>
<p>Click to toggle overlay. (This is only scrollable when overlay is <em>not</em> open.)</p>
<div class="spacer"></div>
<h1>Bottom of page</h1>
<div id="overlay" class="overlay">
  <h1>Top of overlay</h1>
  <p>Click to toggle overlay. (Containing page is no longer scrollable, but this is.)</p>
  <div class="spacer"></div>
  <h1>Bottom of overlay</h1>
</div>

2
0b10011

Ich hatte ein ähnliches Problem: ein Menü auf der linken Seite, das das Blättern verhindert, wenn es erscheint. Sobald die Höhe auf 100 vh eingestellt war, verschwand die Bildlaufleiste und der Inhalt ruckte nach rechts.

Wenn Sie also nichts dagegen haben, die Bildlaufleiste aktiviert zu lassen (aber das Fenster auf die volle Höhe einstellen, damit es nicht wirklich irgendwo rollen kann), besteht die Möglichkeit, einen winzigen unteren Rand festzulegen, der die Bildlaufleisten anzeigen lässt:

body {
    height: 100vh;
    overflow: hidden;
    margin: 0 0 1px;
}
1
dhc

Eine grobe Arbeitsweise besteht jedoch darin, den Bildlauf nach oben zu zwingen, wodurch der Bildlauf effektiv deaktiviert wird:

var _stopScroll = false;
window.onload = function(event) {
    document.onscroll = function(ev) {
        if (_stopScroll) {
            document.body.scrollTop = "0px";
        }
    }
};

Wenn Sie den Leuchtkasten öffnen, heben Sie die Fahne an und senken Sie die Fahne, wenn Sie sie schließen.

Live Testfall .

0
Shadow Wizard

<div id="lightbox"> befindet sich innerhalb des <body>-Elements. Wenn Sie also den Leuchtkasten scrollen, scrollen Sie auch den Hauptteil. Die Lösung besteht darin, das <body>-Element nicht über 100% zu erweitern, den langen Inhalt in ein anderes div-Element zu platzieren und bei Bedarf diesem div-Element mit overflow: auto eine Bildlaufleiste hinzuzufügen.

html {
  height: 100%
}
body {
  margin: 0;
  height: 100%
}
#content {
  height: 100%;
  overflow: auto;
}
#lightbox {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
}
<html>
  <body>
    <div id="content">much content</div>
    <div id="lightbox">lightbox<div>
  </body>
</html>

Das Scrollen über die Lightbox (und auch die Variable body) hat jetzt keine Auswirkungen, da der Körper nicht mehr als 100% der Bildschirmhöhe beträgt.

0
Marek C

Wenn die Seite unter der Überlagerung oben fixiert werden kann, können Sie beim Öffnen der Überlagerung festlegen

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

wenn Sie diese Klasse für den scrollbaren Körper bereitstellen, sollte zwar immer noch die rechte Bildlaufleiste angezeigt werden, der Inhalt kann jedoch nicht gescrollt werden.

Um die Position der Seite beizubehalten, tun Sie dies in jquery

$('body').css('top', - ($(window).scrollTop()) + 'px').addClass('disableScroll');

Wenn Sie die Überlagerung schließen, setzen Sie diese Eigenschaften einfach mit zurück

var top = $('body').position().top;
$('body').removeClass('disableScroll').css('top', 0).scrollTop(Math.abs(top));

Ich habe diesen Weg nur vorgeschlagen, weil Sie kein Bildlaufereignis ändern müssen

0
Bhuvan Arora

Alle Javascript-basierten Systeme auf Modal-/Leuchtkasten verwenden einen Überlauf, wenn die Modal-/Lightbox, das HTML-Tag oder das Body-Tag angezeigt wird.

Wenn der Leuchtkasten angezeigt wird, wird der js Push-Überlauf für HTML oder Body-Tag ausgeblendet. Wenn ein Lightbox ausgeblendet ist, entfernen einige den ausgeblendeten Push-Überlauf automatisch für HTML oder Body-Tag.

Entwickler, die unter Mac arbeiten, sehen das Problem der Bildlaufleiste nicht.

Ersetzen Sie einfach das ausgeblendete durch ein nicht festgelegtes Element, damit der Inhalt nicht unter dem Modal des Entfernens der Bildlaufleiste angezeigt wird.

Lightbox öffnen/anzeigen:

<html style="overflow: unset;"></html>

Lightbox schließen/verbergen:

<html style="overflow: auto;"></html>
0
Vizor

Ich bleibe gerne bei der "overflow: hidden" -Methode und füge einfach eine Auffüll-Rechte hinzu, die der Bildlaufleistenbreite entspricht.

Funktion zum Abrufen der Bildlaufleiste durch lostsource .

function getScrollbarWidth() {
    var outer = document.createElement("div");
    outer.style.visibility = "hidden";
    outer.style.width = "100px";
    outer.style.msOverflowStyle = "scrollbar"; // needed for WinJS apps

    document.body.appendChild(outer);

    var widthNoScroll = outer.offsetWidth;
    // force scrollbars
    outer.style.overflow = "scroll";

    // add innerdiv
    var inner = document.createElement("div");
    inner.style.width = "100%";
    outer.appendChild(inner);        

    var widthWithScroll = inner.offsetWidth;

    // remove divs
    outer.parentNode.removeChild(outer);

    return widthNoScroll - widthWithScroll;
}

Wenn Sie das Overlay anzeigen, fügen Sie "noscroll" -Klasse zu html hinzu und fügen Sie dem Körper ein Füllzeichen hinzu:

$(html).addClass("noscroll");
$(body).css("paddingRight", getScrollbarWidth() + "px");

Entfernen Sie die Klasse und die Auffüllung beim Ausblenden:

$(html).removeClass("noscroll");
$(body).css("paddingRight", 0);

Der Noscroll-Stil ist genau dieser:

.noscroll { overflow: hidden; }

Wenn Sie Elemente mit position: fixed haben, müssen Sie die Auffüllung auch zu diesen Elementen hinzufügen.

0
Janne Annala

sie können den Überlauf beibehalten: ausgeblendet, die Bildlaufposition jedoch manuell verwalten:

vor dem Anzeigen der aktuellen Scrollposition nachverfolgen:

var scroll = [$(document).scrollTop(),$(document).scrollLeft()];
//show your lightbox and then reapply scroll position
$(document).scrollTop(scroll[0]).scrollLeft(scroll[1]);

es sollte funktionieren

0
malko