【问题标题】:Why is persisting data not working as it should?为什么持久化数据不能正常工作?
【发布时间】:2017-09-12 03:09:43
【问题描述】:

我正在使用三个标签,分别称为“星期一”、“星期二”和“收藏夹”。我有一个切换图标,它在开始“最喜欢的 i”时是一颗空心。如果我在星期一并单击该图标,则会填充空心,并将其父级克隆并添加到“#fav”选项卡中。发生这种情况时,克隆将保存到本地存储。因此,如果人们刷新页面,他们仍然可以看到自己的偏好。

当在其中一个克隆的 div 中单击心脏时,特定 div 将从“#fav”中删除,并且也会从数组中删除。

一切正常,除非我刷新浏览器并检测到本地存储。

因此,在这种情况下,如果我在星期一并单击充满的心,它不会从#fav 中删除克隆,但仍会向#fav 添加新的克隆。另外,如果我在#fav 选项卡中,当单击其中一颗心时,它应该会从数组中删除索引,但实际上,它会删除整个数组。

如何解决这个问题?非常感谢。

HTML:

<section id="speakers-programme">
  <div class="container">
    <div class="tabs_main">

      <div class="col-md-5"><a data-target="#mon" class="btn active" data-toggle="tab">Monday</a></div>
      <div class="col-md-5"><a data-target="#tue" class="btn active" data-toggle="tab">Tuesday</a></div>
      <div class="col-md-2"><a data-target="#fav" class="btn active" data-toggle="tab"><i class="fa fa-heart" aria-hidden="true"></i></a></div>

    </div>

    <div class="tab-content">
      <div class="tab-pane active" id="mon">
        <br>
        <div class="spaces">
          <div class="box-container">
            <div class="box not-selected" id="box1">
              <span>1</span>
              <a href="#" class="favorite"><i class="fa fa-heart-o" aria-hidden="true"></i></a>
            </div>
          </div>
          <div class="box-container">
            <div class="box not-selected" id="box2">
              <span>2</span>
              <a href="#" class="favorite"><i class="fa fa-heart-o" aria-hidden="true"></i></a>
            </div>
          </div>
        </div>
      </div>

      <div class="tab-pane active" id="tue">
        <br>
        <div class="spaces">
        </div>
      </div>

      <div class="tab-pane active" id="fav">
        <br>
        <div class="spaces">
        </div>
      </div>

    </div>
  </div>
</section>

JS

console.clear();
//localStorage.setItem('sessions', "");

var tempArray = [];

// Clones
$('div.tab-pane').on('click', '.favorite', function(e) {
  e.preventDefault();

  // Elements we play with... Having significative variable names.
  var heartLink = $(this);
  var box = heartLink.parent('.box');
  var container = box.parent('.box-container');
  var favoriteTab = $("#fav .spaces");

  // I don't know what is the use for those 3 lines below.
  var idFind = box.attr("id");
  var idComplete = ('#' + idFind);
  console.log(idComplete);

  //TOGGLE FONT AWESOME ON CLICK
  heartLink.find('i').toggleClass('fa-heart fa-heart-o'); // .selected or not, you need those 2 classes to toggle.
  box.toggleClass("selected not-selected"); // Toggle selected and not-selected classes

  // Clone div
  var boxContent = container.clone(true, true);

  // Change the id
  var thisID = boxContent.attr("id")+"_cloned";
  boxContent.attr("id", thisID);

  // Get the html to be saved in localstorage
  var get = boxContent.wrap('<p>').parent().html();
  get = get.replace(/\r?\n/g, "").replace(/>\s*</g, "><"); // remove line feeds and spaces
  console.log(get);
  boxContent.unwrap();

  // Decide to add or remove
  if(box.hasClass("selected")){
    console.log("Add to array")
    tempArray.push(get);

    // Add to favorites tab
    favoriteTab.append(boxContent);

  }else{
    console.log("Remove from array");
    var index = tempArray.indexOf(get);
    tempArray.splice(index);

    // Remove from favorite tab
    favoriteTab.find("#"+thisID).remove();
  }

  // Save array
  localStorage.setItem('sessions', tempArray.join(""));
  console.log(tempArray);

  // save this current toggle state
  localStorage.setItem(box.attr("id"), $(this).find("i").attr("class"));
  console.log($(this).find("i").attr("class"));

});

// Append item if localstorage is detected
if (localStorage["sessions"]) {
  console.log("storage exist");

  // Load 
  $(".box").each(function(){
    console.log( $(this).attr("id") );
    console.log( localStorage.getItem($(this).attr("id")) );

    if(localStorage.getItem($(this).attr("id")) != null){
      $(this).find("i").removeClass().addClass( localStorage.getItem($(this).attr("id")) );
    }
  });

  $("#fav .spaces").append(localStorage["sessions"]);
  console.log( localStorage["sessions"] );
}

