Infinite scrolling using AJAX, Javascript/jQuery, the DOM and Facebook Like button - javascript

I am preparing to implement a Twitter-like infinite scrolling to my product pages. That is, loading additional page portions using AJAX when I am crossing certain scroll thresholds. But I am unsure how the topics in the title are affected after such loading. My questions are the following:
For each new batch of elements being loaded with AJAX, will the DOM be updated for these new elements OR totally renewed? What happens with the old DOM?
Will I be able to use Javascript and jQuery on these new DOM elements exactly like I have on the DOM I start off with for the page? I guess this relates to the first question.
For each load, I will load say 9 new products. Each product has a FB Like button which is utilising FB Open Graph API. Will the new products Like elements go through the same asynchronous modification which happens to the DOM elements I start off with so that a proper Like submission is possible?

Let's begin one by one.
The DOM, in your intent, should only be updated, not renewed. There
is no old DOM since what you do is to insert new elements on them.
Yes, you'll be able to do that. Be careful though with event
listeners because if you start them wrong, you'll have to attach new
event listener to those new nodes again. For example:
$('body').on('click','a.addToCart',function(){}) // Will match present and future nodes
$('a.addToCart').on('click',function(){}); // Will only match present nodes
Yes, you'll need to do the same process for each button again.
Bonus tip: If you care about mobile environments, you should keep your DOM as clean as you can by deleting nodes you won't need.

Just use document.appendChild() for adding new Elements to the DOM. (http://www.w3schools.com/jsref/met_node_appendchild.asp)
Rebuilding the hole page would be a waste of time ;)
There should be no problem. I've done it many times without any problems. If you are using jQuery Mobile you have to refresh the new elements maybe. (Look at the methods of die jQuery Mobile Widget you are using, if it needs refreshing)
I don't have much experience with the facebook api, but i would say "yes" =)
edit: I had a link to a german site in my answer. I've forgot that this is an english site ;)

Related

Continue modifying DOM as user scrolls

I have a chrome extension that modifies the DOM based on keywords. The problem is, for websites like twitter that have an infinite scroll, I need a way for my function to keep firing as the user scrolls through the page.
Is .livequery() the only way to do this or is there a better way?
Right now all of the logic is plain JavaScript/Jquery, but I'm open to using a framework like Angular if that's the best way to do it.
I have several functions that interact -
1) a hide() function that adds a class to divs containing words I want hidden
2) a walk() function that walks the DOM and identifies divs to call hide() on
3) walkWithFilter() function that gets words to filter from localstorage and calls walk() function
The last function walkWithFilter() is called in a window.onload() event
It seems like the onScroll event would be a natural match for this. The trick would be that you'd need to keep track of what's already been processed to avoid reprocessing old content. If you're assuming that the user is always exposing new content below the existing content, that could be as simple as keeping a pointer to the last processed item and restarting the walkWithFilter method from there. That doesn't seem like an entirely safe assumption to me, though.
If you want to be more robust in that regard, you could try a virtual DOM approach: you maintain a copy of the DOM as you last saw it, compare it to the DOM as it currently exists, and take a diff. I know there are a bunch of premade libraries for this kind of thing, but I haven't used any and can't recommend a specific one (the link just goes to the first example that showed up in Google). It also doesn't appear to be overly burdensome to roll your own, if you're so inclined.

Single Page Application - Large DOM - SLOW

