Reading JSON+LD Structured Data with JavaScript

I'd been working on a website that included a couple of event schedule pages for about 18 months, and so in order to take advantage of Google and Bing's enhanced snippets display of JSON+LD data for such pages I started adding Structured Data in that format to the site. But it felt like I was short-changing visitors to the site by not making that data easily accessible, so I decided to write some JavaScript to locate and parse the JSON+LD data and insert it into a toggled DIV.

Since I had no idea how to begin, I tried searching for some example JavaScript just to get me started and found almost no help for beginners. Every article I found seemed to be aimed at advanced users with vast experience in Structured Data and most of it was focused on server-side solutions. Once I got a foothold on reading JSON with JavaScript, I found it was dirt simple since JavaScript's built-in JSON object library does the dirty work for you.

My little JavaScript JSON parser scans your document for div tags with a class name of "rdEvent", which includes a well-structured JSON data component for each event.

Let's start with the HTML and the JavaScript JSON+LD structured data that displays a sample event listing:

<div class="rdEvent"> <a class="eName" href="http://www.raintaxi.com/twin-cities-book-festival/">Twin Cities Book Festival</a>: <span class="eDate">October 17</span><br> Premier literary event in the Twin Cities held each year on the Minnesota State Fairgrounds. This year's Festival is open from 10AM to 5PM. Free admission! <script type="application/ld+json"> { "@context": "http://schema.org", "@type": "Event", "name": "Twin Cities Book Festival", "startDate" : "2015-10-17T10:00", "endDate" : "2015-10-17T17:00", "url" : "http://www.raintaxi.com/twin-cities-book-festival/", "location" : { "@type" : "Place", "sameAs" : "http://www.mnstatefair.org/", "name" : "Minnesota State Fairgrounds", "address" : "1265 Snelling Avenue N, St. Paul, MN 55108" } } </script> </div>

This example JSON parser scans a document for all containing elements (like a div) with a class name of "rdEvent". Each such container is then scanned for a JavaScript/JSON block, whose "innerHTML" is then parsed as a JSON Object with "JSON.parse()" and its individual properties can subsequently be easily retrieved by JavaScript using "jsonObjectName.propertyName".

My implementation converts the location data into an address suitable for display and adds a link labeled "Location Info" to the displayed information block. When the link is clicked by a user, a hidden block containing the name and street address of the location is made visible along with a link to a pop-up Google map of the location. Try it yourself, below:

Twin Cities Book Festival: October 17
Premier literary event in the Twin Cities held each year on the Minnesota State Fairgrounds.
This year's Festival is open from 10AM to 5PM. Free admission!

The box below contains my JavaScript JSON parser as it is used on this page. You'll undoubtedly need to modify it for your own uses. Again, the key point is to note how the various properties of the JSON object I named 'json' are referenced. Everything else is specific to this example implementation. This example includes a good example of inserting HTML code into the DOM with JavaScript that uses the JSON data to build enhanced content for the user. By relying on JavaScript to create these additional elements, it insures that users running with JavaScript disabled will not encounter non-functioning links and buttons.

// JSON Parser Globals var rdEvents = new Array(); var rdJSONContainerName = 'rdEvent'; var rdLocInfoLinkText = 'Location Info'; var rdMapLinkText = 'See Map'; function rdInitShowEvent() { var s, data, json, atag, t, spantag, locText; rdEvents = document.getElementsByClassName(rdJSONContainerName); for (i=0; i<rdEvents.length; i++) { atag = document.createElement('A'); atag.setAttribute('onclick', 'return rdToggleLoc("rdLocBoxID' + i + '")'); atag.setAttribute('class', 'rdToggleBtn'); atag.setAttribute('style', 'padding:2px 4px; font-weight:bold; background-color:gold;'); t = document.createTextNode(rdLocInfoLinkText); atag.appendChild(t); rdEvents[i].appendChild(atag); t = document.createElement('BR'); rdEvents[i].appendChild(t); spantag = document.createElement('DIV'); spantag.setAttribute('class', 'rdLocBox'); spantag.setAttribute('id', 'rdLocBoxID' + i); spantag.setAttribute('style', 'display:none;'); s = rdEvents[i].getElementsByTagName('script')[0]; data = s.innerHTML; json = JSON.parse(data); atag = document.createElement('A'); atag.setAttribute('href', json.location.sameAs); atag.setAttribute('style','font-weight:bold;'); t = document.createTextNode(json.location.name); atag.appendChild(t); spantag.appendChild(atag); atag = document.createElement('BR'); spantag.appendChild(atag); t = document.createTextNode(json.location.address); spantag.appendChild(t); var rdLocation = json.location.address.split(','); if (rdLocation.length == 3) { atag = document.createElement('BR'); spantag.appendChild(atag); var stateZip = rdLocation[2].replace(/^\s+/,'').split(' '); link = "popZoomMap('" + rdLocation[0] + "','" + rdLocation[1] + "','" + stateZip[0] + "','" + stateZip[1] + "','" + json.location.name + "');"; t = document.createTextNode(' '); spantag.appendChild(t); atag = document.createElement('A'); atag.setAttribute('onclick',link); atag.setAttribute('class','mapButton'); atag.setAttribute('style','font-weight:bold;'); t = document.createTextNode(rdMapLinkText); atag.appendChild(t); spantag.appendChild(atag); } // endif rdLocation.length rdEvents[i].appendChild(spantag); } // end for i } // end rdInitShowEvent() // Show/Hide function function rdToggleLoc(id) { var box = document.getElementById(id); (box.style.display == 'none') ? box.style.display = 'block' : box.style.display = 'none'; return false; } // end rdToggleLoc() // Install 'onload' event to initialize the JSON Parser if (window.addEventListener) { window.addEventListener('load', rdInitShowEvent, false); } else if (window.attachEvent) { window.attachEvent('onload', rdInitShowEvent); }

This page was last modified on August 27, 2020


Copyright © 2005-2024 by Richard L. Trethewey - Rainbo Design Minneapolis. It's not that I think this is such an earth-shatteringly great presentation, but if you want to copy it, I'd appreciate it if you would ask for permission. I've been working with computers for over 30 years now, and one phrase keeps popping into my head - "I hate it when it's right!" And laptops and smartphones are no better.

Looking for more website design information? See my Sitemap!