1

Well I have a very simple website, the body of the site should scroll such that the address bar is no longer visible. from this topic it seems that simply calling the follwing ought to do the trick:

window.scrollTo(0,1)

However in my react app this is not working at all, the application is:

import * as React from 'react';
import {Route, Router} from 'react-router';
class App extends React.Component<PropTy> {
    componentDidMount() {
        console.log('ok');
        window.scrollTo(0, 1);
    }
    render() {
        return (<div style={{height: '100vh', position: 'relative'}}>
            text
        </div>);
    }
}

export default App;

I can manually scroll down (on mobile). However it doesn't do this automatically - yet I do see the "ok" in the console.

The index.html and manifest.json have hardly changed from the default create-react-app:

<!DOCTYPE html>
<!--suppress HtmlUnknownTarget -->
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#7B0000">
    <meta name="Description" content="Spots platform, event calendar, enroll">
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <title>AllSports</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root" ></div>
  </body>
</html>

What causes the browser to just ignore scrollTo() - I've tried different offsets for scrolling but none of them seemed to work?

I've also tried modifying the index.html:

<!DOCTYPE html>
<!--suppress HtmlUnknownTarget -->
<html lang="en">
  <head>
    <meta charset="utf-8">
    <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#7B0000">
    <meta name="Description" content="Spots platform, event calendar, enroll">
    <!--
      manifest.json provides metadata used when your web app is added to the
      homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
    -->
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json">
    <title>AllSports</title>
  </head>
  <body>
    <noscript>
      You need to enable JavaScript to run this app.
    </noscript>
    <div id="root" style="height: 100vh; position: relative;"></div>
  </body>
</html>

But that doesn't seem to work either.

I now notice (thanks for the comment) that this is due to react router import. If I remove the import it "works'. - The application is however tightly coupled with react-router, so how would I "fix" this?

paul23
  • 8,799
  • 12
  • 66
  • 149
  • You don't happen to be using `react-router` in this app by any chance, do you? – Sébastien Renauld Jul 14 '19 at 02:03
  • @SébastienRenauld I am, but I don't see how that has any effect? (In the test I am not even "using" it, just importing it) – paul23 Jul 14 '19 at 02:14
  • there's some fun regarding similar things and it, particularly when implementing scroll-to-top-like functionality. – Sébastien Renauld Jul 14 '19 at 02:23
  • did you find a solution when using `react-router`? – John Jan 31 '21 at 17:07
  • @John I actually discovered the solution was to "do nothing". Whatever I did the address bar would always appear when an input menu was gaining focus. Even if I manually scroll down. As such the solutions with `window.scrollTo(0, 1)` didn't work. -- Because the search bar in our application always gains focus; – paul23 Jan 31 '21 at 20:18

2 Answers2

0

Problem with your code is,

componentDidMount() {
   console.log('ok');
   window.scrollTo(0, 1);
}

componentDidMount will execute only once when your component loads first time, and not for any successive render. So this code might get execute once.

The effect you are unable to see is because, window.scrollTo(0, 1) takes arguments in pixel, so it is possible that your page might scroll 1px vertically and you are unable to see it. Ref.

You can use scrollIntoView and ref to achieve this,

import React, {useRef, useEffect} from 'react'
import ReactDOM from 'react-dom'

function App() {
  const scrollInto = useRef(null)
  useEffect(() => {
    scrollInto.current.scrollIntoView()
  })
  return (
    <div>
      <h2>Header</h2>
      <div ref={scrollInto}>Scroll till here</div>
      <h2>
        Below dummy text is to get scroll on page so tht our code will work.
      </h2>
      <div>
        More data here
      </div>
    </div>
  )
}

Demo

ravibagul91
  • 20,072
  • 5
  • 36
  • 59
0

Here is a one-line-code solution well working. :)

just put this below inside your index.html !

<meta name="apple-mobile-web-app-capable" content="yes" />

or you can just put this inside your app.js code like this todo-list app example below ~

import React, { useState, useCallback, useRef } from 'react';

const App = () => {
  const [todos, setTodos] = useState([
    {
      id: 1,
      text: 'todo item one'
    },
    {
      id: 2,
      text: 'todo item two'
    },
    {
      id: 3,
      text: 'todo item three'
    }
  ]);


  const nextId = useRef(4);

  const onInsert = useCallback(
    text => {
      const todo = {
        id: nextId.current,
        text,
        checked: false
      };
      setTodos(todos.concat(todo));
      nextId.current += 1;
    },
    [todos],
  );

  return (
    <div>
      <meta name="apple-mobile-web-app-capable" content="yes" />
      <TodoTemplate>
        <TodoInsert onInsert={onInsert} />
        <TodoList todos={todos} />
      </TodoTemplate>
    </div>
  );
}

export default App;

Cheers :)

Initd
  • 11
  • 2
  • This meta tag does more than just hide the address bar. When opened as a PWA, the back button/gesture no longer exists (regardless of manifest). – Jonathan Rosa Jun 16 '20 at 19:07