1

Using and html element's addEventListener has several advantages over using inline events, like onclick.

However, to store the element including its inline event is straight forward, for example, by embedding it in a parent element and storing the parent's innerHTML.

Is it possible to do something similar when using event listeners?

Edit:

I realized that my question is not sufficiently explained. So here some additions.

By "store" I mean a way to get the information holding the element and the event listener.

The analogue with inline events is easy: just embed in a parent element and save the parent's innerHTML (string) somewhere, for example in a database, and recreate the element later by loading the string and applying it to the innerHTML of some element.

But how would one do the analogue with elements when using event listeners? One cannot just use the innerHTML since then the events are not stored.

I hope this clarifies my question a bit.

Edit 2

With the help of comments I have made some unsuccessful attempts.

It is possible to get store the information of an element using createDocumentFragment() or element.cloneNode(true).

However, the first method does not work for external storage since, if I understood correctly, will contain only a pointer. Here is an example:

https://jsfiddle.net/hcpfv5Lu/

The second method does not work either. I am not fully sure why, but if I JSON.stringify the clone it "vanishes". Here is an example:

https://jsfiddle.net/3af001tq/

Daniel
  • 3,383
  • 4
  • 30
  • 61
  • What do you mean by "store"? – KevBot Jan 05 '17 at 16:07
  • @KevBot I mean a way to get the information to put it somewhere else and load it again later. For example, one could store the `innerHTML` (string) of one element and reapply it later to some other element in order to have the former element restored. – Daniel Jan 05 '17 at 16:10
  • am i missing something? addEventListener is javascript, not html – Cruiser Jan 05 '17 at 16:11
  • You can create elements using `Document.createElement()`[doc](https://developer.mozilla.org/en-US/docs/Web/API/Document/createElement) and attach event listeners to the created object. Then you can insert this object into a "parent" by `parent.appendChild(obj)`[doc](https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild). Then you can "store" the objects in JavaScript. – E. Sundin Jan 05 '17 at 16:13
  • [http://stackoverflow.com/a/6348597/3877877](http://stackoverflow.com/a/6348597/3877877) ... perhaps i misunderstood, but you can do it the same way. – Martin E Jan 05 '17 at 16:13

2 Answers2

0

You could use a document fragment to store the DOM node in a JavaScript variable which can then be appended to a DOM element when required.

https://developer.mozilla.org/en/docs/Web/API/Document/createDocumentFragment

MrBizle
  • 418
  • 4
  • 12
  • Thanks. Sounds like it could work. Unfortunately, I fail to figure out the details: https://jsfiddle.net/hcpfv5Lu/. In order to store the element I use `JSON`. Otherwise I get only a pointer to the element, I think. But when I restore it javascript complains that it is no node. – Daniel Jan 05 '17 at 18:23
  • I think you are perhaps barking up the wrong tree, a dom node cannot be stored in json format. If you need to store HTML in JSON format you will need a string, then you need to append that string to a node, if that doesn't already exist you will need to create it using a doc frag or document.createElement – MrBizle Jan 06 '17 at 09:43
  • Thanks. I am not sure I get your suggestion. I want to transform a DOM element (including its event listeners attached by javascript) into a string in order to store it in a database. I can store the DOM excluding its event listeners with `string = JSON.stingify(element.innerHTML)` and restore it with `element.inerHTML = JSON.parse(string)`. But how do I preserve the event listeners? – Daniel Jan 06 '17 at 10:04
  • 1
    You cannot store a dom node in JSON, so you will need to write to your document and bind the event listeners to the node when created, adding them in the first instance before storing in JSON would be redundant. This is a nice solution http://stackoverflow.com/questions/16113070/how-to-associate-an-object-with-a-dom-element – MrBizle Jan 06 '17 at 10:11
  • Too bad that one cannot export dom nodes. I wonder why. The solution you refer to works only if I know from the start which nodes get which events. But it seems to fail if I don't, for example, in case a user can add them. – Daniel Jan 06 '17 at 13:38
  • 1
    Yeah a node and the event listeners attached to it is very much a part of the document object model by nature. What are you actually trying to do? Why does it need to be stored in JSON and why do you not know what events need to be attached when it's in the DOM? – MrBizle Jan 06 '17 at 16:45
  • I have a script that creates an svg with attached event listeners. The user can save the information to a database and load it later again. However, the script takes quite long to create the svg. So rather than saving the input of the algorithm and let it run again, I would like to save the output (the svg). Hence it would be nice to store it including its event listeners. I know how to store strings in a database hence I wanted to `stringify` the output. Does that make sense? – Daniel Jan 06 '17 at 18:57
  • 1
    Unfortunately you will not be able to retain the event listeners in a string, only store a reference to what they were. Could you create the string for the SVG with a server side lang? depending on what you're doing it's likely to be faster. – MrBizle Jan 09 '17 at 09:40
  • Thanks. I see. Interesting that after all there seems to be at least one good case where inline events have an edge. Although it is still a bit surprising that there is no default method to save the whole SVG including attached event listeners. – Daniel Jan 10 '17 at 08:21
  • I did not consider server side computation yet. The SVG is created using MathJax. So I guess I would have to pull that server side too. I'll might look into that. For now I am loading the SVG and show it quickly without the attached events and let the event SVG be computed in the background while showing a "Loading..." message and replace it once it's done. – Daniel Jan 10 '17 at 08:22
  • Im not sure if inline would have any advantage over a function, it would be worse in the case of server side rendering eg if you stored the string with a reference to all the event listeners it could be done with very small amounts of data handled by a script on page. Good luck buddy! – MrBizle Jan 10 '17 at 17:00
-2

Yes.

You can use something like.

<ul>
   <li id="list">Some data</li>
   <li>Dumy</li>
</ul>

then in your javascript file,

document.getElementById("list").addEventListener("click", function(){
     var htmlMarkUp = this.parentNode.innerHTML;
});

This would store the html content of ul in var htmlMarkUp.

relentless-coder
  • 1,478
  • 3
  • 20
  • 39