Ich habe gestern eine ähnliche Frage gestellt , sie aber schlecht erklärt und meinen Wunsch nach einer reinen CSS-Lösung, die meiner Meinung nach möglich sein sollte, nicht spezifiziert, also versuche ich es erneut.
Grundsätzlich habe ich ein Problem, bei dem ein Teil der scrollbaren Nachrichten und ein Eingabefeld darunter angezeigt werden. Wenn ich auf eine Schaltfläche klicke, möchte ich, dass das Eingabefeld um 100 Pixel vergrößert wird, ohne dass auch das Div der Nachrichten gescrollt wird.
Hier ist eine Geige, die das Problem in seiner Gesamtheit demonstriert
Wie Sie sehen können, wird beim Klicken auf die Schaltfläche "Rand hinzufügen" auch die Meldung div nach oben gescrollt. Ich möchte, dass es dort bleibt, wo es war. Wenn Sie leicht nach oben gescrollt sind, sodass Sie nur die vorletzte Nachricht sehen können, sollte das Klicken auf die Schaltfläche diese Position beim Klicken ebenfalls beibehalten.
Das Interessante ist, dass dieses Verhalten "manchmal" erhalten bleibt. Zum Beispiel wird unter bestimmten Umständen (die ich nicht ganz ableiten kann) die Bildlaufposition beibehalten. Ich möchte nur, dass es sich konsequent als solches verhält.
window.onload = function(e) {
document.querySelector(".messages").scrollTop = 10000;
};
function test() {
document.querySelector(".send-message").classList.toggle("some-margin");
}
.container {
width: 400px;
height: 300px;
border: 1px solid #333;
display: flex;
flex-direction: column;
}
.messages {
overflow-y: auto;
height: 100%;
}
.send-message {
width: 100%;
display: flex;
flex-direction: column;
}
.some-margin {
margin-bottom: 100px;
}
<div class="container">
<div class="messages">
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
<div class="message">hello</div>
</div>
<div class="send-message">
<input />
</div>
</div>
<button onclick="test()">add margin</button>
div
, was nach oben rollt, sondern die Höhe des Div, die abnimmt. Warum ist das so wichtig? Nun, was es bedeutet ist, dass derscrollbar
seine Position nicht anpasst. Die Bildlaufleiste merkt sich nur die Position relativ zum oberen Rand des Containers. Wenn die Höhe des Divs abnimmt, scheint die Bildlaufleiste nach oben zu scrollen, ist es aber nicht.Antworten:
Dies ist eine lustige Lösung, die Ihnen gefallen könnte.
Was wir über das div wissen, ist, dass es nur die oberste Position der Bildlaufleiste beibehält. Wenn sich also die Höhe aus irgendeinem Grund ändert, bleibt die Bildlaufleiste gleich und dies ist der Grund für Ihr Problem.
Um dieses Problem zu umgehen, können Sie den
.messages
180-Grad-transform: rotate(180deg) scaleX(-1);
Wert mit und umdrehen.message
, um das Umdrehen des Inhalts abzubrechen. Das Div behält dann automatisch die untere Bildlaufleiste (die oben ist) bei.quelle
Das normale Verhalten der Bildlaufleiste ist, dass sie sich oben befindet. Wenn Sie sie also beim Laden der Seite auf den unteren Rand setzen, müssen Sie sie selbst beibehalten, da Div Scroll immer dann nach oben verschoben wird, wenn der unten stehende Inhalt sie verschoben hat.
Ich habe also zwei Lösungen für Sie:
Kehren Sie die Nachrichten innerhalb des Nachrichtendivs um, sodass die letzte Nachricht die erste ist und der Bildlauf immer oben ist.
Ich habe eine Javascript-Funktion erstellt, um zum Ende eines Elements zu scrollen, sodass Sie es immer dann aufrufen, wenn Sie zum Ende scrollen möchten.
Überprüfen Sie das Snippet
quelle
Sie können es umgekehrt machen, indem Sie die Höhe dem geben,
.messages
anstatt es dem zu geben..container
In diesem Fall hat dies keine Auswirkungen auf die Nachrichten.div
Wenn Sie es dem geben,.container
wird Ihr Div verschoben, da sich der Rand innerhalb des Hauptbereichs befindet div die eine Höhe haben.Überprüfen Sie dieses Snippet
quelle
.send-message
. Wenn Sie sich meine vorherige Frage ansehen, geschieht dies, weil es dem Randstoß beim Öffnen der virtuellen Tastatur auf Mobilgeräten ähnelt (der Rand unten ist nur ein 1: 1-Ersatz zum Debuggen der Lösung)Die einfache Problemumgehung besteht darin, den vorherigen
scrollTop
Schalter umzuschalten. Hier verwende ich einen Datensatz , um den vorherigenscrollTop
Wert zu speichern . Sie können auch eine Variable verwenden.quelle
Ich meine, das Folgende ist eine reine CSS-Lösung, die genau Ihr Beispiel löst:
aber ich denke nicht, dass es Ihnen bei Ihrem ursprünglichen Problem der virtuellen Tastatur helfen wird. Aber vielleicht kann dies jemand anderen zu einer Lösung inspirieren.
Das Hauptproblem scheint zu sein, dass die Bildlaufleiste bereits vorhanden ist genau das tut, was Sie wollen:
Behalten Sie die Position bei, damit der zuletzt gelesene Inhalt sichtbar ist.
Außer die Bildlaufleiste entscheidet, dass Sie die Oberseite des aktuell sichtbaren Inhalts sehen möchten, nicht die Unterseite. (Es ist einfacher zu erkennen, ob Sie Zahlen verwenden: https://jsfiddle.net/1co3x48n/ )
Wenn Sie bereit sind, Javascript zu verwenden, gibt es alle möglichen Antworten: https://www.google.com/search?q=scrollbar+always+on+bottom+css+site:stackoverflow.com
Ehrlich gesagt, die Tatsache, dass Sie ~ 3 + Seiten davon durchgehen und nur Javascript-Antworten finden können, sagt mir, dass Sie keine Nur-CSS-Antwort finden werden, schon gar keine, die weitgehend browserkompatibel ist.
quelle
Keine der angebotenen Lösungen scheint leider wirklich zu funktionieren. Das Problem bei der Verwendung
onFocus
für ein Textfeld besteht darin, dass es nicht angewendet wird, wenn das Textfeld bereits den Fokus hat. Ich habe stundenlang damit herumgespielt und die nächste Lösung, die ich bisher gefunden habe, ist folgende:Dies scheint jedoch nur manchmal zu funktionieren. Es funktioniert 100% der Zeit, wenn Sie auf das Textfeld klicken, aber aus irgendeinem Grund funktioniert es beim Schließen der virtuellen Tastatur nur, wenn es ausreichend nach oben gescrollt wurde. Andernfalls wird es jedes Mal auf dieselbe Position zurückgesetzt (in der Nähe des Bodens, aber nicht ganz unten).
Ich bin mir nicht sicher, was das verursacht. Ich nehme an, ich muss morgen mehr Nachforschungen anstellen. Dies ist jedoch die bisher nächstgelegene.
quelle
Erstellen Sie einen Container wie in den obigen Beispielen, ändern Sie jedoch einfach das CSS, wenn Sie mit der Eingabe beginnen.
Ich stelle die Position der Bildlaufleiste nicht ein, sondern bewege den gesamten Nachrichtencontainer nach oben. Was auch immer Ihre Bildlaufposition sein mag, sie bleibt gleich. Zumindest nach unten können Sie die Linien oben natürlich nicht sehen.
Sie sollten in der Lage sein, das CSS an Ihre Bedürfnisse anzupassen. Sie könnten sogar auf JS verzichten, wenn Sie Folgendes verwenden: Fokus oder etwas anderes CSS-Setup, seien Sie kreativ :)
quelle
Sie müssen hinzufügen
document.querySelector(".messages").scrollTop = 10000;
zutest
Funktion hinzufügen, wenn Sie einen Rand hinzufügenscrollTop
,scrolltop
und dann zum Ende der von Ihnen festgelegten Last gehen. Wenn Sie einen Rand hinzufügen oder einen Rand entfernenscrolltop
, wurde das Skript nicht so geändert, dass es Ihnen gefälltquelle
Es scheint ein Problem mit der Umschaltfunktion von js zu geben. Ich habe es in ein einfaches Verstecken geändert. Außerdem habe ich dem Eingabe-Tag eine Breite hinzugefügt. Sie müssen auch eine Position hinzufügen: absolut in der Send-Nachricht div und unten: 0, damit sie unten bleibt. Platzieren Sie dann position: relative auf dem Container, sodass die send message div im Container bleibt. Dies bedeutet, dass der Nachrichtencontainer die Nachrichten selbst nicht beeinflusst und sie nach oben drückt.
quelle
Ein reiner unvollkommener CSS-Ansatz, den ich entwickeln kann, ist der folgende:
Der oberste Abschnitt hat ein kleines Problem, wenn der Rand vorhanden ist. Der Trick hier besteht darin, einen negativen Rand zu verwenden und mit translate zu "scrollen" (nicht wirklich eine Schriftrolle, nur eine Illusion)
wrapper
.quelle
div
)?Es kann sehr einfach mit Ankernamen angesprochen werden. Schauen Sie sich die JS-Geige unter https://jsfiddle.net/gvbz93sx/ an.
HTML-Änderung
<a name="bottom"></a>
JS-Änderung
document.location.hash = "#bottom";
quelle