0

I have a one-file website... We all know bandwidth and internet are... yeah... That's why I only render parts of user interface when needded. Now I wanna take a step further and use JSON to store small parts of my website (trees of html elements) and generete the actual HTML on demand.

But I'm struggling to figure out how to "convert" the JSON object into plain old HTML. I found many topics and answers on how to achieve this, but none of those solved problems. I need a solution that could generate trees with ANY number of chid elements, inside of child elements and so on... All these solutions used .innerHTML which could literally void all my event handlers. I found nothing I wouldn't know already...

The JSON notation would look like this:

var htmlTree = {
	'type': 'section',
	'attr': {
		'id': 'someID',
		'class': 'someClass'
	},
	'content': 'section name',
	'children': [
		{
			'type': 'h1',
			'attr': {
				'class': 'heading'
			},
			'content': 'Heading',
			'children': [
				{
					'type': 'span',
					'content': 'text'
				},
				{
					'type': 'span',
					'content': 'more text'
				}
			]
		}
	]
}

And the result would look like this:

<section id="someID" class="someClass">
	section name
	<h1 class="heading">
		Heading
		<span>text</span>
		<span>more text</span>
	</h1>
</section>

Does anybody know a solution to this problem? I really don't want to use any frameworks or libraries. I know it's a little hard to do something like this, that's why I'm asking here...

13
  • This is actually not hard at all. It involves traversing the tree and emitting content based exactly on how its described in the JSON. Commented Aug 23, 2019 at 22:19
  • 2
    It sounds like you're really trying to reinvent the wheel and achieve something based on false premises. Using a JSON data structure to generate your website is pretty much a costlier version of doing it in native HTML at this point. Better bandwidth optimizations lie on the way your HTML is served, for example by using gzip compression. Commented Aug 23, 2019 at 22:19
  • Why hard? This is really easy. 1) Just turn that JSON into JavaScript object via window.parseJSON() 2) Then just Iterate over that object and create html tags from there Commented Aug 23, 2019 at 22:19
  • @PaulStenne Yes but I wnna use JSON because this way I can avoid rendering gigabytes of data at once (and everything is served using only ONE HTML file) Imagine that stackoverflow would render this exact page 20 times but with different images and titles. that's what I wanna avoid. Commented Aug 23, 2019 at 22:23
  • 1
    And again--this is a simple recursive structure, any tree-oriented recursion tutorial will have this sorted out in minutes. Commented Aug 23, 2019 at 23:02

2 Answers 2

2

Bandwidth is cheap nowadays as the server supports gzip it takes even less. Why combine with more engaging Json and libraries to create HTML?

Instead of processing JSON, inject ready (parts) html - loaded via Ajax.

Try http://www.json2html.com

You can try something like this but this make sense only if you have many same rows (and your data is really simple).

<html>
<body>
<div id="ct"></div>
<script>
var data = [{ 
    "id" : 1,
    "f" : "Arya",
    "l" : "Stark"
},
{ 
     "id" : 1,
    "f" : "Jon",
    "l" : "Snowk"
}];

var parent = document.getElementById("ct");

data.forEach( function (row) {
	
	newDiv = document.createElement("div");
	newDiv.innerHTML = "<h1>" + row.f + " " + row.l + "</h1>";
	parent.append(newDiv);  
})
</script>
</body>
</html>

Sign up to request clarification or add additional context in comments.

7 Comments

Json is more compact than HTML, even gzipped. I just wanna know if there is a good way to achieve my goal without using any external frameworks/libraries. If you know any good ways, then I would really appreciate your help. Plus the bandwidth isn't really cheap in my country... as it's in 40% just a forest and small valleys with internet over phone cables... Which is 5Mb/s here... Thing again... Cheap?
I compare your JSON (minified) 245 B: and HTML 136 B. pastebin.com/MCJKkq5D Of course after gzipped results can be other. You can write own parser (or use library) in JS and build elements one by one, acording your data. Or prepare HTML ready in backend.
And another thing, I could just store the whole html tree as a string in a variable, but then I would have to use innerHTML to render those, which could ruin the event handlers.
@FalsePrice I really don't think you've completely thought this through. You're either going to need a non-HTML representation of the bits you want to render, or HTML. If you have complex event handling you can't do via normal event bubbling, you're backing yourself into a corner. So all the data will be there anyway--just hide or show it. I just don't believe there's any point to what you're doing, and there's not enough detail in the question to suggest what you're doing is a valuable exercise.
@FalsePrice added a small snippet. Maybe you should consider dividing the page into subpages, using browser-side caching - PWA elements. maybe that would reduce the amount of bandwidth. Good luck.
|
0

The JSON.parse reviver can be used to transform key value pairs in JSON string :

var json = '{"type":"section","attr":{"id":"someID","class":"someClass"},"content":"section name","children":[{"type":"h1","attr":{"class":"heading"},"content":"Heading","children":[{"type":"span","content":"text"},{"type":"span","content":"more text"}]}]}'

var el = JSON.parse(json, function(k, v) {
  if (!v.type) return v
  
  var el = document.createElement(v.type)
  el.textContent = v.content
  
  for (k in v.attr || {})
    el.setAttribute(k, v.attr[k])
    
  for (var c of v.children || []) 
    el.append('\n', c)
    
  return el
})

document.body.innerHTML = el.outerHTML
console.log( el.outerHTML )

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.