Ich habe ein Problem, von dem ich keine Ahnung habe, wie ich es lösen soll. In meiner Reaktionskomponente zeige ich unten eine lange Liste von Daten und wenige Links an. Nachdem ich auf einen dieser Links geklickt habe, fülle ich die Liste mit einer neuen Sammlung der Links aus und muss nach oben scrollen.
Das Problem ist - wie nach oben zu bewegen , nachdem die neue Kollektion gemacht wird?
'use strict';
// url of this component is #/:checklistId/:sectionId
var React = require('react'),
Router = require('react-router'),
sectionStore = require('./../stores/checklist-section-store');
function updateStateFromProps() {
var self = this;
sectionStore.getChecklistSectionContent({
checklistId: this.getParams().checklistId,
sectionId: this.getParams().sectionId
}).then(function (section) {
self.setState({
section,
componentReady: true
});
});
this.setState({componentReady: false});
}
var Checklist = React.createClass({
mixins: [Router.State],
componentWillMount: function () {
updateStateFromProps.call(this);
},
componentWillReceiveProps(){
updateStateFromProps.call(this);
},
render: function () {
if (this.state.componentReady) {
return(
<section className='checklist-section'>
<header className='section-header'>{ this.state.section.name } </header>
<Steps steps={ this.state.section.steps }/>
<a href=`#/${this.getParams().checklistId}/${this.state.section.nextSection.Id}`>
Next Section
</a>
</section>
);
} else {...}
}
});
module.exports = Checklist;
React.useEffect(() => { window.scrollTo(0, 0); }, []);
Beachten Sie, dass Sie useEffect auch direkt importieren können:import { useEffect } from 'react'
Da die ursprüngliche Lösung für eine sehr frühe Version von reag bereitgestellt wurde , ist hier ein Update:
constructor(props) { super(props) this.myRef = React.createRef() // Create a ref object } componentDidMount() { this.myRef.current.scrollTo(0, 0); } render() { return <div ref={this.myRef}></div> } // attach the ref property to a dom element
quelle
ReactDOM.findDOMNode(this).scrollTop = 0
this is undefined in arrow functions
ist falsch. Das Schlüsselwort this ist an denselben Kontext gebunden wie die umschließende Funktion developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…Sie könnten so etwas gebrauchen. ReactDom ist für react.14. Reagiere einfach anders.
componentDidUpdate = () => { ReactDom.findDOMNode(this).scrollIntoView(); }
Update 5/11/2019 für React 16+
constructor(props) { super(props) this.childDiv = React.createRef() } componentDidMount = () => this.handleScroll() componentDidUpdate = () => this.handleScroll() handleScroll = () => { const { index, selected } = this.props if (index === selected) { setTimeout(() => { this.childDiv.current.scrollIntoView({ behavior: 'smooth' }) }, 500) } }
quelle
componentDidMount
ist dies eine weitere Alternative.Beim React Routing gibt es das Problem, dass Sie nicht automatisch zum oberen Rand der Seite gelangen, wenn wir zur neuen Route umleiten.
Sogar ich hatte das gleiche Problem.
Ich habe gerade die einzelne Zeile zu meiner Komponente hinzugefügt und es hat wie Butter funktioniert.
componentDidMount() { window.scrollTo(0, 0); }
Siehe: Reaktionstraining
quelle
Dies könnte und sollte wahrscheinlich mit refs gehandhabt werden :
Beispielcode:
class MyComponent extends React.Component { componentDidMount() { this._div.scrollTop = 0 } render() { return <div ref={(ref) => this._div = ref} /> } }
quelle
<div ref={(ref) => this._div = ref} />
in die allererste<div>
meiner Render-Anweisung eingefügt. Der Rest meines Renderings bleibt genau gleich.<div ref="main">
und dannthis.refs.main.scrollTop=0
Für diejenigen, die Hooks verwenden, funktioniert der folgende Code.
React.useEffect(() => { window.scrollTo(0, 0); }, []);
Beachten Sie, dass Sie useEffect auch direkt importieren können:
import { useEffect } from 'react'
quelle
[]
zweite Parameter bedeutet, dass er nur beim ersten Rendern auftritt. Haben Sie es ohne versucht?Sie können dies im Router folgendermaßen tun:
ReactDOM.render(( <Router onUpdate={() => window.scrollTo(0, 0)} history={browserHistory}> <Route path='/' component={App}> <IndexRoute component={Home}></IndexRoute> <Route path="/about" component={About}/> <Route path="/work"> <IndexRoute component={Work}></IndexRoute> <Route path=":id" component={ProjectFull}></Route> </Route> <Route path="/blog" component={Blog}/> </Route> </Router> ), document.getElementById('root'));
Das
onUpdate={() => window.scrollTo(0, 0)}
setzt die Schriftrolle nach oben. Weitere Informationen finden Sie unter: Codepen-Linkquelle
/somePage/:imgId
, wird nach oben gescrollt :(. Jede Möglichkeit, um zu "steuern", ob ausgelöst werden soll oder nicht das onUpdate Ereignis auf bestimmten Strecken / params?onUpdate
es in HashRouters Requisiten nicht vorhanden ist ... Wenn jemand auf dasselbe Problem stößt: Ich habe schließlich die weiter unten beschriebene ScrollToTop-Lösung (und in den React-Router-Dokumenten) verwendet, die für mich perfekt funktioniert hat.Hier ist ein weiterer Ansatz, mit dem Sie auswählen können, auf welche gemounteten Komponenten die Bildlaufposition des Fensters zurückgesetzt werden soll, ohne dass ComponentDidUpdate / ComponentDidMount massenweise dupliziert wird.
Im folgenden Beispiel wird die Blog-Komponente mit ScrollIntoView () umhüllt. Wenn sich die Route beim Mounten der Blog-Komponente ändert, aktualisiert das ComponentDidUpdate des HOC die Bildlaufposition des Fensters.
Sie können es genauso einfach über die gesamte App wickeln, sodass bei jeder Routenänderung ein Zurücksetzen des Fensters ausgelöst wird.
ScrollIntoView.js
import React, { Component } from 'react'; import { withRouter } from 'react-router'; export default WrappedComponent => { class ResetWindowScroll extends Component { componentDidUpdate = (prevProps) => { if(this.props.location !== prevProps.location) window.scrollTo(0,0); } render = () => <WrappedComponent {...this.props} /> } return withRouter(ResetWindowScroll); }
Routes.js
import React from 'react'; import { Route, IndexRoute } from 'react-router'; import App from '../components/App'; import About from '../components/pages/About'; import Blog from '../components/pages/Blog' import Index from '../components/Landing'; import NotFound from '../components/navigation/NotFound'; import ScrollIntoView from '../components/navigation/ScrollIntoView'; export default ( <Route path="/" component={App}> <IndexRoute component={Index} /> <Route path="/about" component={About} /> <Route path="/blog" component={ScrollIntoView(Blog)} /> <Route path="*" component={NotFound} /> </Route> );
Das obige Beispiel funktioniert hervorragend, aber wenn Sie zu migriert haben
react-router-dom
, können Sie das obige vereinfachen, indem Sie ein erstellenHOC
, das die Komponente umschließt.Auch hier können Sie es genauso einfach über Ihre Routen umbrechen (ändern Sie einfach die
componentDidMount
Methode in den oben beschriebenencomponentDidUpdate
Methodenbeispielcode und umbrechen Sie sieScrollIntoView
mitwithRouter
).container / ScrollIntoView.js
import { PureComponent, Fragment } from "react"; class ScrollIntoView extends PureComponent { componentDidMount = () => window.scrollTo(0, 0); render = () => this.props.children } export default ScrollIntoView;
Komponenten / Home.js.
import React from "react"; import ScrollIntoView from "../containers/ScrollIntoView"; export default () => ( <ScrollIntoView> <div className="container"> <p> Sample Text </p> </div> </ScrollIntoView> );
quelle
Dies ist das einzige, was für mich funktioniert hat (mit einer ES6-Klassenkomponente):
componentDidMount() { ReactDOM.findDOMNode(this).scrollIntoView(); }
quelle
Ich verwende die ScrollToTop-Komponente des React-Routers, deren Code in den React-Router-Dokumenten beschrieben ist
https://reacttraining.com/react-router/web/guides/scroll-restoration/scroll-to-top
Ich ändere Code in einer einzelnen Routendatei und danach muss kein Code mehr in jeder Komponente geändert werden.
Beispielcode -
Schritt 1 - Erstellen Sie die ScrollToTop.js-Komponente
import React, { Component } from 'react'; import { withRouter } from 'react-router'; class ScrollToTop extends Component { componentDidUpdate(prevProps) { if (this.props.location !== prevProps.location) { window.scrollTo(0, 0) } } render() { return this.props.children } } export default withRouter(ScrollToTop)
Schritt 2 - Fügen Sie in der Datei App.js nachher die ScrollToTop-Komponente hinzu
<Router
const App = () => ( <Router> <ScrollToTop> <App/> </ScrollToTop> </Router> )
quelle
Hakenlösung :
import { useEffect } from "react"; import { withRouter } from "react-router-dom"; const ScrollToTop = ({ children, location: { pathname } }) => { useEffect(() => { window.scrollTo({ top: 0, left: 0, behavior: "smooth" }); }, [pathname]); return children || null; }; export default withRouter(ScrollToTop);
<Router> <ScrollToTop> <App /> </ScrollToTop> </Router>
quelle
Verwenden von Hooks in funktionalen Komponenten, vorausgesetzt, die Komponenten werden aktualisiert, wenn die Ergebnis-Requisiten aktualisiert werden
import React, { useEffect } from 'react'; export const scrollTop = ({result}) => { useEffect(() => { window.scrollTo(0, 0); }, [result]) }
quelle
use
All das hat bei mir nicht funktioniert - ich weiß nicht warum, aber:
componentDidMount(){ document.getElementById('HEADER').scrollIntoView(); }
funktioniert, wobei HEADER die ID meines Header-Elements ist
quelle
Wenn alles einfach sein will, ist hier eine Lösung, die für alle funktioniert
Fügen Sie diese Mini-Funktion hinzu
scrollTop() { window.scrollTo({ top: 0, behavior: "smooth" }); }
Rufen Sie die folgende Funktion in der Fußzeile der Seite auf
<a className="scroll-to-top rounded" style={{display: "inline"}} onClick={this.scrollTop}>TOP</a>
Wenn Sie schöne Stile hinzufügen möchten, ist hier die CSS
.scroll-to-top { position: fixed; right: 1rem; bottom: 1rem; display: none; width: 2.75rem; height: 2.75rem; text-align: center; color: #fff; background: rgba(90, 92, 105, 0.5); line-height: 46px; }
quelle
Ich verwende React Hooks und wollte etwas wiederverwendbares, aber auch etwas, das ich jederzeit aufrufen kann (und nicht nur nach dem Rendern).
// utils.js export const useScrollToTop = (initialScrollState = false) => { const [scrollToTop, setScrollToTop] = useState(initialScrollState); useEffect(() => { if (scrollToTop) { setScrollToTop(false); try { window.scroll({ top: 0, left: 0, behavior: 'smooth', }); } catch (error) { window.scrollTo(0, 0); } } }, [scrollToTop, setScrollToTop]); return setScrollToTop; };
Um den Haken zu benutzen, können Sie Folgendes tun:
import { useScrollToTop } from 'utils'; const MyPage = (props) => { // initialise useScrollToTop with true in order to scroll on page load const setScrollToTop = useScrollToTop(true); ... return <div onClick={() => setScrollToTop(true)}>click me to scroll to top</div> }
quelle
Wenn Sie dies für Handys tun , zumindest mit Chrom, sehen Sie unten einen weißen Balken.
Dies geschieht, wenn die URL-Leiste verschwindet. Lösung:
Google Developer Docs
quelle
Keine der oben genannten Antworten funktioniert derzeit für mich. Es stellt sich heraus, dass dies
.scrollTo
nicht so weit kompatibel ist wie.scrollIntoView
.In unseren App.js haben
componentWillMount()
wir hinzugefügtthis.props.history.listen((location, action) => { setTimeout(() => { document.getElementById('root').scrollIntoView({ behavior: "smooth" }) }, 777) })
Dies ist die einzige Lösung, die universell für uns funktioniert. root ist die ID unserer App. Das "reibungslose" Verhalten funktioniert nicht bei jedem Browser / Gerät. Das 777-Timeout ist etwas konservativ, aber wir laden auf jeder Seite viele Daten, sodass dies durch Tests erforderlich war. Ein kürzerer 237 funktioniert möglicherweise für die meisten Anwendungen.
quelle
Ich bin auf dieses Problem gestoßen, als ich mit Gatsby eine Site erstellt habe, deren Link auf Reach Router basiert. Es scheint seltsam, dass dies eine Änderung ist, die vorgenommen werden muss und nicht das Standardverhalten.
Wie auch immer, ich habe viele der oben genannten Lösungen ausprobiert und die einzige, die tatsächlich für mich funktioniert hat, war:
document.getElementById("WhateverIdYouWantToScrollTo").scrollIntoView()
Ich habe dies in einen useEffect eingefügt, aber Sie können es genauso einfach in componentDidMount einfügen oder auf eine andere Weise auslösen, die Sie möchten.
Ich bin mir nicht sicher, warum window.scrollTo (0, 0) für mich (und andere) nicht funktioniert.
quelle
Die Seite, die nach dem Klicken angezeigt wird, schreiben Sie einfach hinein.
componentDidMount() { window.scrollTo(0, 0); }
quelle
Sie können verwenden, das funktioniert bei mir.
import React, { useEffect } from 'react'; useEffect(() => { const body = document.querySelector('#root'); body.scrollIntoView({ behavior: 'smooth' }, 500) }, []);
quelle
Ich habe alles versucht, aber das ist das einzige, was funktioniert hat.
useLayoutEffect(() => { document.getElementById("someID").scrollTo(0, 0); });
quelle
Das habe ich getan:
useEffect(() => ref.current.scrollTo(0, 0)); const ref = useRef() return( <div ref={ref}> ... </div> )
quelle
Dieser Code führt zu einem reibungslosen Verhalten beim Scrollen :
<div onClick={() => { ReactDOM.findDOMNode(this.headerRef) .scrollIntoView({behavior: "smooth"}); }} className='go-up-button' > </div>
Sie können andere Parameter in scrollIntoView () übergeben. Folgende Syntax kann verwendet werden:
element.scrollIntoView(); element.scrollIntoView(alignToTop); // Boolean parameter element.scrollIntoView(scrollIntoViewOptions); // Object parameter
alignToTop Optional Ist ein boolescher Wert:
If true, the top of the element will be aligned to the top of the visible area of the scrollable ancestor. Corresponds to scrollIntoViewOptions: {block: "start", inline: "nearest"}. This is the default value. If false, the bottom of the element will be aligned to the bottom of the visible area of the scrollable ancestor. Corresponds to scrollIntoViewOptions: {block: "end", inline: "nearest"}.
scrollIntoViewOptions Optional Ist ein Objekt mit den folgenden Eigenschaften:
*behavior* Optional Defines the transition animation. One of "auto", "instant", or "smooth". Defaults to "auto". *block* Optional One of "start", "center", "end", or "nearest". Defaults to "center". *inline* Optional One of "start", "center", "end", or "nearest". Defaults to "nearest".
Weitere Details finden Sie hier: MDN-Dokumente
quelle
Keine der oben genannten Antworten funktioniert derzeit für mich. Es stellt sich heraus, dass dies
.scrollTo
nicht so weit kompatibel ist wie.scrollIntoView
.In unseren App.js haben
componentWillMount()
wir hinzugefügtthis.props.history.listen((location, action) => { setTimeout(() => { document.getElementById('root').scrollIntoView({ behavior: "smooth" }) }, 777) })
Dies ist die einzige Lösung, die universell für uns funktioniert.
root
ist die ID unserer App. Das "reibungslose" Verhalten funktioniert nicht bei jedem Browser / Gerät. Das 777-Timeout ist etwas konservativ, aber wir laden auf jeder Seite viele Daten, sodass dies durch Tests erforderlich war. Ein kürzerer 237 funktioniert möglicherweise für die meisten Anwendungen.quelle
Wenn ich davon ausgehe, dass Sie ein Kapitel wie beispielsweise ein Buch pro Seite rendern, müssen Sie dies nur Ihrem Code hinzufügen. Das hat bei mir wie Magie funktioniert.
componentDidUpdate(prevProps) { if (prevProps.currentChapter !== this.props.currentChapter) { window.scrollTo(0, 0); } }
Damit müssen Sie keine Referenz für die gerenderte Komponente erstellen.
quelle
Für Funktionskomponenten;
import React, {useRef} from 'react'; function ScrollingExample (props) { // create our ref const refToTop = useRef(); return ( <h1 ref={refToTop}> I wanna be seen </h1> // then add enough contents to show scroll on page <a onClick={()=>{ setTimeout(() => { refToTop.current.scrollIntoView({ behavior: 'smooth' })}, 500) }}> Take me to the element <a> ); }
quelle
Ich habe einen Ereignis-Listener auf der Seite index.html hinzugefügt, da hiermit alle Seiten geladen und neu geladen werden. Unten ist das Snippet.
// Event listener addEventListener("load", function () { setTimeout(hideURLbar, 0); }, false); function hideURLbar() { window.scrollTo(0, 1); }
quelle
In allen Lösungen wird über das Hinzufügen der Schriftrolle auf
componentDidMount
odercomponentDidUpdate
mit dem DOM gesprochen.Ich habe das alles gemacht und nicht gearbeitet.
Also, ich habe einen anderen Weg gefunden, der für mich gut funktioniert.
Ich habe auch etwas über ScrollRestoration gefunden , bin aber jetzt faul. Und vorerst werde ich es auf die "DidUpdate" Weise behalten.
quelle
So etwas hat bei mir an einer Komponente funktioniert:
<div ref="scroller" style={{height: 500, overflowX: "hidden", overflowY: "auto"}}> //Content Here </div>
Dann in welcher Funktion auch immer mit Updates zu tun hat:
this.refs.scroller.scrollTop=0
quelle
Nichts hat bei mir funktioniert, aber:
componentDidMount(){ $( document ).ready(function() { window.scrollTo(0,0); }); }
quelle