0

I'm trying to have a permanent drawer (not below the top app bar), and a scrollable part of the website, with a standard top app bar at the top, like this demo.
It all works fine, until I start scrolling the page, and the top app bar does not move at all, unlike I expect it to do based on the demo.

(I'm doing all this without locally hosting any content, so it should work without any local files.)
Here's my code, simplified and in one html file:

<!DOCTYPE html>
<html lang="en">
<head>
    <title style="display: none">Page Title</title>
    <link rel="shortcut icon" href="http://triarc.hu/src/favicon.ico" type="image/x-icon">
    
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>

    <link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css">
    <script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700" rel="stylesheet">

    <style type="text/css">
        body {
            margin:0;
        }
        html, body {height: 100vh; overflow: hidden;}

        .drawer-frame-root {
            display: -ms-flexbox;
            display: flex;
            height: 100vh;
        }
        .drawer-app-content {
            -ms-flex: auto;
            flex: auto;
            overflow: auto;
        }
        .drawer-main-content {
            overflow: auto;
            height: 100%;
            padding: 0 18px;
        }
        .drawer-top-app-bar {
            position: absolute;
        }
        .drawer-frame-app-content {
            position: relative;
            width: 100%;
        }
    </style>
</head>
<body class="mdc-typography">
    <div id="root">
        <div class="drawer-frame-root">
            <aside class="mdc-drawer">
                <div class="mdc-drawer__content scrollbox">
                    <nav class="mdc-list">
                        <a class="mdc-list-item" href="#1">
                            <span class="mdc-list-item__ripple"></span>
                            <i class="material-icons mdc-list-item__graphic" aria-hidden="true">contact_page</i>
                            <span class="mdc-list-item__text">Contact</span>
                        </a>
                        <a class="mdc-list-item" href="#2">
                            <span class="mdc-list-item__ripple"></span>
                            <i class="material-icons mdc-list-item__graphic" aria-hidden="true">people</i>
                            <span class="mdc-list-item__text">Our Team</span>
                        </a>
                    </nav>
                </div>
            </aside>
            <div class="drawer-frame-app-content">
                <header class="mdc-top-app-bar drawer-top-app-bar">
                    <div class="mdc-top-app-bar__row">
                        <section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-start">
                            <span class="mdc-top-app-bar__title">Top app bar</span>
                        </section>
                        <section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-end" role="toolbar">
                            <button class="material-icons mdc-top-app-bar__action-item mdc-icon-button" aria-label="Search">search</button>
                        </section>
                    </div>
                </header>
                <div class="drawer-main-content">
                    <div class="mdc-top-app-bar--fixed-adjust">
                        This<br> is<br> a<br> long<br> text<br> that<br> will<br> take<br> up<br> multiple<br> lines<br> and<br> hopefully<br> let<br> you<br> scroll<br> the<br> page<br> without<br> having<br> to<br> resize<br> the<br> window.<br> If<br> it<br> isn't<br> long<br> enough<br> for<br> you,<br> just<br> make<br> your<br> window<br> smaller<br> or<br> open<br> devtools<br> and<br> turn<br> on<br> the<br> device<br> toolbar.
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
<script>
    const topAppBarElement = document.querySelector('.mdc-top-app-bar');
    topAppBar = new mdc.topAppBar.MDCTopAppBar(topAppBarElement);
</script>
</html>

What am I doing wrong, or what am I missing?

Something else that I figured out and might help: if I open chrome devtools on the demo, than delete and re-insert the mdc-top-app-bar or the drawer-main-content component, it starts working like mine.

vitrack
  • 65
  • 5

2 Answers2

1

By default TopAppBar scroll handler is attached to window scroll. In your case, you need to watch content div scroll. From MDC Web docs:

MDCTopAppBar.setScrollTarget(target: element) => void - Sets scroll target to different DOM node (default is window).

Add the following lines after topAppBar initialization:

const mainContentEl = document.querySelector('.drawer-main-content');
topAppBar.setScrollTarget(mainContentEl);
Konstantin Lyakh
  • 781
  • 6
  • 15
0

I managed to solve the problem by initialising the top app bar like this:

const topAppBarElement = document.querySelector('.mdc-top-app-bar');
setScrollTarget = function(e) {
    this.scrollTarget_.removeEventListener("scroll",this.handleTargetScroll_);
    this.scrollTarget_=e;
    this.handleTargetScroll_=this.foundation_.handleTargetScroll.bind(this.foundation_);
    this.scrollTarget_.addEventListener("scroll",this.handleTargetScroll_);
}
topAppBar = new mdc.topAppBar.MDCTopAppBar(topAppBarElement).setScrollTarget(document.querySelector('.drawer-main-content'));

This is probably not the best solution, but hey, it works. Here's the code snippet:

<!DOCTYPE html>
<html lang="en">
<head>
    <title style="display: none">Page Title</title>
    <link rel="shortcut icon" href="http://triarc.hu/src/favicon.ico" type="image/x-icon">
    
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>

    <link rel="stylesheet" href="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.css">
    <script src="https://unpkg.com/material-components-web@latest/dist/material-components-web.min.js"></script>
    <link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,600,700" rel="stylesheet">

    <style type="text/css">
        body {
            margin:0;
        }
        html, body {height: 100vh; overflow: hidden;}

        .drawer-frame-root {
            display: -ms-flexbox;
            display: flex;
            height: 100vh;
        }
        .drawer-app-content {
            -ms-flex: auto;
            flex: auto;
            overflow: auto;
        }
        .drawer-main-content {
            overflow: auto;
            height: 100%;
            padding: 0 18px;
        }
        .drawer-top-app-bar {
            position: absolute;
        }
        .drawer-frame-app-content {
            position: relative;
            width: 100%;
        }
    </style>
</head>
<body class="mdc-typography">
    <div id="root">
        <div class="drawer-frame-root">
            <aside class="mdc-drawer">
                <div class="mdc-drawer__content scrollbox">
                    <nav class="mdc-list">
                        <a class="mdc-list-item" href="#1">
                            <span class="mdc-list-item__ripple"></span>
                            <i class="material-icons mdc-list-item__graphic" aria-hidden="true">contact_page</i>
                            <span class="mdc-list-item__text">Contact</span>
                        </a>
                        <a class="mdc-list-item" href="#2">
                            <span class="mdc-list-item__ripple"></span>
                            <i class="material-icons mdc-list-item__graphic" aria-hidden="true">people</i>
                            <span class="mdc-list-item__text">Our Team</span>
                        </a>
                    </nav>
                </div>
            </aside>
            <div class="drawer-frame-app-content">
                <header class="mdc-top-app-bar drawer-top-app-bar">
                    <div class="mdc-top-app-bar__row">
                        <section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-start">
                            <span class="mdc-top-app-bar__title">Top app bar</span>
                        </section>
                        <section class="mdc-top-app-bar__section mdc-top-app-bar__section--align-end" role="toolbar">
                            <button class="material-icons mdc-top-app-bar__action-item mdc-icon-button" aria-label="Search">search</button>
                        </section>
                    </div>
                </header>
                <div class="drawer-main-content">
                    <div class="mdc-top-app-bar--fixed-adjust">
                        This<br> is<br> a<br> long<br> text<br> that<br> will<br> take<br> up<br> multiple<br> lines<br> and<br> hopefully<br> let<br> you<br> scroll<br> the<br> page<br> without<br> having<br> to<br> resize<br> the<br> window.<br> If<br> it<br> isn't<br> long<br> enough<br> for<br> you,<br> just<br> make<br> your<br> window<br> smaller<br> or<br> open<br> devtools<br> and<br> turn<br> on<br> the<br> device<br> toolbar.
                    </div>
                </div>
            </div>
        </div>
    </div>
</body>
<script>
    const topAppBarElement = document.querySelector('.mdc-top-app-bar');
    setScrollTarget = function(e) {
        this.scrollTarget_.removeEventListener("scroll",this.handleTargetScroll_);
        this.scrollTarget_=e;
        this.handleTargetScroll_=this.foundation_.handleTargetScroll.bind(this.foundation_);
        this.scrollTarget_.addEventListener("scroll",this.handleTargetScroll_);
    }
    topAppBar = new mdc.topAppBar.MDCTopAppBar(topAppBarElement).setScrollTarget(document.querySelector('.drawer-main-content'));
</script>
</html>
vitrack
  • 65
  • 5