gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 17:26:05 29 4
gpt4 key购买 nike

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

当页面加载并且 localStorage 中没有保存任何状态时,侧边栏会折叠一瞬间然后展开。当 localStorage 中没有存储任何状态时,Expand 应该是默认状态。我不希望它先折叠,然后再展开。我只想加载侧边栏 expanded 的页面。

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

完整代码:Codepen

这是代码(请注意 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>

最佳答案

您可以通过告诉浏览器一次只重绘 一次来最小化闪烁效果。但是您的 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>

编辑:

如果您查看 Observers 记录的消息,您会注意到总是有重绘,如上所述。

看完this您上一个问题的解决方案: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)。

现在,如果您比较观察到的变化,您会注意到第二个解决方案,即在 head 中使用阻塞 JS 脚本,只显示初始侧边栏大小,即:初始重绘消失了:

   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

(致谢:Roko C. Buljan):

更多信息:


我的第一个示例中的调试函数仅用于描述浏览器内调整大小和重新设置样式事件的顺序。

这里有一些关于Observers的文档:

关于javascript - 侧边栏折叠一秒钟并在页面加载时展开,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63327866/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com