Search code examples
javascripthtmljsonserializationeventhandler

Serialising an HTML element that has event handlers


I am currently making a website for a class that I am in. It is supposed to be a store, made in Pure HTML, CSS, and JavaScript (no libraries including jQuery). I am currently attempting at making a functional cart right now. My idea is to take the element that has the information about that item (image and name, but price I kept to be constant throughout to make it simpler). From here, I thought about serialising that element and saving it to localStorage so that I can load it from the cart page. When I try JSON.serialize(product) where product is the element of the item, it only ends up with "{}" and nothing else. XMLS.serialiseToString() only gives the element without the event handler. How am I supposed to make this work?

I also tried loading the event handler in the cart page too, but I cannot figure out a way to get the HTML element from a string. Could someone tell me how to make this work? I looked at a few other questions on here but it does not make much sense to me.

Edit: I got the serialisation and deserialisation working using XMLSerializer. However, I want to change the click event handler after deserialising the element. How am I supposed to make this work?


Solution

  • XMLSerializer should work.

    You will need to provide more code for what you're doing with local storage and your event handler but based on the info you provided, I included some code with comments below.

    //this is a test click handler function to see if it still works after being added to page
    function testClickHandler() {
      console.log('I still work after being added to document again.')
    }
    
    //initialize XML serializer
    var serializer = new XMLSerializer();
    //get html element from document
    var html = document.querySelector('#serializemecapt');
    //convert element to string
    var htmlString = serializer.serializeToString(html);
    
    //once element is converted to string you can save in local storage
    
    //after you retrieve the element again from local storage, use the code below to insert it into your document again
    
    //insert element back onto page
    document.body.insertAdjacentHTML('afterbegin', htmlString);
    <div id="serializemecapt" onclick="testClickHandler()">Click me to see if the click event still works after I'm pushed back into the document.<br/><br/></div>

    Edit: If you want to change the click handler after serialization, you can do something like this (run the snippet below and see comments):

    //this function will be removed before serialization
    function originalFunction() {
      console.log('I am the original function before serialization.')
    }
    
    //this function will be added after serialization
    function newFunction() {
      console.log('I am the new function after serialization.')
    }
    
    //get html element from document
    var html = document.querySelector('#serializeme');
    
    //apply originalFunction to div using addEventListener
    html.addEventListener('click', originalFunction)
    
    
    //new function to demonstrate serialization
    function serializeHtml() {
    
      //initialize XML serializer
      var serializer = new XMLSerializer();
    
      //remove event listener for originalFunction before serialization
      html.removeEventListener('click', originalFunction)
    
      //serialize html
      var htmlString = serializer.serializeToString(html);
    
      //insert element back onto page
      document.body.insertAdjacentHTML('afterbegin', htmlString);
    
      //change innerText on element for example purposes
      html.innerText = 'I am the same div as above after serialization. I have new text and a new function. Click me now and I will run the new function.'
    
      //add newFunction to div using addEventListener
      html.addEventListener('click', newFunction)
    }
    
    //get button element from document
    var serialButton = document.querySelector('#serialButton');
    
    //apply serializeHtml function to button using addEventListener
    serialButton.addEventListener('click', serializeHtml)
    <div id="serializeme"><b>Click me</b> before serializing to run the original function.<br/><br/></div>
    
    <p><b>Click button below to serialize the div above and apply a new function to the div after serialization.</b></p>
    
    <button id="serialButton">Serialize</button>