1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
This was an okay approach and worked for quite a while but we were still having to do things like this all over the site where we wanted to use this method:
1 2 3 4 5 6 7 8 9 10
I started drinking the jQuery Kool-Aid a while back and was doing some prototyping and trying to find more intricate solutions to help reduce the amount of script we had littered across the site. I had my ah-ha moment while doing some research into the jQuery Widget framework.
I wanted to create a widget that would allow us to load content via ajax without having to write a lot of additional script code. I needed a way to be able to indicate what url, params and target div to render the content to in the event that we want the load of some thing to trigger ajax to be loaded into another div. To solve the first problem I started looking into is jQuery’s support of the HTML 5 data attributes.
By adding items such asand using the jQuery.attr(“data-controller”) I am able to retrieve the value. We played around with just using the jQuery.data(“controller”), but jQuery seemed to only like to find the data-controller attribute when it was added via the jQuery.data(“controller”,“value”) (This is something I want to play around with more going forward).
The ui.lazyload.js Widget:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
This basically takes any item with a class of “lazy-load” and attempts to load the content via ajax. The only requirement is that you define the data objects in the html tag such as the following:
1 2 3 4 5 6 7
Since we use Spring MVC we are invoking our urls like the following /url/url.url?action=doWork. This could all be combined into the data- controller attribute, but for clarity of invocation we split them up as separate items. The target of “this” is assumed if the data-target isn’t provided. If we needed to add params to the ajax call we could add a data- params=“foo=bar” and the resulting url would be invoked as /url/url.url?action=doWork&foo=bar where foo=bar is passed to the jQuery ajax method in the data parameter.
before – execute the [function] before calling the ajax method on the object complete – execute the [function] after calling the ajax method on the object regardless of status success – execute the [function] after calling the ajax method on the object on success error – execute the [function] after calling the ajax method on the object on error
Also if people really want to customize how the item loads they could skip adding the class of lazy-load and the ajax call will not happen on load. Instead they can do something like:
1 2 3 4 5
This will bind a click event with a name-space of lazy-load (which will be auto unbound after click via widget) to the object with id=“one”. I wanted to unbind the click event so I used the name-space, but if the user were to simply bind(‘click’,…); instead, it would not unbind the event and the ajax would get invoked on every click.
When we are crossing multiple object boundaries and controls we have to be conscious as to which object we add the data attributes to and which objects have events that invoke the lazy-load. The object with the .lazyload() invoked must have the data attributes on it. You can bind an even to another object, but it will not get unbound unless you added support for that via the complete event.
1 2 3 4 5 6
That code would lazy-load id=“one” when clicking on id=“two” and unbind the click event after complete. Perhaps using the before event would be better to stop the multiple invocation of the ajax get.