引导手风琴.保留多个面板的页面加载状态

Bootstrap Accordion. Retain state on pageload for multiple panels

本文关键字:加载 状态 手风琴 保留      更新时间:2023-09-26

我在表单页面上使用引导手风琴。用户可以同时打开多个面板。提交表格后, 我想保留任何打开的 Bootstrap 手风琴面板的状态.

我已经修改了我在堆栈溢出上找到的一些代码,以使用本地存储执行此操作,如下所示:

Accordion HTML
-------------------
<div class="panel-group" id="accordion">
  <div class="panel panel-default">
    <div class="panel-heading">
      <div class="panel-title"> <a data-toggle="collapse" href="#client_12325">Panel heading</a> </div>
    </div>
    <div id="client_12325" class="panel-collapse collapse">
      <div class="panel-body">Panel Content</div>
    </div>
  </div>
  <div class="panel panel-default">
    <div class="panel-heading">
      <div class="panel-title"> <a data-toggle="collapse" href="#client_12326">Panel heading</a> </div>
    </div>
    <div id="client_12326" class="panel-collapse collapse">
      <div class="panel-body">Panel Content</div>
    </div>
  </div>
 <div class="panel panel-default">
    <div class="panel-heading">
      <div class="panel-title"> <a data-toggle="collapse" href="#client_12327">Panel heading</a> </div>
    </div>
    <div id="client_12327" class="panel-collapse collapse">
      <div class="panel-body">Panel Content</div>
    </div>
  </div>
</div>
Javascript
---------------
<script>
$(document).ready(function() {
    var retainState = [];
    localStorage.setItem('retainState', JSON.stringify(retainState));
    $('#accordion').on('shown.bs.collapse', '.panel-collapse', function() {
        retainState = JSON.parse(localStorage.getItem('retainState'));
        if ($.inArray($(this).attr('id'), retainState) == -1) {
            retainState.push($(this).attr('id'));
        };
        localStorage.setItem('retainState', JSON.stringify(retainState));
    });
    $('#accordion').on('hidden.bs.collapse', '.panel-collapse', function() {
        retainState = JSON.parse(localStorage.getItem('retainState'));
        retainState.splice( $.inArray($(this).attr('id'), retainState), 1  ); //remove item from array
        localStorage.setItem('retainState', JSON.stringify(retainState));
    });
});

var retainStateArray = JSON.parse(localStorage.getItem('retainState'));
var arrayLength = retainStateArray.length;
for (var i = 0; i < arrayLength; i++) {
    var panel = '#'+retainStateArray[i];
    $(panel).addClass('in');
    console.log(panel);
}
</script>

此代码有 2 个问题

1/它在页面刷新时获取面板的正确 ID(您可以通过循环中的控制台日志查看),但它无法将类"in"添加到面板中。

2/它只保留第一次页面重新加载的状态。我希望它保留整个用户会话的状态,无论页面重新加载多少次。

提前谢谢。

如果你不反对添加一个额外的js库,为什么不使用js-cookie。

单击提交按钮时,使用选择了"in"类的 ID 创建一个 cookie。

如果饼干不存在
观察到默认折叠状态。

如果 Cookie 确实存在
测试当前页面上
是否存在"#accordion"从 cookie
中获取 ID解析 ID 的
dom应用类"in"

赢?

在您的代码上,当 DOM 准备就绪时,它将始终将 localstorage 设置为空数组,因为您将空数组分配给 retainState。

您可以做的是首先检查本地存储是否存在,然后将其分配给 retainState。

设法

让它工作。我确信这段代码可能会更漂亮

$(document).ready(function() {
  var lastState = localStorage.getItem('lastState');
  if (!lastState) {
    lastState = [];
    localStorage.setItem('lastState', JSON.stringify(lastState));
  } else {
    lastStateArray = JSON.parse(lastState);
    var arrayLength = lastStateArray.length;
    for (var i = 0; i < arrayLength; i++) {
        var panel = '#'+lastStateArray[i];
        $(panel).addClass('in');
    }
  }
  $('#accordion').on('shown.bs.collapse', '.panel-collapse', function() {
    lastState = JSON.parse(localStorage.getItem('lastState'));
    if ($.inArray($(this).attr('id'), lastState) == -1) {
        lastState.push($(this).attr('id'));
    };
    localStorage.setItem('lastState', JSON.stringify(lastState));
  });
  $('#accordion').on('hidden.bs.collapse', '.panel-collapse', function() {
    lastState = JSON.parse(localStorage.getItem('lastState'));
    lastState.splice( $.inArray($(this).attr('id'), lastState), 1 ); 
    localStorage.setItem('lastState', JSON.stringify(lastState));
  });
});