1

The idea is pretty simple, yet I cannot figure it out. Basically I want to save an element that was clicked in the sessionStorage. However, this is not easy because sessionStorage only takes strings.

I am attatching a click event to all my navigation buttons. (This does not work of course)

navButtons.addEventListener("click", function () {
    sessionStorage['active-nav'] = $(this);
});

How would I save a DOM element and access it later?

EDIT

Basically when the page is reloaded, I want to keep track which element was clicked before and the apply some CSS to it once the new page is loaded. For example changing the background color of that element to orange, etc. Therefore, I need to somehow save some information about that element in the sessionStorage and access the element/ find the element, once the page is reloaded. I used the approach of adding an Id to all elements and then using the javascript function document.getElementById("test"), to find it. However, there are quite a few navigation elements, so adding Ids to all of them would probably not be the cleanest solution. What would be the best way of solving this wihtout adding Ids to everything?

Tom el Safadi
  • 6,164
  • 5
  • 49
  • 102
  • As you say, you cannot save object into sessionStorage, you need to find another solution. Why do you need to do that ? If it's to reproduce later you can use html() function (http://api.jquery.com/html/) – Arthur Feb 02 '19 at 00:26

3 Answers3

2

I'd say you should either:

  • Store it's id, then use document.querySelector() to reselect it using the stored id.

  • Produce & store a reverse selector, by using a library such as SimmerJS, then use document.querySelector() to reselect it using the stored selector.

Reverse selectors avoid the need to add explicit ids to all relevant elements.

Here's how reverse selectors work:

window.simmer = window.Simmer.configure({ depth: 10 })

document
  .querySelector('.container')
  .addEventListener('click', e => {
    console.log(simmer(e.target))
  })
<script src="https://cdn.jsdelivr.net/npm/simmerjs@0.5.6/dist/simmer.js"></script>


<div class="container">
  <div class="left">
    <button> Click Me </button>
  </div>
  <div class="right">
    <button> Click Me </button>
  </div>
</div>

Then save the produced selector and use it again to reselect the element on page load. No explicit ids needed.

Saving selectors avoids serialising & rehydrating HTML, so you don't loose any event listeners attached to the element, plus they won't take up a lot of storage space in case you plan to do this for a lot of elements.

nicholaswmin
  • 21,686
  • 15
  • 91
  • 167
1

You can set the sessionStorage value to .outerHTML of the element.

sessionStorage['active-nav'] = this.outerHTML;

If more data than only the HTML is needed you can store a JSON string at sessionStorage, where one of the values is the .outerHTML.

guest271314
  • 1
  • 15
  • 104
  • 177
  • 1
    Thanks for the suggestion. On a page reload, how would I find the same element? I know this could be achieved adding an Id to all my elements but I would rather avoid that since I am searching for the most elegant solution. – Tom el Safadi Feb 02 '19 at 00:31
  • @TomelSafadi What do you mean by _"find the same element"_? What are you trying to achieve? – guest271314 Feb 02 '19 at 00:32
  • Sorry for the confusion. I made an edit to my post which should clarify what I am trying to do. – Tom el Safadi Feb 02 '19 at 00:38
  • @TomelSafadi If the element is in `sessionStorage` the element was clicked, correct? See [Persist variables between page loads](https://stackoverflow.com/q/29986657/) – guest271314 Feb 02 '19 at 00:39
  • Exactly. But what information about the element do I save? I want to avoid adding Ids to all my elements. Is it a clean solution to save the entire object? – Tom el Safadi Feb 02 '19 at 00:42
  • 1
    @TomelSafadi You can define a unique `data-*` attribute for each element and set the value of that `data-*` attribute as the key at `sessionStorage`. It is not possible to save an `HTMLElement` object at `sessionStorage`. The value needs to be a string, or valid `JSON`, where event names and event handlers can also be stored in `JSON`. – guest271314 Feb 02 '19 at 00:44
  • @TomelSafadi Consider `let fn = e => console.log(e); let data = JSON.stringify({html:this.outerHTML /* "
    " */, event:"click", handler:fn.toString()}); sessionStorage.setItem(this.dataset, data); let el = JSON.parse(data).html; document.body.insertAdjacentHTML('beforeend', el); let e = document.querySelector('[data-id="1"]'); e.addEventListener(JSON.parse(data).event, new Function(\`return ${JSON.parse(data).handler}\`)())`
    – guest271314 Feb 02 '19 at 00:52
  • @TomelSafadi Essentially assign all applicable elements a unique `data-*` attribute which is set as the key for `sessionStorage`. Within the `JSON` set at value you can store one or more event name and handlers, or additional data. When getting `sessionStorage` you can set the same stored values (events) at the element or modify those event handlers to perform other tasks when the re-attached event is dispatched. – guest271314 Feb 02 '19 at 01:07
1
navButtons.addEventListener("click", function () {
   sessionStorage.setItem('div', this.outerHTML);
});

Save using the outerHTML property of the element

To get the same element

var element=sessionStorage.getItem('div');
ellipsis
  • 12,049
  • 2
  • 17
  • 33