【问题标题】:javascript sidebar stay open on page changejavascript 侧边栏在页面更改时保持打开状态
【发布时间】:2016-10-11 14:05:12
【问题描述】:

我是 JS 方面的新手,主要使用 bootstrap 就绪的解决方案,但现在我想为我的方面实现一个侧边栏(过滤)。

所以点击一个过滤器,内容会根据它和页面 URL 发生变化,所以侧边栏会关闭。

我想做的是,侧边栏保持打开状态,直到用户点击 X..

我为此使用了 W3School 侧边栏教程,所以这是我的代码:

<div id="mySidenav" class="sidenav">
  <a href="javascript:void(0)" class="closebtn" onclick="closeNav()">&times;</a>
  <a href="#">About</a>
  <a href="#">Services</a>
  <a href="#">Clients</a>
  <a href="#">Contact</a>
</div>

<!-- Use any element to open the sidenav -->
<span onclick="openNav()">open</span>

JavaScript:

/* Set the width of the side navigation to 250px and the left margin of the page content to 250px */
function openNav() {
    document.getElementById("mySidenav").style.width = "250px";
    document.getElementById("main").style.marginLeft = "250px";
}

/* Set the width of the side navigation to 0 and the left margin of the page content to 0 */
function closeNav() {
    document.getElementById("mySidenav").style.width = "0";
    document.getElementById("main").style.marginLeft = "0";
}

CSS

/* The side navigation menu */
.sidenav {

    height: 100%; /* 100% Full-height */
    width: 0; /* 0 width - change this with JavaScript */
    position: fixed; /* Stay in place */
    z-index: 1; /* Stay on top */
    top: 0;
    left: 0;
    background-color: #111; /* Black*/
    overflow-x: hidden; /* Disable horizontal scroll */
    padding-top: 60px; /* Place content 60px from the top */
    transition: 0.5s; /* 0.5 second transition effect to slide in the sidenav */
}

/* The navigation menu links */
.sidenav a {
   font-size: 20px;
   padding:5px 10px 5px 10px;
    text-decoration: none !important;    
    color: #818181;
    background: transparent;
    display: block;
    transition: 0.3s
}

/* When you mouse over the navigation links, change their color */
.sidenav a:hover, .offcanvas a:focus{
    color: #f1f1f1;
}

/* Position and style the close button (top right corner) */
.sidenav .closebtn {
    position: absolute;
    top: 0;
    right: 25px;
    font-size: 36px;
    margin-left: 50px;
}

.sidenav .removebtn {
    color: #e9e9e9;
    position: absolute;
    top: 0;
    left: 25px;
    font-size: 20px;
    margin-right: 50px;
}

/* Style page content - use this if you want to push the page content to the right when you open the side navigation */
#main {
    transition: margin-left .5s;
    padding: 20px;
}

/* On smaller screens, where height is less than 450px, change the style of the sidenav (less padding and a smaller font size) */
@media screen and (max-height: 450px) {
    .sidenav {padding-top: 15px;}
    .sidenav a {font-size: 18px;}
}

我看到了一些解决方案,包括 Cookies,但作为 JS 方面的菜鸟,我想要一个我能理解的答案。

谢谢!

【问题讨论】:

标签: javascript html css


【解决方案1】:

因此,如果我理解正确,您希望在页面更改时保持栏打开。

当页面重新加载到另一个页面时,浏览器从服务器获取一个新的html(即使它是相同的),并且洞页面重置,因此侧栏状态重置。

您可以将侧边栏的状态保存在某处,以便在页面再次加载时检索它。 Javascript 可以访问 2 个存储,Cookie 和 LocalStorage。

Cookies 与服务器共享(浏览器在每次请求时将所有 cookie 发送到服务器) 而localStorage只能被javascript访问。

