【问题标题】:Limit Scrolling to Content Area限制滚动到内容区域
【发布时间】:2021-12-19 14:35:41
【问题描述】:

问题:

我无法将滚动限制到典型 Vue 3 SPA 的内容区域(滚动条不应延伸到页眉和页脚区域)。 Header 和 Footer 块与 Bootstrap fixed-topfixed-bottom 类一起放置。在附加的图像中有点难以看到,但当前内容区域在页眉和页脚后面延伸。页眉和页脚是从 Bootstrap 组件库构建的。我可以使用填充修复内容可见性,但这并不能解决溢出(滚动条)问题。

采取的措施

我尝试了许多类似问题的解决方案,但这些解决方案通常适用于早期版本的 Vue 和 Bootstrap,并且似乎对我不起作用。我能够在 vanilla html 和 Bootstrap 中生成我想要的布局——似乎是 Vue 3 注入过程让我感到困惑。我尝试将布局应用到 index.html 和 App.vue 都没有成功(尝试 Bootstrap 类和 vanilla css)。 Bootstrap 依赖项似乎工作正常,所以我认为这不是问题(Bootstrap 5 不是 Bootstrap-Vue)。

预期结果:

限制滚动到内容区域,同时保持页眉和页脚导航栏固定在其位置(并且始终可见)。

环境

代码 sn-ps 用于提高可读性(不会在原地运行)。下面的代码已删除所有(或几乎所有)放置尝试,因为它们不起作用。

index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="../public/favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
    <!--    <script>window.scrollTo(0,1) // this is meant to hide the address bar in mobile Safari on page load.</script>-->
  </head>
  <body>
    <noscript>
      <strong>The <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>

    <div id="app"></div>
    <!-- built files are auto injected here -->
  </body>
</html>
App.vue

<template>
  <div id="wrapper" class="m-1">
    <div id="header_area">
      <Header/>
    </div>
    <div id="content_area">
      <span class="page-title">{{ title }}</span>
      <hr class="border-secondary">
      <span class="page-content">{{ content }}</span>
      <router-view @page-data="updatePageName($event)"/>
    </div>
    <div id="footer_area">
      <Footer/>
    </div>
  </div>
</template>

<script>
import Header from '@/components/Header.vue'
import Footer from '@/components/Footer.vue'

export default {
  data() {
    return {
    title: "home",
    content: ""
    }
  },
  components: {
    Header,
    Footer,
  },
  methods: {
    updatePageName: function(event) {
      this.title = event.title;
      this.content = event.content;
    }
  }
};
</script>

<style>
  @import'~bootstrap/dist/css/bootstrap.css';
  @import "./assets/main.css";
</style>
Header.vue(部分)

<template>
  <div>
    <nav class="Header navbar navbar-expand-sm navbar-dark bg-dark border-bottom border-4 fixed-top" aria-label="Header Bar">
      <div class="container-fluid">
        <router-link to="/"><span class="navbar-brand">brand</span>  </router-link>
        <button class="navbar-toggler btn-sm" type="button" data-bs-toggle="collapse" data-bs-target="#Navbar" aria-controls="Navbar" aria-expanded="false" aria-label="Toggle navigation">
          <span class="navbar-toggler-icon"></span>
        </button>

        <div class="collapse navbar-collapse" id="Navbar">
          <ul class="navbar-nav me-auto mb-2 mb-sm-0">
            <li class="nav-item dropdown">
              <router-link to=""><a class="nav-link dropdown-toggle" id="dropdown01" data-bs-toggle="dropdown" aria-expanded="false">pages</a></router-link>
              <ul class="dropdown-menu bg-dark" aria-labelledby="dropdown01" id="dave">
              
              [snip]
main.css

@charset "utf-8";

@font-face {
    font-family: 'Lato-Light';
    src: local('Lato-Light'), url('Lato-Light.ttf') format("truetype");
}

:root {
    --background: #191919;
    --dark: #000000;
    --grey1: #111111;
    --grey2: #222222;
    --grey3: #333333;
    --grey4: #444444;
    --grey5: #555555;
    --grey6: #666666;
    --grey7: #777777;
    --grey8: #888888;
    --grey9: #999999;
    --light: #FFFFFF;
}


html, body {
    background-color: var(--dark) !important;
    color: var(--light) !important;
}

a {
    color: var(--bs-secondary) !important;
    text-decoration: none;
}

body {
    font-family: Lato-Light, sans-serif;
    font-size: 0.9em;
}

button {
    padding: 1px;
}

input {
    border: solid 1px var(--grey9);
    border-radius: 5px;
    box-sizing: border-box;
    padding: 5px;
}

li {
    float: left;
    margin: 0 5px;
    padding: 0 2px;
    text-align: start;
}

ul {
    list-style-type: none;
    padding: 0;
}

.dropdown-item {
    border: solid 1px var(--bs-dark);
    color: var(--bs-secondary) !Important;
    /*font-size: 0.9rem;*/
    width: 94%;
}

.dropdown-item:hover {
    background-color: var(--bs-dark) !important;
    border: solid 1px var(--bs-secondary);
    border-radius: 5px;
    width: 94%;
}

.dropdown-menu {
    background-color: var(--bs-dark) !important;
    border: solid 1px var(--bs-dark) !important;
    color: var(--bs-secondary) !Important;
    /*font-size: 0.9rem !important;*/
}

.dropdown-submenu {
    position: relative;
}

