Best practice for creating multiple HTML blocks dynamically [closed] - javascript

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed last year.
Improve this question
For context: My application has a scheduler and I want to display multiple appointment blocks (say a div as childs an image, text and a button), but this question can also be applicable for let's say product catalogs. What is the best practice for building the HTML content for those blocks?
In my search I found multiple options, for example (with pseudo code)
Build line by line in jQuery
$('<div />').append($('<img />')).append($('<p />').append($('<button />'));
Personally I found this option to become quite ugly once the block contains more than 3-5 elements, because the code started to span more than a full page of scrolling and became unreadable (but this could also be because of my poor coding skills).
Retrieve HTML page via Ajax/Load
<div>
<img><p></p><button></button>
</div>
$("target").load("page.php");
or
$.ajax({
url: "page.php",
success: function (response) {
$("target").append(response);
});
On the plus side this separates the content which reduces initial page loading time and the content can be built server side right before it is required, on the downside my server shows a delay of ~0.1s (on average, reproducable) for AJAX calls to return (with practically no data sent back and forth). Although this might seem insignificant in the end all small delays add up and can impact user experience.
Clone templates
<template>
<div>
<img><p></p><button></button>
</div>
</template>
const template = document.querySelector("template");
var tgt = document.getElementById("target");
node = document.importNode(template.content, true);
tgt.appendChild(node);
On the plus side this option is about 10-20x faster than the 1st option (build via jQuery), but that will only become noticable after ~1000 blocks which far exceeds my use case. On the down side this 'pollutes' the page HTML code and processing of the content into the object is required through JS anyways.
Which other viable options are out there? And what is the best practice for this use case?

Since you're not using SPA approach (an example explaining that: with angular). The best (cleanest/fastest) option (in my opinion) is to fully render the blocks from the server side (you're using PHP apparently). Meaning that you'll have a file defining a single block structure of an appointment 'appointment.php' which holds the template + rendering logic, this 'appointment.php' result (after rendering) then you'll be calling (loop) in the page you need it in, as many times as you wish and with the parameters you wish, for each instance of the appointments list you have

Related

Dynamically loading content on local HTML page [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
Context:
Basically I'm attaching a little HTML help doc to go with my program (not meant to be on a server, viewed locally). HTML just because I'm most comfortable in making docs in it but I also want it to have some interactivity/dynamic content which I can't do in a PDF or whatever.
I'm dynamically replacing the content when you click on a link instead of making every page need it's own HTML page, which is just something I'm used to doing so I can change the menu and banner and whatever else on a single 'main' html file without having to adjust every single other html file for one tiny change in the shared stuff.
Current Method:
Right now it's all done through javascript and jQuery. When a user clicks a link, I use jQuery's load() function to load the appropriate content (an html file) and replace the content div with what's in the loaded html file. Currently just using relative links. E.g. the core function is something like below:
$("#ContentBox").load("content/faq.html");
This actually worked a few weeks ago when I first wrote it. It's not like I built the whole thing and didn't test its core concept until just now. But now it seems all the browsers are blocking it. Chrome says:
XMLHttpRequest cannot load file:///C:/[....]/content/home.html. Cross origin requests are only supported for protocol schemes: http, data, chrome-extension, https, chrome-extension-resource. `
Question:
So I understand why it's happening as it's a potential security risk to allow that, I just want to figure a good way around it that still does what I want (if it's possible). I mean I could just preload all the content as huge string variables in the javascript file or as hidden divs that get turned on and off, but I was hoping for something a little more elegant.
And I can't expect all users of my program to setup a local web server just to view to help doc.
I've considered the File and FileReader classes but they require a user input for a lot of functions. There's also iFrames but that introduces all sorts of weirdness that needs to be accounted for and I hate iFrames.
If this is all local content then you should not be loading it via ajax. One option you have at your disposal is to set up your help files as local Javascript templates. You can then refer to them using a template library like mustache or underscore and link to them in your application like so:
<script type="text/template" src="local/helpfile.js" />
If you don't want to use a templating library then you can set up helpfile.js as JSON data, but you'll need to escape quote characters first.
If your help docs are to be viewed on a Windows machine only, you should look into using HTML Applications to get rid of the cross-origin issues. Or you can work around it by combining all of the source code files in hidden textareas. I've done it lol
To anyone still interested this is the solution I settled on as of now. At the end of the body are all the divs with the different page content styled like so:
<div id='PageName' class='content-div'>
<!-- content goes here -->
</div>
<div id='AnotherPage' class='content-div'>
<!-- content goes here -->
</div>
The id is important as that becomes the name of the page and the class type, which you can name whatever, I used to hide them with visibility:hidden; as well as gave it absolute positioning at 0,0 - just in case - so that they don't interact with other elements and screw up the layout.
On the page loading, along with a bunch of other functions, I store the elements into a javascript associative object by page name.
var content = {};
function onLoadThisGetsCalledSomewhere() {
// loop through all of those divs
$(".div-content").each(
function() {
// using $(this) to grab the div in the scope of the function here
var element = $(this).element;
var name = $(this).attr('id');
// remove it from the html (now it exists only in the content object)
element.detach();
// remove that style class that makes it invisible
element.removeClass('content-div');
// put it into memory
content[name] = element;
}
);
}
So when a link to another page is clicked, the onclick does something like switchPage(pageName) let's say.
function switchPage(requestedPage) :
// somewhat simplified, real version has case and null checks that take you to 404 page
var contentElement = content[requestedPage];
// replace content in some container div where you want content to go
$("#TheContentContainer").empty().append( contentElement );
// have to adjust size (width possibly too but I had a fixed width)
$("#TheContentContainer").height( contentElement.height() );
}
I'm not at the same computer so I'm writing all this up anew, not copy/pasting so there may be some bugs/typos (Caveat emptor - I'll fix it tomorrow). The version I used is somewhat more complicated as well since I have subpages as well as dynamically handled menu bar changes. Also features so that you can open the "links" correctly in new windows/tabs if such an action is made. But that's not important here now.
It's not too different I suppose with hidden divs (the benefit here is the detach() function to remove it from the html) or just storing long strings of html code in java vars (much more readable than that though), but I think it's advantage is is much cleaner (IMHO) and so far I like it. The one downside is with lots of pages you get one huge HTML doc that can be a pain to go through to edit one specific page but any decent editor should have a bookmark feature to make it a little easier to get to the line you're looking for. Also cause of that a bad idea if not local, but then again if it's online just use the jQuery load() function.

loading jQuery at the end of the page for mobile [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I've been told loading jQuery at the end of a page increases performance for mobile.
I don't believe this, however open for an explanation.
Regardless, is there any way to get jQuery calls at the beginning of the page to load only after jQuery has been loaded? I know of timeout work around but they seem inconsistent.
The reason why you get "better" performance is that the page will be parsed before it reaches JavaScript at the end of the document, and once a section is parsed, rendering can begin. By loading JavaScript at the end of the document, you let the basic hard-coded layout in your HTML and CSS appear before you add functionality with JavaScript. This gives the user the illusion of "faster loading time" for your page.
The caveat here is any JavaScript you want to use that will call on external libraries must occur after the libraries' script tags. This is not an issue if you have packed all of your code together into its own file, but it will cause trouble for inline scripts you have strewn about the page.
This is part of why such behavior is discouraged in production applications, the rest having to do with the ability to maximize compression of the script content with gzip and so on.

Effeciency, hidden HTML or JavaScript DOM appending?

I am working on a simple Cordova app with about 4 page types and I am trying to think through which is the better way to handle the inner HTML templates.
Hidden HTML hard coded into the HTML files that is hidden and populated/revealed by my JS.
Using a JS template system and appending and removing from the DOM.
I feel that appending all that to the DOM for a page is inefficient when I could just update the sections that change. But perhaps an append is lightweight enough where I shouldn't worry about it.
There are a number of ways you can do it. In terms of load on the browser. That is hard to say. From your question it is hard to know what is in these pages, what are you displaying, is it live data, static html etc.
When you first plot out an app, if you are from the old class of building multiple page websites, it can be a little concerning as to how well your app/page will run with all those pages crammed in to one, and all that data plus code.
The answer is, amazingly well. If done properly in modern browsers, and for example Ipads the app will run to near native performance.
The options you have are
Map all the pages into one HTML document. Hide each page content using css display:none, flip them into view using css animation, fading or just display:block.
Use a javascript routing library to map urls to blocks of code that deal with each page, this makes mapping out your app much easier, and means that buttons can just link to your pages, like a real website. see http://projects.jga.me/routie/
Building all the page templates into one page can make it hard to code, as the page becomes enormous, consider breaking the inner content of each page into separate files, you can then give each page holder a url and use a small xhr request to load the page on-the fly, once loaded you can cache it into memory or even local-storage, depending on whether you remove it when it is closed or keep it hidden.
In my experience you can put an enormous number or nodes into one page and have very little speed drop, bear in mind if you use something like jquery and do a lot of $(".page > .page1 > .items li") your going to have a slow app.
Tips
Use element ID's everywhere document.getElementById(..) is 100's of times faster in a loop that $(...)
cache elements when you find them, if you need them later store them in a memory cache.
keep for loop inner code to a minimum.
use a decent click touch libary like http://hammerjs.github.io/ and delegate all the events of the body tag or at least on each page.
If you need to touch the server, load data, think dom first, device second server later. A good app is a responsive app, that responds to the user instantly.
I know this has been posted a while ago, but for the sake of the users I am going to add my answer.
I completely agree with MartinWebb but my answer will shed some light on the results of his options. I am currently working on a similar project. Please note that this answer pertains to cordova (previously called phonegap) specifically. My app has about 5 pages with +-20 different components (input's, div's, h1's, p's, etc.). This is what i tried and the result of each:
jQuery was my first option, mainly because it is easy to use and reduces the amount of code required to accomplish a said goal. Result: First time I tried this approach I though I would spice it up with animations and transformations. The result of this was a very unresponsive app. I removed the animation and transformation, however due to the nature of my application I required multiple dynamically added components and jQuery just wasn't up for the task.
Css display:none and visible:hidden was my next option. I used javascript's dom to display certain div's. Result: This works if your not planning on switching many div shortly after one another eg. a simple menu. It quickly became apparent that this wasn't going to work. Also this does not eliminate my need for the dom. Remember document.getElementById('menu').style.display = "none"; is still part of the dom. This as a solution, for me, is poor. There is a reason that var menu= document.createElement('div'); is part of the language. Which brings me to my last option.
Building a page 90% on javascript's dom was my last option. Logically I could not see how 600 lines of code cold trump one .innerHTML or .style.display = "block"; but it did. Result: It was by far the most responsive of all the solutions.
I'm not saying that all webpages should be coded with dom appending, but as I stated previously, for a cordova app of a few pages (<6), with a few components a javascript dom appending approach would be best. It takes longer to code, but you will be rewarded with control and efficiency. I would suggest coding the backbone of your app in html and populating and controlling with javascript's dom.
Best of luck.
The first option, <div>s with display:none; would be more efficient by a small margin, but you can get the best of both worlds by compiling your JavaScript and templates together into a single file using something like browserify or require.js.

Is it good practice to create JavaScript objects on the basis of html5 data attribute values? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I am working on a small HTML/JavaScript application where a user can browse through different content without refreshing the page. I use divs as 'pages' by showing and hiding the divs as the user navigates through the application. Between two pages occurs a small animation (like fading or sliding). When the animation is finished and the 'page' is visible a trigger is fired.
Each page executes his own behavior when triggered (e.g. playing a video/animation/show some text). Each page(div) has his own JavaScript class linked to it. The Class name of the JavaScript class is stored in a data attribute called data-pageClass:
<div id="page1" class="pn-page intro" data-pageClass="IntroPage">
Page 1: introduction text
</div>
<div id="page2" class="pn-page page2" data-pageClass="VideoPage">
Page 2: playing a video here
</div>
The class handling the navigation creates the classes of the pages by looping through the html structure and using the data attribute to identify which class to create. I use the 'stringToFunction' function described in this question on StackOverflow
Looping code:
$("#pages .pn-page").each(function (i, el) {
var PageClass = stringToFunction(el.getAttribute("data-pageClass"));
var newPage = new PageClass(el);
_this.pages.push(newPage)
});
For simplicity's sake I left out all the other code. please let me know when it's unclear.
So my question is if it is bad practice to 'dynamically' create objects in this way. I thought it very useful to link divs to custom javascript classes (a bit like DOM does).
I believe that what you are doing is good practice. The data attribute is meant to be used to embed custom data on a page, which is exactly what you are doing. You should obviously take care that potential attackers will not be able to inject custom HTML into your page in order to affect your JavaScript code in malicious ways, but that is nothing new.
An alternative approach I have used in the past is use view classes that run on on both the server (NodeJS) and client side. The server and client side are both able to generate the HTML, and the client side is able to attach the generated objects to the HTML if it was already generated by the server. This saves you the littering of your HTML by inserting data attributes, but otherwise it is not that much different, and it might not be applicable in all situations.

Add just a </div> using JavaScript [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I'm going crazy! :)
I need a way to add a closing </div> before another element. But everything I try the </div> gets filtered out. The problem is, that this might be the only solution for me.
So please, please have a look to this and maybe you're able to give me a hint:
I'm building a bootstrap based template for LimeSurvey, a online survey tool. Their templates are completely done with tables and I try to find another way and to get it mobile friendly.
The template is separated into different files. For my issue this is:
-> Startpage
-> Navigator
-> Endpage
Normally it loads always a "Surveypage" between Startpage and Navigator. But there is an option which automatically puts all question directly under the startpage and therefore into my header. So in this case I need another '' or another way to close the header first.
So there's a
<div class="jumbotron">
and I have to close it before the element
<table id="ls-table" ... >
I already tried many JavaScript examples I've been able to find around the web. But none makes the job.
Thanks a lot!
Philipp
There are only two ways to manipulate a web page using JavaScript.
The DOM, or document object model.
Via string-manipulation of the HTML.
Most web browsers will NOT allow you to do #2 directly on an already-loaded or loading document. At best, you could find a situation wherein you read the HTML of a <body> and then re-parse it. But doing so is an amazing amount of work for very little effort.
Look into the insertBefore method on the DOM, which will let you grab that <table id="ls_table" > element and move it from within that <div> to being a child of said <div>'s parent, immediately after the offending element.

Categories

Resources