服务器通常不关心侧边栏是打开还是关闭,因此要使用的“正确”存储是 localStorage。 (w3schools 中的LocalStorage http://www.w3schools.com/html/html5_webstorage.asp

现在解决你的问题,

你需要保存侧边栏状态,所以你在关闭或打开侧边栏时更新状态:

function openNav() {
    ...
    // If localStorage is supported by the browser
    if (typeof(Storage) !== "undefined") {
        // Save the state of the sidebar as "open"
        localStorage.setItem("sidebar", "opened");
    }
    ...
}

function closeNav() {
    ...
    // If localStorage is supported by the browser
    if (typeof(Storage) !== "undefined") {
        // Save the state of the sidebar as "open"
        localStorage.setItem("sidebar", "closed");
    }
    ...
}

现在我们已经保存了状态,我们需要在每次浏览器加载页面时检查它。 我们需要快速完成,所以我们不想等待任何像 onload 事件这样的事件。 我们只需要在页面上加载侧边栏元素,而不是整个页面,所以我们可以在侧边栏元素正下方输入我们的代码。

<!-- The sidebar element -->
<div id="mySidenav" class="sidenav">...</div>
<!-- Right after the browser renders the sidebar -->
<script type="text/javascript">
    // If localStorage is supported by the browser
    if (typeof(Storage) !== "undefined") {
        // If we need to open the bar
        if(localStorage.getItem("sidebar") == "opened"){
            // Open the bar
            document.getElementById("mySidenav").style.width = "250px";
            document.getElementById("main").style.marginLeft = "250px";
        }
    }
</script>

这有两个问题,

  1. 必须支持LocalStorage。 (Google Chrome 4.0+、Internet Explorer 8.0+、Firefox 3.5+、Safari 4.0+、Opera 11.5+)
  2. 由于transition: .5s; css 规则,它会重播动画。

第二个问题可以通过在一个类上添加transition: .5s; 并用javascript临时删除它直到你打开侧边栏来解决。

<!-- The sidebar element -->
<div id="mySidenav" class="sidenav">...</div>
<!-- Right after the browser renders the sidebar -->
<script type="text/javascript">
    // If localStorage is supported by the browser
    if (typeof(Storage) !== "undefined") {
        // If we need to open the bar
        if(localStorage.getItem("sidebar") == "opened"){
            // Remove class with transition from the 'sidebar' and the 'main'
            ...
            // Open the bar
            document.getElementById("mySidenav").style.width = "250px";
            document.getElementById("main").style.marginLeft = "250px";
            // Add the transition class again
            ...
        }
    }
</script>

使用 Cookies

Javascript 访问 cookie 的方式与访问本地存储的方式不同。

你可以把cookie想象成一个可以从变量中访问的大字符串 在 document.cookie 上(所有文档 cookie 都在这里)

你可以在控制台看到这个变量

> document.cookie
"a_cookie_name=cookie_value; an_other_cookie_name=and_his_value; ..."

要保存 cookie,您所要做的就是

// Add/Update a cookie by name
document.cookie = name + "=" + value + ";"

这不会清除旧的 cookie,它只会添加一个新的 cookie,或者如果它存在,它会更新它。

但是获取它们的值有点困难......你必须在一个变量中获取字符串,将字符串拆分为“;”,这样你就有一个字符串数组,其中数组的每个项目都是一个 cookie ,然后在数组中搜索你的cookie……太麻烦了。

但我们不必重新发明轮子……所以我们可以使用w3schools' code

function setCookie(cname, cvalue, exdays) {
    var d = new Date();
    d.setTime(d.getTime() + (exdays*24*60*60*1000));
    var expires = "expires="+d.toUTCString();
    document.cookie = cname + "=" + cvalue + ";" + expires + ";path=/";
}

function getCookie(cname) {
    var name = cname + "=";
    var ca = document.cookie.split(';');
    for(var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') {
            c = c.substring(1);
        }
        if (c.indexOf(name) == 0) {
            return c.substring(name.length, c.length);
        }
    }
    return "";
}

现在使用 localStorage 我们使用上面的函数

localStorage.getItem("sidebar") 等价于 getCookie("sidebar")

localStorage.setItem("sidebar","&lt;value&gt;") 等价于 setCookie("sidebar", "&lt;value&gt;", 30)

(请注意,由于 cookie 过期,我们将其设置为在 30 天后过期,因此要删除 cookie,请将过期日期设置为之前的时间 -1

最好在w3schoolslocalStorage 上查看有关cookie 的更多信息。

【讨论】:

  • 直截了当&很好的解释!我删除了过渡,现在它更好了。你也可以包括cookies解决方案吗?如果这不是一件非常耗时的事情:)(为了后代和进一步的解释)euxaristw thano!
  • 我加了cookie解释,但是cookie里面的东西比较深。
  • 使用不同的网址是否有区别:http:// vs. file://。我处理file:// URL 并将侧边栏的状态存储在localStorage 中。但是当我刷新或加载新页面(使用不同的参数)时,该变量在 localStorage 上不再可用 - 它总是localStorage.getItem('stateSidebar') --&gt; null... 请参阅:github.com/jerik/mdCanvas/blob/list-of-canvas/mdCanvas.html
  • 正常情况下是没有区别的,但我想这取决于浏览器的实现。在最新的 Chrome 和最新的 Firefox 上,它按预期工作。使用 Application 选项卡上的 devtools (F12) 调试您的应用程序,您可以在其中看到所有 localStorage 项。
  • @jerik 这就是为什么我建议你使用 devtools 的特殊选项卡,你可以看到所有的 localStorage。在 Firefox 中,此选项卡是 devtools 上的“存储”选项卡(您可能需要从 devtools 设置中激活它)。
【解决方案2】:

给你一个非常简单的例子。您可以根据自己的需要设计所有样式。如果您有任何问题,请告诉我。

$('.btn').click(function() {
  $('.sidenav').toggleClass('comeBack');
});
* {
  margin: 0;
  padding: 0;
  border: 0;
}
.sidenav {
  height: 100%;
  width: 200px;
  z-index: 1;
  background-color: #ccc;
  overflow-x: hidden;
  transition: 0.5s;
  transform: translateX(-300px);
}
.sidenav a {
  font-size: 20px;
  padding: 5px 10px 5px 10px;
  text-decoration: none;
  color: #818181;
  background: transparent;
  display: block;
  transition: 0.3s
}
.sidenav a:hover,
.offcanvas a:focus {
  color: #f1f1f1;
}
.btn {
  cursor: pointer;
  outline: none;
  height: 30px;
  width: 100px;
  border-radius: 10px;
}
.btn:hover {
 color: white;
}
.comeBack {
  transform: translateX(0);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button class='btn'>
  Toggle menu
</button>

<div id="mySidenav" class="sidenav">
  <a href="#">About</a>
  <a href="#">Services</a>
  <a href="#">Clients</a>
  <a href="#">Contact</a>
</div>

【讨论】:

  • 这将如何在页面之间持续存在?除非我遗漏了什么,否则不会。
  • 这并不能解决持续存在的问题.. 非常感谢你 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多