侧边栏折叠一秒钟并在页面加载时展开

2023-12-22

我有一个侧边栏,单击按钮即可展开或折叠。现在我已经成功地将它的状态存储在localStorage除了有一个小问题之外,它工作正常。

当页面加载并且没有保存状态时localStorage, 侧边栏collapses一瞬间expands. Expand当没有存储状态时应该是默认状态localStorage。我不想这样collapse首先然后expand。我只想加载侧边栏的页面expanded.

我一直在尝试用我自己的代码解决这个问题。但它不起作用,然后我将我的代码与 SO 的帖子结合起来。它仍然不起作用。

完整代码:Codepen https://codepen.io/zakero/pen/dyMovBz

这是代码(请注意localStorage在 SO 中不起作用):

$('document').ready(function() {

    if (typeof window.isMinified === "undefined") {
      window.isMinified = false;
    }


    const body = $('#body');
    $("#sidebar-toggler").on("click", function () {
        
        if (window.isMinified === false) {

            // localStorage.setItem('menu-closed', !$(body).hasClass("sidebar-minified"));
            body.removeClass("sidebar-minified-out").addClass("sidebar-minified");
            window.isMinified = true;

        } else {

            // localStorage.setItem('menu-closed', !$(body).hasClass("sidebar-minified"));
            body.removeClass("sidebar-minified").addClass("sidebar-minified-out");
            window.isMinified = false;

        }
            
    });

    const state = // localStorage.getItem('menu-closed');

    if (state === null) {

        $(body).removeClass('sidebar-minified');

    } else {

        const closed = state === "true" ? true : false;

        if (!closed) {
            $(body).removeClass('sidebar-minified');
        }

    }
});
#body {
  background: #fff;
  transition: all 0.3s;
}

aside.left-sidebar{
  background-color: #2c0963;
  height: 100vh;
}

.sidebar-minified-out .left-sidebar {
  width: 180px;
  transition: width .3s ease-in; 
}
.sidebar-minified .left-sidebar {
  width: 75px;
  transition: width .3s ease-in; 
} 


.sidebar-toggle {
    font-weight: 300;
    font-size: 15px;
    cursor: pointer;
    height: 30px;
    position: absolute;
    left: 20%;
    top: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body id="body" class="sidebar-minified sidebar-minified-out">
  <aside class="left-sidebar"></aside>

  <button id="sidebar-toggler" class="sidebar-toggle">Collapse/Expand</button>
  
</body>

您可以通过告诉浏览器来最小化闪烁效果repaint只有一次,一击。但总会有一个适合您的初始尺寸sidebar:已在您的标记中定义的尺寸。

在我的示例中,我使用了两个Observers跟踪款式和尺寸的变化。请注意开头sidebar宽度。您可以将初始侧边栏宽度设置为等于 0,或者让它未分配,或者您可以将其样式设置为与展开的侧边栏相同的大小,但始终会进行初始重绘。

最后,我坚信您需要从body.

$(function() {
  /* avoid SO unsecure operation error */
  var storage = (function () {
    return {
      setItem: function(k,v){try{return localStorage.setItem(k,v)}catch(e){return !1}},
      getItem: function(k){try{return localStorage.getItem(k)}catch(e){return null}}
    }; 
  })();
  
  log("jQuery DOM Ready");
  
  $("#sidebar-toggler").on("click", function() {
    var isMinified = !$("body").hasClass("sidebar-minified-out");
    $("body")
      .toggleClass("sidebar-minified", !isMinified)
      .toggleClass("sidebar-minified-out", isMinified);   
    storage.setItem('menu-closed', +!isMinified);
  });
  
  var closed = +storage.getItem('menu-closed');
  log('Closed: ' + !!closed);
  $("body")
    .addClass(closed ? "sidebar-minified" : "sidebar-minified-out")
    .css({"visibility": "visible"});
});
body {
  background: #fff;
  transition: all 0.3s;
}
aside.left-sidebar{
  background-color: #2c0963;
  height: 100vh;
}
.sidebar-minified-out .left-sidebar {
  width: 180px;
  transition: width .3s ease-in; 
}
.sidebar-minified .left-sidebar {
  width: 75px;
  transition: width .3s ease-in; 
} 
.sidebar-toggle {
  font-weight: 300;
  font-size: 15px;
  cursor: pointer;
  height: 30px;
  position: absolute;
  left: 20%;
  top: 0;
}
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Sidebar State</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body style="visibility: hidden;">
  <aside class="left-sidebar"></aside>
  <button id="sidebar-toggler" class="sidebar-toggle">Collapse/Expand</button>
  <div id="log" style="position:absolute;top:0;right:0;padding:1em;"></div>
  <script>
    /* only debug functions inside this script block */
    function log(msg) {
      $("<div>").appendTo("#log").text(msg);
    }
    var mo = new MutationObserver(function (ml){
      for(var m of ml) {
        if (m.type == 'attributes') log('Body ' + m.attributeName + ' changed');
      }
    });
    mo.observe(document.getElementsByTagName('body')[0], {attributes: true});
    var ro = new ResizeObserver(function (rl){
      for(var r of rl) {
        var w = r.contentRect.width;
        if(w<=75 || w>=180) log('Sidebar width: ' + r.contentRect.width);
      }
    });
    ro.observe(document.getElementsByClassName("left-sidebar")[0]);
  </script>
</body>
</html>

EDIT:

如果您查看由观察员,你会注意到总是有重画,如上所述。

看完之后this https://stackoverflow.com/a/63033934/4845566您上一个问题的解决方案:黑暗模式在重新加载时会闪烁白色背景一毫秒 https://stackoverflow.com/questions/63033412/dark-mode-flickers-a-white-background-for-a-millisecond-on-reload我相信您可以以同样的方式实现您的侧边栏切换器。

而不是将 CSS 类应用到body,您可以将其应用到html。这里是完整代码:

HTML

<!DOCTYPE html>
<html>
<head>
  <script>
    /* Render blocking script */
    var c = +localStorage.getItem('menu-closed');
    document.documentElement.classList.add(c ? 'sidebar-minified' : 'sidebar-minified-out');
  </script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
</head>
<body>
  <aside class="left-sidebar"></aside>
  <button id="sidebar-toggler" class="sidebar-toggle">Collapse/Expand</button>
</body>
</html>

JS

$(function() {
  $("#sidebar-toggler").on("click", function (e) {
    var isMinified = !$("html").hasClass("sidebar-minified-out");
    $("html")
      .toggleClass("sidebar-minified", !isMinified)
      .toggleClass("sidebar-minified-out", isMinified);
    localStorage.setItem('menu-closed', +!isMinified);
  });
});

除了一个小更改之外,您的 CSS 将保持不变(我只是删除了#body id).

现在,如果你比较Observed更改后,您会注意到第二个解决方案,即使用阻塞 JS 脚本head,仅显示初始侧边栏大小,即:初始重绘消失了:

   1st solution                          2nd solution
==============================================================
    Sidebar width: 601                    Closed: false
    jQuery DOM Ready                      Sidebar width: 180
    Closed: false                         jQuery DOM Ready
    Body class changed
    Body style changed
    Sidebar width: 180

(学分:罗科·C·布尔扬 https://stackoverflow.com/users/383904/roko-c-buljan):

更多信息:


The debug functions in my first example are used just only to depict the sequence of the resize and restyle events inside the browser.

这是一些关于此的文档观察员:

  • 变异观察者 https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
  • 调整大小观察者 https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

侧边栏折叠一秒钟并在页面加载时展开 的相关文章

随机推荐