.dropdown-submenu .dropdown-menu {
    border: solid 1px var(--bs-dark) !important;
    color: var(--bs-secondary) !Important;
    /*font-size: 0.9rem !important;*/
    left: 100%;
    top: 0;
}

.dropdown-toggle::after {
    display: none;
}

.navbar {
    border-bottom-color: var(--dark) !important;
    border-top-color: var(--dark) !important;
    margin-bottom: 0;
}

.navbar-brand {
    border: solid 1px var(--bs-dark);
    border-radius: 5px;
    color: var(--bs-secondary) !important;
    padding: 5px;
}

.navbar-brand:hover {
    border: solid 1px var(--bs-secondary);
    border-radius: 5px;
}

.nav-link {
    background-color: var(--bs-dark) !important;
    border: solid 1px var(--bs-dark);
    border-radius: 5px;
    color: var(--bs-secondary) !important;
}

.nav-link:hover {
    border: solid 1px var(--bs-secondary);
    border-radius: 5px;
}

.nav-link.dropdown-toggle {
    padding: 8px;
}

.navbar-nav li:hover > ul.dropdown-menu {
    border: solid 1px var(--grey5) !important;
    color: var(--bs-secondary) !Important;
    display: block;
}

.page-title {
    color: var(--grey5);
    font-size: 2rem !important;
    text-align: left !important;
}

.page-content {

}

.selected {
    border-color: lime !important;
}

#app {

}

#header_area {

}

#content_area {

}

#footer_area {

}


#Footer {
     font-size: 0.9em;
}


:focus {
    border-color: var(--dark);
    box-shadow: none;
    outline: none;
}

【问题讨论】:

  • 这听起来更像是一个纯 CSS 问题,应该与 Vue 无关,因为您可以完全控制内容,例如CSS 网格:css-tricks.com/snippets/css/complete-guide-grid
  • @Thomas 谢谢。我已经尝试过直接的 CSS 网格但没有成功,但我会再试一次。
  • @Thomas 花了我一段时间,但我能够让 CSS Grid 工作。谢谢你让我走上这条路。如果您选择写答案,我会接受。干杯!
  • 我是一个程序员,对 CSS 不太熟悉,所以我可能无法为它提供答案。
  • @Thomas - 明白了。我会继续接受我自己的答案。再次感谢您的帮助。干杯。

标签: vuex vue-router vuejs3 bootstrap-5


【解决方案1】:

这就是我能够让 CSS Grid 规范发挥作用的方式。 对于我的情况,在index.html 中为&lt;html&gt;&lt;body&gt; 添加样式很重要,但可能不是必需的。也可能不需要将!Important 分配给网格元素,但这样做是为了保险。

现在,由 Vue 路由器注入的任何内容都将出现在 content_area 中,并且该部分会滚动(根据需要)。

App.vue
<template>
  <div class="app m-1">

    <div id="header_area">
      <Header/>
    </div>

    <div id="content_area">
      <span class="page-title">{{ title }}</span>
      <hr class="border-secondary">
      <span class="page-content">{{ content }}</span>
      <router-view @page-data="updatePageName($event)"/>
    </div>

    <div id="footer_area">
      <Footer/>
    </div>

  </div>
</template>

<script>
import Header from '@/components/Header.vue'
import Footer from '@/components/Footer.vue'

export default {
  data() {
    return {
    title: "home",
    content: ""
    }
  },
  components: {
    Header,
    Footer,
  },
  methods: {
    updatePageName: function(event) {
      this.title = event.title;
      this.content = event.content;
    }
  }
};
</script>

<style>
  @import'~bootstrap/dist/css/bootstrap.css';
  @import "./assets/navbar.css";
  @import "./assets/main.css";
</style>
index.html
<!DOCTYPE html>
<html lang="en" style="margin: 0;">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="../public/favicon.ico">
    <title><%= htmlWebpackPlugin.options.title %></title>
  </head>
  <body style="margin: 0; overflow: hidden;">
    <noscript>
      <strong>The <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
    </noscript>

    <div id="app"></div>
    <!-- built files are auto-injected here -->
  </body>
</html>
main.css
.app {
    height: 100vh !important;
    display: grid !important;
    grid-gap: 5px !important;
    grid-template-columns: 1fr !important;
    grid-template-rows: 65px 1fr 40px !important;
    grid-template-areas: "header" "content" "footer" !important;
}

#header_area {
    grid-area: header !important;
}

#content_area {
    grid-area: content !important;
    overflow: auto !important;
}

#footer_area {
    grid-area: footer !important;
}

纯 HTML 示例

body {
  background-color: red;
  margin: 0;
}

.container {
  height: 100vh;
  display: grid;
  grid-gap: 5px;
  grid-template-columns: 1fr;
  grid-template-rows: 70px 1fr 40px;
  grid-template-areas: "header" "content" "footer";
}

.H {
  grid-area: header;
  background-color: blue;
  color: white;
}

.C {
  grid-area: content;
  background-color: darkgreen;
  color: white;
  padding: 15px 5px 10px 5px;
  overflow: auto;
}

.F {
  grid-area: footer;
  background-color: blue;
  color: white;
}
<!DOCTYPE html>

<html>

<head>
</head>

<body>
  <div class="container">
    <div class="H">header</div>
    <div class="C">
      content
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br> .
      <br>
    </div>
    <div class="F">footer</div>
  </div>
</body>

</html>

【讨论】:

    猜你喜欢
    • 2016-01-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多