LocalStorage addClass多个值

时间:2018-12-31 16:34:54

标签: javascript jquery

我几乎可以得到想要的东西,但这是问题所在。首先,添加了“单击时显示类”功能,并将其保存在本地存储中。在这里,我已经实现了,但是唯一的问题是我想保存多次单击,因此在这里,当我单击一个时,第一个div处于活动状态,而其他则被删除,当单击两个时,第二个div处于活动状态,other(一和三)从活动状态中删除。当我同时单击一个和两个时,我希望两个都处于活动状态并将其保存在json本地存储中。

这里是my jsfiddle

$(document).ready(function() {
  $('.relative_holder').click(function(e) {
    e.preventDefault();
    var $nextDiv = $(this).closest('.list-content-single');

    var $divs = $('.list-content-single').removeClass('visitednw');

    if (!$nextDiv.length)
      $nextDiv = $divs.first();

    $nextDiv.addClass('visitednw');
    localStorage.setItem("activeDiv", $nextDiv.index('.list-content-single'));
  });

  var activeIndex = localStorage.getItem("activeDiv");
  if (activeIndex)
    $('.list-content-single').removeClass('visitednw').eq(activeIndex).addClass('visitednw')
});
.visitednw {
  color: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div class="list-content-single" id="first">
  <h1> first div</h1>
  <a class="relative_holder" href="#" id="btn-first">
    One
  </a>
</div>

<div class="list-content-single" id="second">
  <h1> second div</h1>
  <a class="relative_holder" href="#" id="btn-second">
    Two
  </a>
</div>

<div class="list-content-single" id="third">
  <h1> third div</h1>
  <a class="relative_holder" href="#" id="btn-third">
    Three
   </a>
</div>

4 个答案:

答案 0 :(得分:0)

解释

看到您当前的操作方式,效率似乎有些低下,所以我已经这样写了,这种方式只会在必要时运行,而不是运行$(document).ready函数中的所有内容。

如您所见,我将解决方案分解为一系列小的,简洁和简单的函数,以确保解决方案简单而轻巧。有许多仅用于处理状态的函数,这纯粹是因为在Stackoverflow上,例如,您不能在片段中实际使用localStorage,因此普通ol'try, catch解。

无论如何,您可以看到DOM准备就绪时,两个函数dispatchEventsrender被触发,为了简单起见,我再次使用了这些名称,以确保功能很清楚。然后,当然,clickHandler函数负责管理如何更新状态,一旦更新了状态,就会触发updateState函数,从此处它将重新呈现UI并记录状态,就这么简单。

PS

您可能希望使用比我更多的jQuery,我实际上只是将其用于ready函数,仅此而已。

// Just a global variable for the local storage key.
const stateName = 'activeDiv';

// Global/public state in the event that local storage can't be used. 
let state = {};


// A simple function to get the state of the application.
const getState = () => {
  try {
    const data = JSON.parse(localStorage.getItem(stateName));
    if (typeof data != 'object' || data == null) {
      return state;
    } else {
      state = data;
      return state;
    }
  } catch (e) {
    return state;
  }
};


// A simple function to update the application state.
const updateState = newState => {
  try {
    localStorage.setItem(stateName, JSON.stringify(newState));
  } catch (e) {
    // todo 
  }

  state = getState();
  console.clear();
  console.log(state);

  render();
};


// A simple function to update the UI. 
const render = () => {
  const local = getState();
  const divs = document.querySelectorAll(".list-content-single");

  if (local.active != null) {
    divs.forEach(div => {

      if (local.active.indexOf(div.id) >= 0) {
        div.className = "visitednw list-content-single";
      } else {
        div.className = "list-content-single";
      }
    });
  }
};


// A simple function to update the state when a button is clicked.
const clickHandler = () => {
  const e = event || window.event;
  const div = e.target.parentElement;
  const key = div.id;
  const local = getState();

  if (local[key] == null) {
    local[key] = 1; // The default value, clicked once already. 
  } else {
    local[key] += 1;
  }

  if (local.active == null) {
    local.active = [];
  }

  if (local.active.indexOf(key) == -1) {
    local.active.push(key);
  }

  updateState(local);

  // Double whammy.
  e.preventDefault();
  return false;
};


// A simple function to manage what events handle what.
const dispatchEvents = () => {
  const divs = document.querySelectorAll(".list-content-single");
  divs.forEach(div => {
    const btn = div.querySelector(".relative_holder");
    btn.onclick = () => clickHandler();
  })
};


// A simple function to be fired for $(document).ready.
const onReady = () => {
  render();
  dispatchEvents();
};


// Good ol' $(document).ready.
$(document).ready(onReady);
.visitednw {
  color: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div class="list-content-single" id="first">
  <h1> first div</h1>
  <a class="relative_holder" href="#" id="btn-first">
    One
  </a>
</div>

<div class="list-content-single" id="second">
  <h1> second div</h1>
  <a class="relative_holder" href="#" id="btn-second">
    Two
  </a>
</div>

<div class="list-content-single" id="third">
  <h1> third div</h1>
  <a class="relative_holder" href="#" id="btn-third">
    Three
   </a>
</div>

ES5版本

如果您不熟悉ES6,请不用担心,这是ES5的实现。

// Just a global variable for the local storage key.
var stateName = 'activeDiv';

// Global/public state in the event that local storage can't be used. 
var state = {};


// A simple function to get the state of the application.
var getState = function() {
  try {
    var data = JSON.parse(localStorage.getItem(stateName));

    if (typeof data != 'object' || data == null) {
      return state;
    } else {
      state = data;
      return state;
    }
  } catch (e) {
    return state;
  }
};


// A simple function to update the application state.
var updateState = function(newState) {
  try {
    localStorage.setItem(stateName, JSON.stringify(newState));
  } catch (e) {
    // todo 
  }

  state = getState();
  console.clear();
  console.log(state);
  render();
};


// A simple function to update the UI. 
var render = function() {
  var local = getState();
  var divs = document.querySelectorAll(".list-content-single");

  if (local.active != null) {
    divs.forEach(function(div) {

      if (local.active.indexOf(div.id) >= 0) {
        div.className = "visitednw list-content-single";
      } else {
        div.className = "list-content-single";
      }
    });
  }
};


// A simple function to update the state when a button is clicked.
var clickHandler = function() {
  var e = event || window.event;
  var div = e.target.parentElement;
  var key = div.id;
  var local = getState();

  if (local[key] == null) {
    local[key] = 1; // The default value, clicked once already. 
  } else {
    local[key] += 1;
  }

  if (local.active == null) {
    local.active = [];
  }

  if (local.active.indexOf(key) == -1) {
    local.active.push(key);
  }

  updateState(local);

  // Double whammy.
  e.preventDefault();
  return false;
};


// A simple function to manage what events handle what.
var dispatchEvents = function() {
  var divs = document.querySelectorAll(".list-content-single");
  divs.forEach(function(div) {
    var btn = div.querySelector(".relative_holder");
    btn.onclick = () => clickHandler();
  })
};


// A simple function to be fired for $(document).ready.
var onReady = function() {
  render();
  dispatchEvents();
};


// Good ol' $(document).ready.
$(document).ready(onReady);
.visitednw {
  color: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>


<div class="list-content-single" id="first">
  <h1> first div</h1>
  <a class="relative_holder" href="#" id="btn-first">
    One
  </a>
</div>

<div class="list-content-single" id="second">
  <h1> second div</h1>
  <a class="relative_holder" href="#" id="btn-second">
    Two
  </a>
</div>

<div class="list-content-single" id="third">
  <h1> third div</h1>
  <a class="relative_holder" href="#" id="btn-third">
    Three
   </a>
</div>

答案 1 :(得分:0)

您需要设置并获取localStorage的索引数组,并将类设置为正确的列表项。

由于localStorage仅支持字符串,因此可以使用

localStorage.setItem("activeIndices", JSON.stringify(activeIndices));

JSON.parse(localStorage.getItem("activeIndices"));

我制作了更新的小提琴 here

答案 2 :(得分:0)

我会做这样的事情,基本上将所有当前活动的id存储为逗号分隔的字符串,并在需要使用它时将其转换为数组:

https://jsfiddle.net/Lf6smofv/317/

$(document).ready(function() {

  // set initial display on page load
  displayVisited();

  // update display on click
  $('.relative_holder').click(function(e) {
    e.preventDefault();
    toggleVisited(this.id);
  });
});


function displayVisited() {
  $('.list-content-single').removeClass('visitednw')
  var activeIds = getActiveIds();
  if (activeIds.length > 0) {
    var idString = '#' + activeIds.join(",#");
    $(idString).closest('.list-content-single').addClass('visitednw')
  }
}

function toggleVisited(id) {
  var activeIds = getActiveIds();
  // if the given id is not in our array already, add it
  if ($.inArray(id, activeIds) === -1) {
    activeIds.push(id);
  } else {
    // if the given id is in our array already, remove it
    activeIds = removeVisited(activeIds, id);
  }
  localStorage.setItem("activeDivs", activeIds.join(','));
  displayVisited();
}

// get the array of visited ids with the given id removed
function removeVisited(storedIds, removedId) {
  var cleanIds = [];
  // if the given id is in our array, remove it
  if ($.inArray(removedId, storedIds) !== -1) {
    $.each(storedIds, function(i, currentId) {
      if (currentId !== removedId) {
        cleanIds.push(currentId);
      }
    });
  }
  return cleanIds;
}

// get an array of active ids from local storage
function getActiveIds() {
  var activeIds = localStorage.getItem("activeDivs");
  console.log(activeIds)
  return activeIds ? activeIds.split(',') : [];
}

答案 3 :(得分:0)

此答案提供了一些方法来添加内容,将内容保存到本地存储中,并在我们尝试访问它时处理丢失的内容。我还添加了通过再次单击将其关闭的功能,如果需要,只需将inuse始终设置为true即可轻松关闭该部分。它非常冗长,因此您可以看到每一行的情况。如果您添加更多内容,这也应该处理更多项目(按索引)-您可以考虑使用data属性,而不是使用该索引,这样HTML的顺序就不会与存储紧密地联系在一起。

//console.clear();
var itemName = "activeDiv";

function saveItems(savethese) {
  // Put the object into storage
  localStorage.setItem(itemName, JSON.stringify(savethese));
}

function getSavedItems() {
  // Retrieve the object from storage and parse if it is there
  let retrievedItems = localStorage.getItem(itemName);
  let parsedItems = (!retrievedItems || !retrievedItems.length) ? [] : JSON.parse(retrievedItems);

  return parsedItems;
}

function setItem(sel, index, inuse) {
  return {
    id: index,
    idval: sel[0].id,
    inuse: inuse
  };
}

function addOrReplace(array, item) {
  const i = array.findIndex(_item => _item.id === item.id);
  if (i > -1) {
    array[i] = item;
  } else {
    array.push(item);
  }
  return array;
}
$(function() {
  $('.relative_holder').on('click', function(e) {
    e.preventDefault();
    let items = getSavedItems();
    let $parent = $(this).closest('.list-content-single');
    let $divs = $('.list-content-single');
    let tindex = $divs.index($parent);
    let checkMe = items.find(obj => {
      return obj.id === tindex
    });
    let isPresent = !(checkMe === undefined);
    let isSet = isPresent && checkMe.inuse;
    //console.log("tindex:", tindex);
    //console.log("items:", items);
    $parent.toggleClass('visitednw',!isSet);
    var item = setItem($parent, tindex, !isSet);
    items = addOrReplace(items, item);
    saveItems(items);
  });
  // set initial values based on prior setting
  (function() {
    var possible = $('.list-content-single');
    let itemsSet = getSavedItems();

    var i = 0;
    var ilen = itemsSet.length;
    //console.log(itemsSet);
    for (i; i < ilen; i++) {
      possible.eq(itemsSet[i].id).toggleClass('visitednw', itemsSet[i].inuse);
    }
  })();
});
.visitednw {
  color: #C00;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="list-content-single" id="first">
  <h1> first div</h1>
  <a class="relative_holder" href="#" id="btn-first">
    One
  </a>
</div>
<div class="list-content-single" id="second">
  <h1> second div</h1>
  <a class="relative_holder" href="#" id="btn-second">
    Two
  </a>
</div>
<div class="list-content-single" id="third">
  <h1> third div</h1>
  <a class="relative_holder" href="#" id="btn-third">
    Three
   </a>
</div>