I'm developing a single page application that uses a lot of widgets (mainly grids and tabs) from the jqWidgets library that are all loaded upon page load. It's getting quite large and I've started to notice after using (I emphasize using because it doesn't start to lag after simply being open for any amount of time, but specifically, after opening and closing a bunch of tabs on my page, each tab containing multiple grids loaded thru Ajax that have multiple event listeners tied to each) the site for a couple minutes the UI becomes quite slow and sometimes non-responsive, when the page is refreshed everything works smooth again for a few minutes then back to laggy. I'm still testing on localhost. My initial reaction was that the DOM has too many elements (each grid creates hundreds of divs! And I have a lot of them) so event listeners which are tied to IDs have to search through too many elements and become slow. If this is the case it won't be too hard to fix, is my assumption likely to be the culprit or do I have worse things to fear?
UPDATE: here are captures of the memory time line and heap snapshot. On the memory timeline there was no interaction with the site, the two large increases are page refreshes, the middle saw tooth section is just letting my site idle.
Without seeing any code examples it doesn't sound too bad.
If you have a LOT of jQuery selectors try and make those specific as possible. Especially if you're selecting a lot of items a lot of the time.
For example, if you have a bunch of class "abc", try and specify before that where to look - e.g. are they only found within table cells? are they only found within paragraph tags? The more specific you make your selector the better as if you specify the selector like this:
$('.class')
Then it will search the entire DOM for anything that matches .class, however, if you specify it as follows: $('p .class') then it will only search all paragraph tags for the class.
Other performance killers are wiring up events and then never removing them. If you have any code that removes elements that have event handlers attached to them then best practice is to remove the event handlers when the element is removed. Otherwise you will start piling up orphaned events.
If you are doing a large single page application look to a library like backbone (http://backbonejs.org/) or angular (http://angularjs.org/) to see if this can help you - they alleviate a lot of these issues that people who use plain jQuery will run in to.
Finally, this post (http://coding.smashingmagazine.com/2012/11/05/writing-fast-memory-efficient-javascript/) is seriously good at outlining out you can write fast, efficient javascript and how to avoid the common performance pitfalls.
Hope this helps.
It does sound like you have a memory leak somewhere. Are you using recursion that's not properly controlled or do you have loops that could be ended early, but you fail to break out of them when you find something you're looking for before the loop naturally ends. Are you using something like this:
document.getElementById(POS.CurrentTableName + '-Menus').getElementsByTagName('td');
where the nodelist returned is huge and you only end up using a tiny bit of it. Those calls are expensive.
It could be your choice of architecture also. Hundreds of divs per grid doesn't sound manageable logically by a human brain. Do you address each div specifically by id or are they just an artifact of the lib you're using and are cluttering up the DOM? Have you checked the DOM itself as you're using it to see if you're adding elements in the hinterland by mistake and cluttering up the DOM with junk you don't use causing the DOM to grow continuously as you use the app. Are you adding the event handlers to the elements numerous times instead of just once?
For comparison, I too have a single page app (Google-Chrome App - Multi currency Restaurant Point of Sale) with anywhere from 1,500 to 20,000 event handlers registered making calls to a sqlite back end on a node.js server. I used mostly pure JS and all but 50 lines of the HTML is written in JS. I tie all the event handlers directly to the lowest level element responsible for the event. Some elements have multiple handlers (click, change, keydown, blur, etc).
The app operates at eye blink speed and stays that fast no matter how long its up. The DOM is fairly large and I regularly destroy and recreate huge portions of it (a restaurant table is cleared and recreated for the next sitting) including adding up to 1,500 event handlers per table. Hitting the CLEAR button and it refreshing the screen with the new table is almost imperceptible, admittedly on a high end processor. My development environment is Fedora 19 Linux.
Without being able to see your code, its a little difficult to say exactly.
If the UI takes a little bit before it starts getting laggy, then it sounds likely that you have a memory leak somewhere in your JavaScript. This happens quickly when using a lot of closures as well as nested function and variable references without cleaning them up when your done with them.
Also, event binding to many elements can be a huge drain on browser resources. If possible, try to use event delegation to lower the amount of elements listening to events. For example:
$('table').on('click','td', myEventHandler);
Be careful to make sure that event bindings only occur once as to avoid actions being unintentionally fired many times.
Good luck!

'Persistent' Javascript, like CSS

I have a few javascript functions that changes DOM elements, such as add classes, replace images, etc...
Now, sometimes a page will create a popup or will populate a navigation tree with some extra items without loading a new page. In that case the new element loaded will of course not be affected by my javascript.
For example. Say I give all images an extra class via javascript. Now the page generates a popup with some images in it, and then those images won't be affected by my javascript and the images in the popup won't get said class.
I was wondering if there is a way to make javascript behave like CSS - to be persistent or to work all the time, so that those new images will also be targeted by my scripts?
I hope that id clear :)
Thanks!
EDIT:
I will provide a bit more information here:
Say I have a simeple function like this:
$('.somediv').addClass( '.anotherclass' );
now this function is executed after the page loads.
Is there a way where I can automatically run this function again, when it is detected that a new div of class .somediv has been added to the DOM?
Whenever the new elements are dynamically added to the page you could call a javascript function that resets all the necessary classes and event bindings. Otherwise, if you know on the server-side what classes are necessary for these items you could send them over with the class already assigned to it.

Loading contents dynamically

I have product listing page, which displays all the products which satisfy the search criteria. And these could be any number of products.
What I want is something like FB, that I display only first 5-7 products and as the user scrolls down, the products should be loaded dynamically.
I'd consider switching to jQuery or Mootools as JS libraries if you want to do this - both have native support for the infinite scroller concept as it's commonly called. It's not that hard to implement yourself though, mainly a matter of keeping track what you loaded last, and installing an onScroll event to detect when the bottom of the page is reached.
Here's a good tutorial using native JS to implement it, both server and client side. You'll need to replace the XHR invocations by the proper Prototype alternatives yourself (or not, wouldn't really matter).

AJAX - Element / Class / Timer cleanup on replacing content

As many developers will be I'm producing web based application that are using AJAX to retrieve data and HTML.
I'm new to web development and javascript but have a couple of decades experience in programming in other languages.
I'm using mootools, which is a great framework, but have been battleing with the lack of destructors in javascript or even onDestroys/ unloads for the dom elements.
I've written a number of UI classes ( mostly to learn ) and alot of them use setInterval timers to periodically get data from the WebServer and update elements on the page (mostly images from cameras).
Most issue occur when another page is requested with the menu and the content div is reloaded with new HTML and Javascript ( using Request.HTML ). This simple replaces all the elements already in the div with the new one and runs the new scripts. Any timers in the old scripts or old objects created will continue to run. This was leaving me with lots of orphaned Clases, elements and timers.
I've been reading more on the mootools site and have realized a number of mistakes I've been making and have started to correct alot of the issues. The biggest of which was not using Element.store and Element.retrieve instead of linking my classes directly to the Elements.
I've already found that the contents of the div being reloaded need to be freed by calling destroy on all its child elements before calling the Request.HTML but that will not remove (clear) any timers that are running.
So I've done a JSFiddle here deinitialize classes to show what i've been trying, its appears to work fine but the following and what i want to know is,
Is it a good idea?
are there any other issues I might have missed?
can you see any problem with this type of implementation ?
or am I reinventing the wheel and missed
something?
Explanation
When the class is initialized it stores itself with the element.
It also appendes (makes if necessary) itself into an AssocClasses array also stored with the element.
I've created a ClearElement function that is called whenever the contents of an element are to be replace with and AJAX call or other method, which gets all elements within the div and if they have and AssocClasses array attached, calls the deinitialize on each of the Classes in the array, then it calls destroy on each of its direct children to free the elements/storage.
Any information, pointers etc would be most greatfully recieved.
Most issue occur when another page is requested with the menu and the content div is reloaded with new HTML and Javascript ( using Request.HTML ). This simple replaces all the elements already in the div with the new one and runs the new scripts. Any timers in the old scripts or old objects created will continue to run. This was leaving me with lots of orphaned Clases, elements and timers.
I would rethink your timer storage and use of evalScripts in your ajax calls.
Keep these outside of your AJAX requests. When doing peer code reviews rarely have I seen an instance where these were needed and could be done in a better way.
Maybe on the link that is clicked have it trigger a callback function on Complete or onSuccess
Without seeing your exact code it will be hard to advise further.

Categories