how to lazyload anything - javascript

I know able to lazy load 'image' using some third party jquery library. Is there anyway to lazy load just about anything like <div> element container for example when user scroll to that <div> container

To expand on kinsho's (correct) answer:
For security and maintainability reasons, you should be wary of injecting raw HTML directly into documents. Doing so can break event listeners, break the DOM parser, and potentially open up security vulnerabilities.
Usually, the best way to lazy load stuff is to send encoded data (such as JSON or XML) to the client, and process the result accordingly. For basic HTML, a templating solution could be used. Even an iframe can be better than pasting <div><h1>Hello</h1><table><tbody><td><tr>1</td></tr><tr><td>2</td></tr></tbody></table></div>* into an element's innerHTML.
Also, before you implement lazy loading for your site, take some time to consider if it's really worth it. An additional HTTP request is noticeably more expensive than just downloading data all at once, and any HTML injected via Javascript will not be seen by web search crawlers. So, if you're only injecting a small amount of static information, it really isn't worth the trouble.
*can you find the parse error? Now imagine doing that for a standard-sized HTML document.

Why rely on some third-party library to help you lazy-load? You can do just fine using native JavaScript.
In fact, as long as you accept the principle that all lazy-loading is triggered by some user action, set up a listener on a specific object (be it the scroll bar, some section header, etc). Set up a corresponding handler that relies on AJAX (you can use jQuery here) to fetch data (preferably HTML) that you can load directly into whatever container you want using the innerHTML property of the container element.

Here is what you really wanted to begin with. It is a new jQuery plugin that I made myself. You can "Lazy Load" anything you want based on any element (jQuery selector) you wish.
https://github.com/shrimpwagon/jquery-lazyloadanything

Related

Inserting user provided content into a document--validating HTML string, insertAdjacentHTML and iframe usage?

If I want to accept HTML built by a user of an extension, and not from a web source, and display it within an existing extension document, is there an alternative to using an iframe?
For example, if a user provides mathematical expresions using MathML and they are to be displayed in the current web page, and the user may add a <div> or <p> tag inaccurately and have incomplete HTML, how can it be added to the page without corrupting the layout of the page, apart from an iframe?
Does insertAdjacentHTML really accomplish this? This MDN article seems to imply so, where it reads, "It does not reparse the element it is being used on, and thus it does not corrupt the existing elements inside that element."
Or, is there a way to validate the HTML string before inserting into the DOM, such as DOMParser?
Also, for users that are knowledgeable in HTML, CSS, JS and can construct a small interactive document rather than just an expression, to be dislayed within the page, is an iframe the only option? The user provided code will be stored in indexedDB and rendered only on the user's machine and within this extension tool. So, something similar to a snippet on stackoverflow. I have this working in an iframe now but the user could add about a dozen of these to the page at any one time and I wondered if there is a better way of accomplishing this, regarding memory usage and in general.
Thank you.

Serialization of the full page DOM. Can I get at the JS code that is loaded up, or must I AJAX it separately?