小提琴:https://codepen.io/Bes7weB/pen/bobjdv?editors=1011

【问题讨论】:

  • 在 localStorage 中存储 HTML 对我来说似乎是一种奇怪的方式。如果是我,我会使用简单的 JS 数据结构来表示收藏夹的状态。例如,如果每个部分都有某种类型的 id(我不一定指元素上的 id 属性),您可以将收藏夹表示为当前选定 id 的数组,[1, 2, 3]。然后将更新页面的每个部分以反映该数组的当前状态。尝试使用 DOM 或其 HTML 表示作为应用程序状态的主要参考会很快变得混乱
  • 我不具备这样做的知识。你能告诉我这样做的方法吗?谢谢你。 @裙子

标签: javascript jquery onclick save storage


【解决方案1】:

我以一种值得解释的方式扭曲了你的代码。

首先,您终于不需要保存您喜欢的元素的 HTML。您只需要心脏图标状态,您已经这样做了。我添加了一个计数器,只是为了知道存储中有多少收藏。

现在,在页面加载...你已经把这部分做对了。 然后循环遍历所有的心来定位填充的心并将它们克隆到最喜欢的选项卡中。我做了一个“命名函数”来做到这一点。

现在点击图标...点击克隆元素或原始元素是两种不同的情况。

在原始元素上,您希望切换其类并将其克隆到收藏选项卡。所以在这里,只需进行切换,对于最喜欢的选项卡,只需调用前面的命名函数即可将它们全部克隆!

在克隆元素上,您希望将其从收藏夹中删除并切换原始元素类。查看代码以获取我制作的这个twist!在这种情况下,我重新定义了一些变量。

注意不再使用tempArray
;)

var favoriteTab = $("#fav .spaces");

// Named function to load the favorites tab
function loadFav(){
  // First, clear old favorites.
  favoriteTab.empty();

  // Look for filled hearts
  var favCount = 0;
  $(".tab-content").find("i.fa-heart").each(function(){
    // Count them
    favCount++;
    // Clone its box
    var favClone = $(this).closest(".box").clone();
    // Change the id
    favClone.attr("id", favClone.attr("id")+"_clone");
    // Append to favorites
    favoriteTab.append(favClone);
  });

  console.log("favCount: "+favCount);
  localStorage.setItem("favAmount", favCount);
}

// Click handler
$('div.tab-pane').on('click', '.favorite', function(e) {
  e.preventDefault();

  // Elements we play with... Having significative variable names.
  var heartLink = $(this);
  var box = heartLink.parent('.box');
  var thisID = box.attr("id");
  var container = box.parent('.box-container');

  if(thisID.split("_")[1] == "clone"){
    console.log("You clicked a clone!");
    // Remove that clone
    box.remove();
    // Use the original element for the rest of the function.
    heartLink = $("#"+thisID.split("_")[0]).find("a.favorite");
    box = heartLink.parent('.box');
    thisID = box.attr("id");
  }

  //TOGGLE FONT AWESOME ON CLICK
  heartLink.find('i').toggleClass('fa-heart fa-heart-o'); // .selected or not, you need those 2 classes to toggle.
  box.toggleClass("selected not-selected"); // Toggle selected and not-selected classes

  // Clone div
  loadFav();

  // Save this current toggle state
  localStorage.setItem(box.attr("id"), heartLink.find("i").attr("class"));
  console.log(heartLink.find("i").attr("class"));

});




// ON PAGE LOAD
// Append item if localstorage is detected
if (localStorage["favAmount"]>0) {
  console.log("storage exist");

  // Load heart's element states
  $(".box").each(function(){
    console.log( $(this).attr("id") );
    console.log( localStorage.getItem($(this).attr("id")) );

    if(localStorage.getItem($(this).attr("id")) != null){
      $(this).find("i").removeClass().addClass( localStorage.getItem($(this).attr("id")) );
    }
  });

  // Load favorites
  loadFav();

}else{
  console.log("no storage");
}

CodePen v6

【讨论】:

  • 我能说什么?杰出的!非常感谢您的清晰解释,我学到了很多东西.. :)
  • 这意味着要为我保留两杯啤酒。 ;)
  • 如果你来伦敦给我留言,我会处理的!再次感谢你:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-31
  • 2016-07-16
  • 2019-01-04
  • 2020-09-03
相关资源
最近更新 更多