/hippo/src/main/webapp/yui/imageloader/imageloader.js

http://hdbc.googlecode.com/ · JavaScript · 481 lines · 171 code · 46 blank · 264 comment · 36 complexity · 2d71f67e9892c85aa64290f49f746245 MD5 · raw file

  1. /*
  2. Copyright (c) 2009, Yahoo! Inc. All rights reserved.
  3. Code licensed under the BSD License:
  4. http://developer.yahoo.net/yui/license.txt
  5. version: 2.7.0
  6. */
  7. /**
  8. * The image loader is a framework to dynamically load images
  9. * according to certain triggers, enabling faster load times
  10. * and a more responsive UI.
  11. *
  12. * @module imageloader
  13. * @namespace YAHOO.util
  14. */
  15. if (typeof(YAHOO.util.ImageLoader) == 'undefined') {
  16. YAHOO.util.ImageLoader = {};
  17. }
  18. /**
  19. * A group for images. A group can have one time limit and a series of triggers. Thus the images belonging to this group must share these constraints.
  20. * @class YAHOO.util.ImageLoader.group
  21. * @requires YAHOO.util.Dom
  22. * @requires YAHOO.util.Event
  23. * @constructor
  24. * @param {String|HTMLElement} trigEl The HTML element id or reference to assign the trigger event to. Can be null for no trigger
  25. * @param {String} trigAct The type of event to assign to trigEl. Can be null for no trigger
  26. * @param {Number} timeout Timeout (time limit) length, in seconds. Can be undefined, or <= 0, for no time limit
  27. */
  28. YAHOO.util.ImageLoader.group = function(trigEl, trigAct, timeout) {
  29. /**
  30. * Name for the group. Only used to identify the group in logging statements
  31. * @property name
  32. * @type String
  33. */
  34. this.name = 'unnamed';
  35. /**
  36. * Collection of images registered with this group
  37. * @property _imgObjs
  38. * @private
  39. * @type Object
  40. */
  41. this._imgObjs = {};
  42. /**
  43. * Timeout (time limit) length, in seconds
  44. * @property timeoutLen
  45. * @type Number
  46. */
  47. this.timeoutLen = timeout;
  48. /**
  49. * Timeout object to keep a handle on the time limit
  50. * @property _timeout
  51. * @private
  52. * @type Object
  53. */
  54. this._timeout = null;
  55. /**
  56. * Collection of triggers for this group.
  57. * Keeps track of each trigger's element, event, and event-listener-callback "fetch" function
  58. * @property _triggers
  59. * @private
  60. * @type Array
  61. */
  62. this._triggers = [];
  63. /**
  64. * Collection of custom-event triggers for this group.
  65. * Keeps track of each trigger's event object and event-listener-callback "fetch" function
  66. * @property _customTriggers
  67. * @private
  68. * @type Array
  69. */
  70. this._customTriggers = [];
  71. /**
  72. * Flag to check if images are above the fold. If foldConditional is true, the group will check each of its image locations at page load. If any part of the image is within the client viewport, the image is displayed immediately
  73. * @property foldConditional
  74. * @type Boolean
  75. */
  76. this.foldConditional = false;
  77. /**
  78. * Class name that will identify images belonging to the group. This class name will be removed from each element in order to fetch images.
  79. * This class should have, in its CSS style definition, "background:none !important;"
  80. * @property className
  81. * @type String
  82. */
  83. this.className = null;
  84. /**
  85. * HTML elements having the class name that is associated with this group
  86. * Elements are stored during the _foldCheck function and reused later during the fetch function. Gives a slight performance improvement when className and foldConditional are both used
  87. * @property _classImageEls
  88. * @private
  89. * @type Array
  90. */
  91. this._classImageEls = null;
  92. // add a listener to set the time limit in the onload
  93. YAHOO.util.Event.addListener(window, 'load', this._onloadTasks, this, true);
  94. // add the trigger
  95. this.addTrigger(trigEl, trigAct);
  96. };
  97. /**
  98. * Adds a trigger to the group. Call this with the same style as YAHOO.util.Event.addListener
  99. * @method addTrigger
  100. * @param {String|HTMLElement} trigEl The HTML element id or reference to assign the trigger event to
  101. * @param {String} trigAct The type of event to assign to trigEl
  102. */
  103. YAHOO.util.ImageLoader.group.prototype.addTrigger = function(trigEl, trigAct) {
  104. if (! trigEl || ! trigAct) {
  105. return;
  106. }
  107. /* Need to wrap the fetch function. Event Util can't distinguish prototyped functions of different instantiations
  108. * Leads to this scenario: groupA and groupZ both have window-scroll triggers. groupZ also has a 2-sec timeout (groupA has no timeout).
  109. * groupZ's timeout fires; we remove the triggers. The removeListener call finds the first window-scroll event with Y.u.IL.p.fetch, which is groupA's.
  110. * groupA's trigger is removed and never fires, leaving images unfetched
  111. */
  112. var wrappedFetch = function() {
  113. this.fetch();
  114. };
  115. this._triggers.push([trigEl, trigAct, wrappedFetch]);
  116. YAHOO.util.Event.addListener(trigEl, trigAct, wrappedFetch, this, true);
  117. };
  118. /**
  119. * Adds a custom event trigger to the group.
  120. * @method addCustomTrigger
  121. * @param {Object} event A YAHOO.util.CustomEvent object
  122. */
  123. YAHOO.util.ImageLoader.group.prototype.addCustomTrigger = function(event) {
  124. // make sure we're dealing with a CustomEvent object
  125. if (! event || ! event instanceof YAHOO.util.CustomEvent) {
  126. return;
  127. }
  128. // see comment in addTrigger()
  129. var wrappedFetch = function() {
  130. this.fetch();
  131. };
  132. this._customTriggers.push([event, wrappedFetch]);
  133. event.subscribe(wrappedFetch, this, true);
  134. };
  135. /**
  136. * Setup to do in the window's onload
  137. * Initiates time limit for group; executes the fold check for the images
  138. * @method _onloadTasks
  139. * @private
  140. */
  141. YAHOO.util.ImageLoader.group.prototype._onloadTasks = function() {
  142. if (this.timeoutLen && typeof(this.timeoutLen) == 'number' && this.timeoutLen > 0) {
  143. this._timeout = setTimeout(this._getFetchTimeout(), this.timeoutLen * 1000);
  144. }
  145. if (this.foldConditional) {
  146. this._foldCheck();
  147. }
  148. };
  149. /**
  150. * Returns the group's fetch method, with the proper closure, for use with setTimeout
  151. * @method _getFetchTimeout
  152. * @return {Function} group's fetch method
  153. * @private
  154. */
  155. YAHOO.util.ImageLoader.group.prototype._getFetchTimeout = function() {
  156. var self = this;
  157. return function() { self.fetch(); };
  158. };
  159. /**
  160. * Registers a background image with the group
  161. * @method registerBgImage
  162. * @param {String} domId HTML DOM id of the image element
  163. * @param {String} url URL for the image
  164. * @return {Object} bgImgObj that was registered, for modifying any attributes in the object
  165. */
  166. YAHOO.util.ImageLoader.group.prototype.registerBgImage = function(domId, url) {
  167. this._imgObjs[domId] = new YAHOO.util.ImageLoader.bgImgObj(domId, url);
  168. return this._imgObjs[domId];
  169. };
  170. /**
  171. * Registers a src image with the group
  172. * @method registerSrcImage
  173. * @param {String} domId HTML DOM id of the image element
  174. * @param {String} url URL for the image
  175. * @param {Int} width pixel width of the image - defaults to image's natural size
  176. * @param {Int} height pixel height of the image - defaults to image's natural size
  177. * @return {Object} srcImgObj that was registered, for modifying any attributes in the object
  178. */
  179. YAHOO.util.ImageLoader.group.prototype.registerSrcImage = function(domId, url, width, height) {
  180. this._imgObjs[domId] = new YAHOO.util.ImageLoader.srcImgObj(domId, url, width, height);
  181. return this._imgObjs[domId];
  182. };
  183. /**
  184. * Registers an alpha-channel-type png background image with the group
  185. * @method registerPngBgImage
  186. * @param {String} domId HTML DOM id of the image element
  187. * @param {String} url URL for the image
  188. * @param {Object} ailProps The AlphaImageLoader properties to be set for the image
  189. * Valid properties are 'sizingMethod' and 'enabled'
  190. * @return {Object} pngBgImgObj that was registered, for modifying any attributes in the object
  191. */
  192. YAHOO.util.ImageLoader.group.prototype.registerPngBgImage = function(domId, url, ailProps) {
  193. this._imgObjs[domId] = new YAHOO.util.ImageLoader.pngBgImgObj(domId, url, ailProps);
  194. return this._imgObjs[domId];
  195. };
  196. /**
  197. * Displays the images in the group
  198. * @method fetch
  199. */
  200. YAHOO.util.ImageLoader.group.prototype.fetch = function() {
  201. clearTimeout(this._timeout);
  202. // remove all listeners
  203. for (var i=0, len = this._triggers.length; i < len; i++) {
  204. YAHOO.util.Event.removeListener(this._triggers[i][0], this._triggers[i][1], this._triggers[i][2]);
  205. }
  206. // remove custom event subscriptions
  207. for (var i=0, len = this._customTriggers.length; i < len; i++) {
  208. this._customTriggers[i][0].unsubscribe(this._customTriggers[i][1], this);
  209. }
  210. // fetch whatever we need to by className
  211. this._fetchByClass();
  212. // fetch registered images
  213. for (var id in this._imgObjs) {
  214. if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
  215. this._imgObjs[id].fetch();
  216. }
  217. }
  218. };
  219. /**
  220. * Checks the position of each image in the group. If any part of the image is within the client viewport, shows the image immediately.
  221. * @method _foldCheck
  222. * @private
  223. */
  224. YAHOO.util.ImageLoader.group.prototype._foldCheck = function() {
  225. var scrollTop = (document.compatMode != 'CSS1Compat') ? document.body.scrollTop : document.documentElement.scrollTop;
  226. var viewHeight = YAHOO.util.Dom.getViewportHeight();
  227. var hLimit = scrollTop + viewHeight;
  228. var scrollLeft = (document.compatMode != 'CSS1Compat') ? document.body.scrollLeft : document.documentElement.scrollLeft;
  229. var viewWidth = YAHOO.util.Dom.getViewportWidth();
  230. var wLimit = scrollLeft + viewWidth;
  231. for (var id in this._imgObjs) {
  232. if (YAHOO.lang.hasOwnProperty(this._imgObjs, id)) {
  233. var elPos = YAHOO.util.Dom.getXY(this._imgObjs[id].domId);
  234. if (elPos[1] < hLimit && elPos[0] < wLimit) {
  235. this._imgObjs[id].fetch();
  236. }
  237. }
  238. }
  239. // and by class
  240. if (this.className) {
  241. this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
  242. for (var i=0, len = this._classImageEls.length; i < len; i++) {
  243. var elPos = YAHOO.util.Dom.getXY(this._classImageEls[i]);
  244. if (elPos[1] < hLimit && elPos[0] < wLimit) {
  245. YAHOO.util.Dom.removeClass(this._classImageEls[i], this.className);
  246. }
  247. }
  248. }
  249. };
  250. /**
  251. * Finds all elements in the Dom with the class name specified in the group. Removes the class from the element in order to let the style definitions trigger the image fetching
  252. * @method _fetchByClass
  253. * @private
  254. */
  255. YAHOO.util.ImageLoader.group.prototype._fetchByClass = function() {
  256. if (! this.className) {
  257. return;
  258. }
  259. // this._classImageEls may have been set during _foldCheck
  260. if (this._classImageEls === null) {
  261. this._classImageEls = YAHOO.util.Dom.getElementsByClassName(this.className);
  262. }
  263. YAHOO.util.Dom.removeClass(this._classImageEls, this.className);
  264. };
  265. /**
  266. * Base class for image objects to be registered with the groups
  267. * @class YAHOO.util.ImageLoader.imgObj
  268. * @constructor
  269. * @param {String} domId HTML DOM id of the image element
  270. * @param {String} url URL for the image
  271. */
  272. YAHOO.util.ImageLoader.imgObj = function(domId, url) {
  273. /**
  274. * HTML DOM id of the image element
  275. * @property domId
  276. * @type String
  277. */
  278. this.domId = domId;
  279. /**
  280. * URL for the image
  281. * @property url
  282. * @type String
  283. */
  284. this.url = url;
  285. /**
  286. * Pixel width of the image. Will be set as a "width" attribute after the image is fetched.
  287. * Detaults to the natural width of the image.
  288. * Only appropriate with src images
  289. * @property width
  290. * @type Int
  291. */
  292. this.width = null;
  293. /**
  294. * Pixel height of the image. Will be set as a "height" attribute after the image is fetched.
  295. * Detaults to the natural height of the image.
  296. * Only appropriate with src images
  297. * @property height
  298. * @type Int
  299. */
  300. this.height = null;
  301. /**
  302. * Whether the style.visibility should be set to "visible" after the image is fetched.
  303. * Used when setting src images as visibility:hidden prior to image fetching
  304. * @property setVisible
  305. * @type Boolean
  306. */
  307. this.setVisible = false;
  308. /**
  309. * Whether the image has already been fetched. In the case of a foldCondional group, keeps track for when the trigger is fired so images aren't fetched twice
  310. * @property _fetched
  311. * @type Boolean
  312. * @private
  313. */
  314. this._fetched = false;
  315. };
  316. /**
  317. * Displays the image; puts the URL into the DOM
  318. * @method fetch
  319. */
  320. YAHOO.util.ImageLoader.imgObj.prototype.fetch = function() {
  321. if (this._fetched) {
  322. return;
  323. }
  324. var el = document.getElementById(this.domId);
  325. if (! el) {
  326. return;
  327. }
  328. this._applyUrl(el);
  329. if (this.setVisible) {
  330. el.style.visibility = 'visible';
  331. }
  332. if (this.width) {
  333. el.width = this.width;
  334. }
  335. if (this.height) {
  336. el.height = this.height;
  337. }
  338. this._fetched = true;
  339. };
  340. /**
  341. * Inserts the image URL into the DOM so that the image is displayed.
  342. * Must be overridden by child class
  343. * @method _applyUrl
  344. * @param {Object} el HTML DOM element
  345. * @private
  346. */
  347. YAHOO.util.ImageLoader.imgObj.prototype._applyUrl = function(el) {
  348. };
  349. /**
  350. * Background image object. A background image is one whose URL is specified by "background-image" in the element's style
  351. * @class YAHOO.util.ImageLoader.bgImgObj
  352. * @constructor
  353. * @extends YAHOO.util.ImageLoader.imgObj
  354. * @param {String} domId HTML DOM id of the image element
  355. * @param {String} url URL for the image
  356. */
  357. YAHOO.util.ImageLoader.bgImgObj = function(domId, url) {
  358. YAHOO.util.ImageLoader.bgImgObj.superclass.constructor.call(this, domId, url);
  359. };
  360. YAHOO.lang.extend(YAHOO.util.ImageLoader.bgImgObj, YAHOO.util.ImageLoader.imgObj);
  361. /**
  362. * Inserts the image URL into the DOM so that the image is displayed.
  363. * Sets style.backgroundImage
  364. * @method _applyUrl
  365. * @param {Object} el HTML DOM element
  366. * @private
  367. */
  368. YAHOO.util.ImageLoader.bgImgObj.prototype._applyUrl = function(el) {
  369. el.style.backgroundImage = "url('" + this.url + "')";
  370. };
  371. /**
  372. * Source image object. A source image is one whose URL is specified by a src attribute in the DOM element
  373. * @class YAHOO.util.ImageLoader.srcImgObj
  374. * @constructor
  375. * @extends YAHOO.util.ImageLoader.imgObj
  376. * @param {String} domId HTML DOM id of the image element
  377. * @param {String} url URL for the image
  378. * @param {Int} width pixel width of the image - defaults to image's natural size
  379. * @param {Int} height pixel height of the image - defaults to image's natural size
  380. */
  381. YAHOO.util.ImageLoader.srcImgObj = function(domId, url, width, height) {
  382. YAHOO.util.ImageLoader.srcImgObj.superclass.constructor.call(this, domId, url);
  383. this.width = width;
  384. this.height = height;
  385. };
  386. YAHOO.lang.extend(YAHOO.util.ImageLoader.srcImgObj, YAHOO.util.ImageLoader.imgObj);
  387. /**
  388. * Inserts the image URL into the DOM so that the image is displayed.
  389. * Sets src
  390. * @method _applyUrl
  391. * @param {Object} el HTML DOM element
  392. * @private
  393. */
  394. YAHOO.util.ImageLoader.srcImgObj.prototype._applyUrl = function(el) {
  395. el.src = this.url;
  396. };
  397. /**
  398. * PNG background image object. A PNG background image is one whose URL is specified through AlphaImageLoader or by "background-image" in the element's style
  399. * @class YAHOO.util.ImageLoader.pngBgImgObj
  400. * @constructor
  401. * @extends YAHOO.util.ImageLoader.imgObj
  402. * @param {String} domId HTML DOM id of the image element
  403. * @param {String} url URL for the image
  404. * @param {Object} ailProps The AlphaImageLoader properties to be set for the image
  405. * Valid properties are 'sizingMethod' and 'enabled'
  406. */
  407. YAHOO.util.ImageLoader.pngBgImgObj = function(domId, url, ailProps) {
  408. YAHOO.util.ImageLoader.pngBgImgObj.superclass.constructor.call(this, domId, url);
  409. /**
  410. * AlphaImageLoader properties to be set for the image.
  411. * Valid properties are "sizingMethod" and "enabled".
  412. * @property props
  413. * @type Object
  414. */
  415. this.props = ailProps || {};
  416. };
  417. YAHOO.lang.extend(YAHOO.util.ImageLoader.pngBgImgObj, YAHOO.util.ImageLoader.imgObj);
  418. /**
  419. * Inserts the image URL into the DOM so that the image is displayed.
  420. * If the browser is determined to be IE6 (or older), sets the AlphaImageLoader src; otherwise sets style.backgroundImage
  421. * @method _applyUrl
  422. * @param {Object} el HTML DOM element
  423. * @private
  424. */
  425. YAHOO.util.ImageLoader.pngBgImgObj.prototype._applyUrl = function(el) {
  426. if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
  427. var sizingMethod = (YAHOO.lang.isUndefined(this.props.sizingMethod)) ? 'scale' : this.props.sizingMethod;
  428. var enabled = (YAHOO.lang.isUndefined(this.props.enabled)) ? 'true' : this.props.enabled;
  429. el.style.filter = 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src="' + this.url + '", sizingMethod="' + sizingMethod + '", enabled="' + enabled + '")';
  430. }
  431. else {
  432. el.style.backgroundImage = "url('" + this.url + "')";
  433. }
  434. };
  435. YAHOO.register("imageloader", YAHOO.util.ImageLoader, {version: "2.7.0", build: "1799"});