I have a bug I'm trying to track down, and it is very difficult to do so because of the complexity of the web app. There are many frames, and many instances of Javascript code that is embedded into the HTML in different ways.
The thing that needs to be fixed is a sub-page created with showModalDialog (so you already know it's going to be a disaster), and I am hoping that I can find a way to serialize as much of the DOM as possible within this dialog page context, so that I may open it to the same content both when the bug is present and when it is not, in hopes of detecting missing/extra/different Javascript, which would become apparent by pumping the result through a diff.
I tried jQuery(document).children().html(). This gets a little bit of the way there (it's able to serialize one of the outer <script> tags!) but does not include the contents of the iframe (most of the page content is about 3 iframe/frame levels deep).
I do have a custom script which I'm very glad I made, as it's able to walk down into the frame hierarchy recursively, so I imagine I can use .html() in conjunction with that to obtain my "serialization" which I can then do some manual checking to see if it matches up with what the web inspector tells me.
Perhaps there exists some flag I can give to html() to get it to recurse into the iframes/frames?
The real question, though, is about how to get a dump of all the JS code that is loaded in this particular page context. Because of the significant server-side component of this situation, javascript resources can be entirely dynamic and therefore should also be checked for differences. How would I go about (in JS on the client) extracting the raw contents of a <script src='path'> tag to place into the serialization? I can work around this by manually intercepting these resources but it would be nice if everything can go into one thing for use with the diff.
Is there no way to do this other than by separately re-requesting those JS resources (not from script tags) with ajax?

Best way to execute Javascript on an anchor

Generally, there are 3 ways (that I am aware of) to execute javascript from an <a/> tag:
1) Use onclick():
hello
2) Directly link:
hello
3) Or attach externally:
// In an onload event or similar
document.getElementById('hello').onclick = window.alert('Hello');
return false;
<a id="hello" href="#">hello</a>
I am actually loading the link via AJAX, so #3 is basically out. So, is it better to do #1 or #2 or something completely different? Also, why? What are the pitfalls that I should be aware of?
Also of note, the anchor really doesn't link anywhere, hence the href="#", I am using a so the styles conform as this is still an object to be clicked and a button is inappropriate in the context.
Thanks
If you are loading the content via ajax and need to hook up event handlers, then you have these choices:
Put a javascript handler in your HTML with your option 1) or 2). In my mind option 1) is a cleaner way of specifying it, but I don't think there's a mountain of difference between 1) or 2) - they both do essentially the same thing. I'm not a fan of this option in general because I think there's value in keeping the markup and the code separate.
After loading the content with ajax, call some local code that will find and hook up all the links. This would be the same kind of code you would have in your page and execute on DOMReady if the HTML had been static HTML in your page. I would use addEventListener (falling back to attachEvent) to hook up this way as it more cleanly allows multiple listeners for a single object.
Call some code after you load the content with ajax that finds all the links and hooks up the clicks to some generic click handler that can then examine meta data in the link and figure out what should be done on that click based on the meta data. For example, this meta data could be attributes on the clicked link.
When you load the content, also load code that can find each link individually and hook up an appropriate event handler for each link much the way one would do it if the content was just being loaded in a regular page. This would meet the desire of separating HTML from JS as the JS would find each appropriate link and hook up an event handler for it with addEventListener or attachEvent.
Much like jQuery .live() works, hook up a generic event handler for unhandled clicks on links at the document level and dispatch each click based on some meta data in the link.
Run some code that uses an actual framework like jQuery's .live() capability rather than building your own capability.
Which I would use would depend a little on the circumstances.
First of all, of your three options for attaching an event handler, I'd use a new option #4. I'd use addEventListener (falling back to attachEvent for old versions of IE) rather than assigning to onclick because this more cleanly allows for multiple listeners on an item. If it were me, I'd be using a framework (jQuery or YUI) that makes the cross browser compatibility invisible. This allows complete separation of HTML and JS (no JS inline with the HTML) which I think is desirable in any project involving more than one person and just seems cleaner to me..
Then, it's just a question for me for which of the options above I'd use to run the code that hooks up these event listeners.
If there were a lot of different snippets of HTML that I was dynamically loading and it would be cleaner if they were all "standalone" and separately maintainable, then I would want to load both HTML and relevant code at the same time so have the newly loaded code handle hooking up to it's appropriate links.
If a generic standalone system wasn't really required because there were only a few snippets to be loaded and the code to handle them could be pre-included in the page, then I'd probably just make a function call after the HTML snippet was loaded via ajax to have the javascript hook up to the links in the snippet that had just been loaded. This would maintain the complete separation between HTML and JS, but be pretty easy to implement. You could put some sort of key object in each snippet that would identify which piece of JS to call or could be used as a parameter to pass to the JS or the JS could just examine the snippet to see which objects were available and hook up to whichever ones were present.
Number 3 is not "out" if you want to load via AJAX.
var link = document.createElement("a");
//Add attributes (href, text, etc...)
link.onclick = function () { //This has to be a function, not a string
//Handle the click
return false; //to prevent following the link
};
parent.appendChild(link); //Add it to the DOM
Modern browsers support a Content Security Policy or CSP. This is the highest level of web security and strongly recommended if you can apply it because it completely blocks all XSS attacks.
The way that CSP does this is disabling all the vectors where a user could inject Javascript into a page - in your question that is both options 1 and 2 (especially 1).
For this reason best practice is always option 3, as any other option will break if CSP is enabled.
I'm a firm believer of separating javascript from markup. There should be a distinct difference, IMHO, between what is for display purposes and what is for execution purposes. With that said, avoid using onclick attribute and embedding javascript:* in a href attribute.
Alternatives?
You can include javascript library files using AJAX.
You can setup javascript to look for changes in the DOM (i.e. if it's a "standard task", make the anchor use a CSS class name that can be used to bind a specific mechanism when it's later added dynamically. (jQuery does a great job at this with .delegate()))
Run your scripts POST-AJAX call. (Bring in the new content, then use javascript to [re]bind the functionality) e.g.:
function ajaxCallback(content){
// add content to dom
// search within newly added content for elements that need binding
}

How to dynamically add a Javascript function (and invoke)

Based on a click event on the page, via ajax I fetch a block of html and script, I am able to take the script element and append it to the head element, however WebKit based browsers are not treating it as script (ie. I cannot invoke a function declared in the appended script).
Using the Chrome Developer Tools I can see that my script node is indeed there, but it shows up differently then a script block that is not added dynamically, a non-dynamic script has a text child element and I cannot figure out a way to duplicate this for the dynamic script.
Any ideas or better ways to be doing this? The driving force is there is potentially a lot of html and script that would never be needed unless a user clicks on a particular tab, in which case the relevant content (and script) would be loaded. Thanks!
You could try using jQuery... it provides a method called .getScript that will load the JavaScript dynamically in the proper way. And it works fine in all well known browsers.
How about calling eval() on the content you receive from the server? Of course, you have to cut off the <script> and </script> parts.
If you're using a library like jQuery just use the built-in methods for doing this.
Otherwise you'd need to append it to the document rather than the head like this:
document.write("<scr" + "ipt type=\"text/javascript\" src=\"http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js\"></scr" + "ipt>");
In all honesty, I have no idea why the script tag is cut like that, but a lot of examples do that so there's probably a good reason.
You'll also need to account for the fact that loading the script might take quite a while, so after you've appended this to the body you should set up a timer that checks if the script is loaded. This can be achieved with a simple typeof check on any global variable the script exports.
Or you could just do an eval() on the actual javascript body, but there might be some caveats.
Generally speaking though, I'd leave this kind of thing up to the browser cache and just load the javascript on the page that your tabs are on. Just try not to use any onload events, but rather call whatever initializers you need when the tab is displayed.

How to implement an Enterprise-grade JavaScript "framework" for web designers?

I have been tasked with improving the current mess that is our JavaScript "strategy"; we're an online shopping company and my boss has given me time to do this properly. He is very keen on keepin this modular and increase the reusability of the components.
Our HTML is being rendered with JSP and we have lots of custom tags writing out, for example, information about products without the web designers needing to worry about it.
Now, we want to do similar things with JavaScript. The web designers should be given a set of custom tags, like, say,
<foo:draggable>
... some HTML here ...
</foo:draggable>
that will wrap the HTML in a <div> with a drag bar at the top and a close button.
My idea is to mark the div with a unique namespaced CSS class name, like foo_draggable, and then put all my functions in a single JS file. That JS file then sees if there are elements with the CSS class foo_draggable in the DOM and if it finds any it will attach the required event handlers.
However, I am worried about scaling problems, and wondering whether it is a good idea to have lots of selector queries running when they quite often aren't going to be used.
The first alternative would be to initiate each draggable item explicitly but that would mean putting <script> tags all over the place. The second approach would be to not put all UI function in one file but rather just download the ones I need, but that would mean lots more HTTP requests and slower page load speed.
Has anyone got experience with this?
What about having two classnames?
<div class='foo fooDragable'></div>
<div class='foo fooSortable'></div>
You add the class 'foo' to all your elements that require javascript modification.
Your javascript has to check the dom only once for foo.
var $foo = $('.foo');
Afterwards you can search within this array which should be way smaller than the complete dom.
var $dragAble = $foo.filter('.fooDragable');
Have you considered or taken a look to JSF? I know it's a major change if you aren't using JSF yet. But there are lot of ready-to-use JSF component libaries with an ajaxical sauce, for example RichFaces, IceFaces, PrimeFaces, etc. It's almost a waste of time to create components/tags for it yourself.
Alternatively you can replace all Javascripts to use the great jQuery JS framework.
Depending on how many separate components you have, the extra overhead of running the selectors might not be a big deal. You can initialize all the components just the once, when the page is loaded. Anything that's not present on the page simply won't get initialized, and will incur no further overhead. In most JavaScript frameworks, selecting by classname (or tag name) is pretty fast. It's only the complex selectors, which aren't natively supported by the browser, that are slow.
If you have a few commonly used components, and then a set of less commonly used ones, it may be worth splitting those up. Keep the commonly used components in a single JavaScript file (minified, served with compression and aggressive caching), and load that in every page, regardless of whether it's needed or not. Caching will ensure it's only downloaded once, and it'll only be one small HTTP request. For the less common components, keep them in separate files (ideally, one per component), and add a script tag on pages that use them.
I'm not entirely familiar with how JSP works, but it might be possible to do this automatically - if a tag is included in the document, add a script tag for foo_widget.js in the document header, or something like that.

Categories

Resources