You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1018 lines
32 KiB

9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
  1. /*!
  2. * # Semantic UI 1.10.4 - Visibility
  3. * http://github.com/semantic-org/semantic-ui/
  4. *
  5. *
  6. * Copyright 2014 Contributors
  7. * Released under the MIT license
  8. * http://opensource.org/licenses/MIT
  9. *
  10. */
  11. ;(function ( $, window, document, undefined ) {
  12. "use strict";
  13. $.fn.visibility = function(parameters) {
  14. var
  15. $allModules = $(this),
  16. moduleSelector = $allModules.selector || '',
  17. time = new Date().getTime(),
  18. performance = [],
  19. query = arguments[0],
  20. methodInvoked = (typeof query == 'string'),
  21. queryArguments = [].slice.call(arguments, 1),
  22. returnedValue
  23. ;
  24. $allModules
  25. .each(function() {
  26. var
  27. settings = $.extend(true, {}, $.fn.visibility.settings, parameters),
  28. className = settings.className,
  29. namespace = settings.namespace,
  30. error = settings.error,
  31. eventNamespace = '.' + namespace,
  32. moduleNamespace = 'module-' + namespace,
  33. $window = $(window),
  34. $module = $(this),
  35. $context = $(settings.context),
  36. $container = $module.offsetParent(),
  37. selector = $module.selector || '',
  38. instance = $module.data(moduleNamespace),
  39. requestAnimationFrame = window.requestAnimationFrame
  40. || window.mozRequestAnimationFrame
  41. || window.webkitRequestAnimationFrame
  42. || window.msRequestAnimationFrame
  43. || function(callback) { setTimeout(callback, 0); },
  44. element = this,
  45. observer,
  46. module
  47. ;
  48. module = {
  49. initialize: function() {
  50. module.verbose('Initializing visibility', settings);
  51. module.setup.cache();
  52. module.save.position();
  53. if( module.should.trackChanges() ) {
  54. module.bindEvents();
  55. if(settings.type == 'image') {
  56. module.setup.image();
  57. }
  58. if(settings.type == 'fixed') {
  59. module.setup.fixed();
  60. }
  61. }
  62. if(settings.initialCheck) {
  63. module.checkVisibility();
  64. }
  65. if(settings.observeChanges) {
  66. module.observeChanges();
  67. }
  68. module.instantiate();
  69. },
  70. instantiate: function() {
  71. module.verbose('Storing instance of module', module);
  72. instance = module;
  73. $module
  74. .data(moduleNamespace, module)
  75. ;
  76. },
  77. destroy: function() {
  78. module.verbose('Destroying previous module');
  79. $module
  80. .off(eventNamespace)
  81. .removeData(moduleNamespace)
  82. ;
  83. },
  84. observeChanges: function() {
  85. var
  86. context = $context[0]
  87. ;
  88. if('MutationObserver' in window) {
  89. observer = new MutationObserver(function(mutations) {
  90. module.verbose('DOM tree modified, updating visibility calculations');
  91. module.refresh();
  92. });
  93. observer.observe(element, {
  94. childList : true,
  95. subtree : true
  96. });
  97. module.debug('Setting up mutation observer', observer);
  98. }
  99. },
  100. bindEvents: function() {
  101. module.verbose('Binding visibility events to scroll and resize');
  102. $window
  103. .on('resize' + eventNamespace, module.event.refresh)
  104. ;
  105. $context
  106. .on('scroll' + eventNamespace, module.event.scroll)
  107. ;
  108. },
  109. event: {
  110. refresh: function() {
  111. requestAnimationFrame(module.refresh);
  112. },
  113. scroll: function() {
  114. module.verbose('Scroll position changed');
  115. if(settings.throttle) {
  116. clearTimeout(module.timer);
  117. module.timer = setTimeout(module.checkVisibility, settings.throttle);
  118. }
  119. else {
  120. requestAnimationFrame(module.checkVisibility);
  121. }
  122. }
  123. },
  124. precache: function(images, callback) {
  125. if (!(images instanceof Array)) {
  126. images = [images];
  127. }
  128. var
  129. imagesLength = images.length,
  130. loadedCounter = 0,
  131. cache = [],
  132. cacheImage = document.createElement('img'),
  133. handleLoad = function() {
  134. loadedCounter++;
  135. if (loadedCounter >= images.length) {
  136. if ($.isFunction(callback)) {
  137. callback();
  138. }
  139. }
  140. }
  141. ;
  142. while (imagesLength--) {
  143. cacheImage = document.createElement('img');
  144. cacheImage.onload = handleLoad;
  145. cacheImage.onerror = handleLoad;
  146. cacheImage.src = images[imagesLength];
  147. cache.push(cacheImage);
  148. }
  149. },
  150. should: {
  151. trackChanges: function() {
  152. if(methodInvoked && queryArguments.length > 0) {
  153. module.debug('One time query, no need to bind events');
  154. return false;
  155. }
  156. module.debug('Query is attaching callbacks, watching for changes with scroll');
  157. return true;
  158. }
  159. },
  160. setup: {
  161. cache: function() {
  162. module.cache = {
  163. occurred : {},
  164. screen : {},
  165. element : {},
  166. };
  167. },
  168. image: function() {
  169. var
  170. src = $module.data('src')
  171. ;
  172. if(src) {
  173. module.verbose('Lazy loading image', src);
  174. // show when top visible
  175. module.topVisible(function() {
  176. module.debug('Image top visible', element);
  177. module.precache(src, function() {
  178. module.set.image(src);
  179. settings.onTopVisible = false;
  180. });
  181. });
  182. }
  183. },
  184. fixed: function() {
  185. module.verbose('Setting up fixed on element pass');
  186. $module
  187. .visibility({
  188. once: false,
  189. continuous: false,
  190. onTopPassed: function() {
  191. $module
  192. .addClass(className.fixed)
  193. .css({
  194. position: 'fixed',
  195. top: settings.offset + 'px'
  196. })
  197. ;
  198. if(settings.transition) {
  199. if($.fn.transition !== undefined) {
  200. $module.transition(settings.transition, settings.duration);
  201. }
  202. }
  203. },
  204. onTopPassedReverse: function() {
  205. $module
  206. .removeClass(className.fixed)
  207. .css({
  208. position: '',
  209. top: ''
  210. })
  211. ;
  212. }
  213. })
  214. ;
  215. }
  216. },
  217. set: {
  218. image: function(src) {
  219. var
  220. offScreen = (module.cache.screen.bottom < module.cache.element.top)
  221. ;
  222. $module
  223. .attr('src', src)
  224. ;
  225. if(offScreen) {
  226. module.verbose('Image outside browser, no show animation');
  227. $module.show();
  228. }
  229. else {
  230. if(settings.transition) {
  231. if( $.fn.transition !== undefined ) {
  232. $module.transition(settings.transition, settings.duration);
  233. }
  234. else {
  235. $module.fadeIn(settings.duration);
  236. }
  237. }
  238. else {
  239. $module.show();
  240. }
  241. }
  242. }
  243. },
  244. is: {
  245. visible: function() {
  246. if(module.cache && module.cache.element) {
  247. return (module.cache.element.height > 0 && module.cache.element.width > 0);
  248. }
  249. return false;
  250. }
  251. },
  252. refresh: function() {
  253. module.debug('Refreshing constants (element width/height)');
  254. module.reset();
  255. module.save.position();
  256. module.checkVisibility();
  257. settings.onRefresh.call(element);
  258. },
  259. reset: function() {
  260. module.verbose('Reseting all cached values');
  261. if( $.isPlainObject(module.cache) ) {
  262. module.cache.screen = {};
  263. module.cache.element = {};
  264. }
  265. },
  266. checkVisibility: function() {
  267. module.verbose('Checking visibility of element', module.cache.element);
  268. module.save.calculations();
  269. if( module.is.visible() ) {
  270. // percentage
  271. module.passed();
  272. // reverse (must be first)
  273. module.passingReverse();
  274. module.topVisibleReverse();
  275. module.bottomVisibleReverse();
  276. module.topPassedReverse();
  277. module.bottomPassedReverse();
  278. // one time
  279. module.passing();
  280. module.topVisible();
  281. module.bottomVisible();
  282. module.topPassed();
  283. module.bottomPassed();
  284. }
  285. },
  286. passed: function(amount, newCallback) {
  287. var
  288. calculations = module.get.elementCalculations(),
  289. amountInPixels
  290. ;
  291. // assign callback
  292. if(amount !== undefined && newCallback !== undefined) {
  293. settings.onPassed[amount] = newCallback;
  294. }
  295. else if(amount !== undefined) {
  296. return (module.get.pixelsPassed(amount) > calculations.pixelsPassed);
  297. }
  298. else if(calculations.passing) {
  299. $.each(settings.onPassed, function(amount, callback) {
  300. if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) {
  301. module.execute(callback, amount);
  302. }
  303. else if(!settings.once) {
  304. module.remove.occurred(callback);
  305. }
  306. });
  307. }
  308. },
  309. passing: function(newCallback) {
  310. var
  311. calculations = module.get.elementCalculations(),
  312. callback = newCallback || settings.onPassing,
  313. callbackName = 'passing'
  314. ;
  315. if(newCallback) {
  316. module.debug('Adding callback for passing', newCallback);
  317. settings.onPassing = newCallback;
  318. }
  319. if(calculations.passing) {
  320. module.execute(callback, callbackName);
  321. }
  322. else if(!settings.once) {
  323. module.remove.occurred(callbackName);
  324. }
  325. if(newCallback !== undefined) {
  326. return calculations.passing;
  327. }
  328. },
  329. topVisible: function(newCallback) {
  330. var
  331. calculations = module.get.elementCalculations(),
  332. callback = newCallback || settings.onTopVisible,
  333. callbackName = 'topVisible'
  334. ;
  335. if(newCallback) {
  336. module.debug('Adding callback for top visible', newCallback);
  337. settings.onTopVisible = newCallback;
  338. }
  339. if(calculations.topVisible) {
  340. module.execute(callback, callbackName);
  341. }
  342. else if(!settings.once) {
  343. module.remove.occurred(callbackName);
  344. }
  345. if(newCallback === undefined) {
  346. return calculations.topVisible;
  347. }
  348. },
  349. bottomVisible: function(newCallback) {
  350. var
  351. calculations = module.get.elementCalculations(),
  352. callback = newCallback || settings.onBottomVisible,
  353. callbackName = 'bottomVisible'
  354. ;
  355. if(newCallback) {
  356. module.debug('Adding callback for bottom visible', newCallback);
  357. settings.onBottomVisible = newCallback;
  358. }
  359. if(calculations.bottomVisible) {
  360. module.execute(callback, callbackName);
  361. }
  362. else if(!settings.once) {
  363. module.remove.occurred(callbackName);
  364. }
  365. if(newCallback === undefined) {
  366. return calculations.bottomVisible;
  367. }
  368. },
  369. topPassed: function(newCallback) {
  370. var
  371. calculations = module.get.elementCalculations(),
  372. callback = newCallback || settings.onTopPassed,
  373. callbackName = 'topPassed'
  374. ;
  375. if(newCallback) {
  376. module.debug('Adding callback for top passed', newCallback);
  377. settings.onTopPassed = newCallback;
  378. }
  379. if(calculations.topPassed) {
  380. module.execute(callback, callbackName);
  381. }
  382. else if(!settings.once) {
  383. module.remove.occurred(callbackName);
  384. }
  385. if(newCallback === undefined) {
  386. return calculations.topPassed;
  387. }
  388. },
  389. bottomPassed: function(newCallback) {
  390. var
  391. calculations = module.get.elementCalculations(),
  392. callback = newCallback || settings.onBottomPassed,
  393. callbackName = 'bottomPassed'
  394. ;
  395. if(newCallback) {
  396. module.debug('Adding callback for bottom passed', newCallback);
  397. settings.onBottomPassed = newCallback;
  398. }
  399. if(calculations.bottomPassed) {
  400. module.execute(callback, callbackName);
  401. }
  402. else if(!settings.once) {
  403. module.remove.occurred(callbackName);
  404. }
  405. if(newCallback === undefined) {
  406. return calculations.bottomPassed;
  407. }
  408. },
  409. passingReverse: function(newCallback) {
  410. var
  411. calculations = module.get.elementCalculations(),
  412. callback = newCallback || settings.onPassingReverse,
  413. callbackName = 'passingReverse'
  414. ;
  415. if(newCallback) {
  416. module.debug('Adding callback for passing reverse', newCallback);
  417. settings.onPassingReverse = newCallback;
  418. }
  419. if(!calculations.passing) {
  420. if(module.get.occurred('passing')) {
  421. module.execute(callback, callbackName);
  422. }
  423. }
  424. else if(!settings.once) {
  425. module.remove.occurred(callbackName);
  426. }
  427. if(newCallback !== undefined) {
  428. return !calculations.passing;
  429. }
  430. },
  431. topVisibleReverse: function(newCallback) {
  432. var
  433. calculations = module.get.elementCalculations(),
  434. callback = newCallback || settings.onTopVisibleReverse,
  435. callbackName = 'topVisibleReverse'
  436. ;
  437. if(newCallback) {
  438. module.debug('Adding callback for top visible reverse', newCallback);
  439. settings.onTopVisibleReverse = newCallback;
  440. }
  441. if(!calculations.topVisible) {
  442. if(module.get.occurred('topVisible')) {
  443. module.execute(callback, callbackName);
  444. }
  445. }
  446. else if(!settings.once) {
  447. module.remove.occurred(callbackName);
  448. }
  449. if(newCallback === undefined) {
  450. return !calculations.topVisible;
  451. }
  452. },
  453. bottomVisibleReverse: function(newCallback) {
  454. var
  455. calculations = module.get.elementCalculations(),
  456. callback = newCallback || settings.onBottomVisibleReverse,
  457. callbackName = 'bottomVisibleReverse'
  458. ;
  459. if(newCallback) {
  460. module.debug('Adding callback for bottom visible reverse', newCallback);
  461. settings.onBottomVisibleReverse = newCallback;
  462. }
  463. if(!calculations.bottomVisible) {
  464. if(module.get.occurred('bottomVisible')) {
  465. module.execute(callback, callbackName);
  466. }
  467. }
  468. else if(!settings.once) {
  469. module.remove.occurred(callbackName);
  470. }
  471. if(newCallback === undefined) {
  472. return !calculations.bottomVisible;
  473. }
  474. },
  475. topPassedReverse: function(newCallback) {
  476. var
  477. calculations = module.get.elementCalculations(),
  478. callback = newCallback || settings.onTopPassedReverse,
  479. callbackName = 'topPassedReverse'
  480. ;
  481. if(newCallback) {
  482. module.debug('Adding callback for top passed reverse', newCallback);
  483. settings.onTopPassedReverse = newCallback;
  484. }
  485. if(!calculations.topPassed) {
  486. if(module.get.occurred('topPassed')) {
  487. module.execute(callback, callbackName);
  488. }
  489. }
  490. else if(!settings.once) {
  491. module.remove.occurred(callbackName);
  492. }
  493. if(newCallback === undefined) {
  494. return !calculations.onTopPassed;
  495. }
  496. },
  497. bottomPassedReverse: function(newCallback) {
  498. var
  499. calculations = module.get.elementCalculations(),
  500. callback = newCallback || settings.onBottomPassedReverse,
  501. callbackName = 'bottomPassedReverse'
  502. ;
  503. if(newCallback) {
  504. module.debug('Adding callback for bottom passed reverse', newCallback);
  505. settings.onBottomPassedReverse = newCallback;
  506. }
  507. if(!calculations.bottomPassed) {
  508. if(module.get.occurred('bottomPassed')) {
  509. module.execute(callback, callbackName);
  510. }
  511. }
  512. else if(!settings.once) {
  513. module.remove.occurred(callbackName);
  514. }
  515. if(newCallback === undefined) {
  516. return !calculations.bottomPassed;
  517. }
  518. },
  519. execute: function(callback, callbackName) {
  520. var
  521. calculations = module.get.elementCalculations(),
  522. screen = module.get.screenCalculations()
  523. ;
  524. callback = callback || false;
  525. if(callback) {
  526. if(settings.continuous) {
  527. module.debug('Callback being called continuously', callbackName, calculations);
  528. callback.call(element, calculations, screen);
  529. }
  530. else if(!module.get.occurred(callbackName)) {
  531. module.debug('Conditions met', callbackName, calculations);
  532. callback.call(element, calculations, screen);
  533. }
  534. }
  535. module.save.occurred(callbackName);
  536. },
  537. remove: {
  538. occurred: function(callback) {
  539. if(callback) {
  540. if(module.cache.occurred[callback] !== undefined && module.cache.occurred[callback] === true) {
  541. module.debug('Callback can now be called again', callback);
  542. module.cache.occurred[callback] = false;
  543. }
  544. }
  545. else {
  546. module.cache.occurred = {};
  547. }
  548. }
  549. },
  550. save: {
  551. calculations: function() {
  552. module.verbose('Saving all calculations necessary to determine positioning');
  553. module.save.scroll();
  554. module.save.direction();
  555. module.save.screenCalculations();
  556. module.save.elementCalculations();
  557. },
  558. occurred: function(callback) {
  559. if(callback) {
  560. if(module.cache.occurred[callback] === undefined || (module.cache.occurred[callback] !== true)) {
  561. module.verbose('Saving callback occurred', callback);
  562. module.cache.occurred[callback] = true;
  563. }
  564. }
  565. },
  566. scroll: function() {
  567. module.cache.scroll = $context.scrollTop() + settings.offset;
  568. },
  569. direction: function() {
  570. var
  571. scroll = module.get.scroll(),
  572. lastScroll = module.get.lastScroll(),
  573. direction
  574. ;
  575. if(scroll > lastScroll && lastScroll) {
  576. direction = 'down';
  577. }
  578. else if(scroll < lastScroll && lastScroll) {
  579. direction = 'up';
  580. }
  581. else {
  582. direction = 'static';
  583. }
  584. module.cache.direction = direction;
  585. return module.cache.direction;
  586. },
  587. elementPosition: function() {
  588. var
  589. element = module.cache.element,
  590. screen = module.get.screenSize()
  591. ;
  592. module.verbose('Saving element position');
  593. // (quicker than $.extend)
  594. element.margin = {};
  595. element.margin.top = parseInt($module.css('margin-top'), 10);
  596. element.margin.bottom = parseInt($module.css('margin-bottom'), 10);
  597. element.fits = (element.height < screen.height);
  598. element.offset = $module.offset();
  599. element.width = $module.outerWidth();
  600. element.height = $module.outerHeight();
  601. // store
  602. module.cache.element = element;
  603. return element;
  604. },
  605. elementCalculations: function() {
  606. var
  607. screen = module.get.screenCalculations(),
  608. element = module.get.elementPosition()
  609. ;
  610. // offset
  611. if(settings.includeMargin) {
  612. element.top = element.offset.top - element.margin.top;
  613. element.bottom = element.offset.top + element.height + element.margin.bottom;
  614. }
  615. else {
  616. element.top = element.offset.top;
  617. element.bottom = element.offset.top + element.height;
  618. }
  619. // visibility
  620. element.topVisible = (screen.bottom >= element.top);
  621. element.topPassed = (screen.top >= element.top);
  622. element.bottomVisible = (screen.bottom >= element.bottom);
  623. element.bottomPassed = (screen.top >= element.bottom);
  624. element.pixelsPassed = 0;
  625. element.percentagePassed = 0;
  626. // meta calculations
  627. element.visible = (element.topVisible || element.bottomVisible);
  628. element.passing = (element.topPassed && !element.bottomPassed);
  629. element.hidden = (!element.topVisible && !element.bottomVisible);
  630. // passing calculations
  631. if(element.passing) {
  632. element.pixelsPassed = (screen.top - element.top);
  633. element.percentagePassed = (screen.top - element.top) / element.height;
  634. }
  635. module.cache.element = element;
  636. module.verbose('Updated element calculations', element);
  637. return element;
  638. },
  639. screenCalculations: function() {
  640. var
  641. scroll = $context.scrollTop() + settings.offset
  642. ;
  643. if(module.cache.scroll === undefined) {
  644. module.cache.scroll = $context.scrollTop() + settings.offset;
  645. }
  646. module.save.direction();
  647. $.extend(module.cache.screen, {
  648. top : scroll,
  649. bottom : scroll + module.cache.screen.height
  650. });
  651. return module.cache.screen;
  652. },
  653. screenSize: function() {
  654. module.verbose('Saving window position');
  655. module.cache.screen = {
  656. height: $context.height()
  657. };
  658. },
  659. position: function() {
  660. module.save.screenSize();
  661. module.save.elementPosition();
  662. }
  663. },
  664. get: {
  665. pixelsPassed: function(amount) {
  666. var
  667. element = module.get.elementCalculations()
  668. ;
  669. if(amount.search('%') > -1) {
  670. return ( element.height * (parseInt(amount, 10) / 100) );
  671. }
  672. return parseInt(amount, 10);
  673. },
  674. occurred: function(callback) {
  675. return (module.cache.occurred !== undefined)
  676. ? module.cache.occurred[callback] || false
  677. : false
  678. ;
  679. },
  680. direction: function() {
  681. if(module.cache.direction === undefined) {
  682. module.save.direction();
  683. }
  684. return module.cache.direction;
  685. },
  686. elementPosition: function() {
  687. if(module.cache.element === undefined) {
  688. module.save.elementPosition();
  689. }
  690. return module.cache.element;
  691. },
  692. elementCalculations: function() {
  693. if(module.cache.element === undefined) {
  694. module.save.elementCalculations();
  695. }
  696. return module.cache.element;
  697. },
  698. screenCalculations: function() {
  699. if(module.cache.screen === undefined) {
  700. module.save.screenCalculations();
  701. }
  702. return module.cache.screen;
  703. },
  704. screenSize: function() {
  705. if(module.cache.screen === undefined) {
  706. module.save.screenSize();
  707. }
  708. return module.cache.screen;
  709. },
  710. scroll: function() {
  711. if(module.cache.scroll === undefined) {
  712. module.save.scroll();
  713. }
  714. return module.cache.scroll;
  715. },
  716. lastScroll: function() {
  717. if(module.cache.screen === undefined) {
  718. module.debug('First scroll event, no last scroll could be found');
  719. return false;
  720. }
  721. return module.cache.screen.top;
  722. }
  723. },
  724. setting: function(name, value) {
  725. if( $.isPlainObject(name) ) {
  726. $.extend(true, settings, name);
  727. }
  728. else if(value !== undefined) {
  729. settings[name] = value;
  730. }
  731. else {
  732. return settings[name];
  733. }
  734. },
  735. internal: function(name, value) {
  736. if( $.isPlainObject(name) ) {
  737. $.extend(true, module, name);
  738. }
  739. else if(value !== undefined) {
  740. module[name] = value;
  741. }
  742. else {
  743. return module[name];
  744. }
  745. },
  746. debug: function() {
  747. if(settings.debug) {
  748. if(settings.performance) {
  749. module.performance.log(arguments);
  750. }
  751. else {
  752. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  753. module.debug.apply(console, arguments);
  754. }
  755. }
  756. },
  757. verbose: function() {
  758. if(settings.verbose && settings.debug) {
  759. if(settings.performance) {
  760. module.performance.log(arguments);
  761. }
  762. else {
  763. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  764. module.verbose.apply(console, arguments);
  765. }
  766. }
  767. },
  768. error: function() {
  769. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  770. module.error.apply(console, arguments);
  771. },
  772. performance: {
  773. log: function(message) {
  774. var
  775. currentTime,
  776. executionTime,
  777. previousTime
  778. ;
  779. if(settings.performance) {
  780. currentTime = new Date().getTime();
  781. previousTime = time || currentTime;
  782. executionTime = currentTime - previousTime;
  783. time = currentTime;
  784. performance.push({
  785. 'Name' : message[0],
  786. 'Arguments' : [].slice.call(message, 1) || '',
  787. 'Element' : element,
  788. 'Execution Time' : executionTime
  789. });
  790. }
  791. clearTimeout(module.performance.timer);
  792. module.performance.timer = setTimeout(module.performance.display, 100);
  793. },
  794. display: function() {
  795. var
  796. title = settings.name + ':',
  797. totalTime = 0
  798. ;
  799. time = false;
  800. clearTimeout(module.performance.timer);
  801. $.each(performance, function(index, data) {
  802. totalTime += data['Execution Time'];
  803. });
  804. title += ' ' + totalTime + 'ms';
  805. if(moduleSelector) {
  806. title += ' \'' + moduleSelector + '\'';
  807. }
  808. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  809. console.groupCollapsed(title);
  810. if(console.table) {
  811. console.table(performance);
  812. }
  813. else {
  814. $.each(performance, function(index, data) {
  815. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  816. });
  817. }
  818. console.groupEnd();
  819. }
  820. performance = [];
  821. }
  822. },
  823. invoke: function(query, passedArguments, context) {
  824. var
  825. object = instance,
  826. maxDepth,
  827. found,
  828. response
  829. ;
  830. passedArguments = passedArguments || queryArguments;
  831. context = element || context;
  832. if(typeof query == 'string' && object !== undefined) {
  833. query = query.split(/[\. ]/);
  834. maxDepth = query.length - 1;
  835. $.each(query, function(depth, value) {
  836. var camelCaseValue = (depth != maxDepth)
  837. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  838. : query
  839. ;
  840. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  841. object = object[camelCaseValue];
  842. }
  843. else if( object[camelCaseValue] !== undefined ) {
  844. found = object[camelCaseValue];
  845. return false;
  846. }
  847. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  848. object = object[value];
  849. }
  850. else if( object[value] !== undefined ) {
  851. found = object[value];
  852. return false;
  853. }
  854. else {
  855. module.error(error.method, query);
  856. return false;
  857. }
  858. });
  859. }
  860. if ( $.isFunction( found ) ) {
  861. response = found.apply(context, passedArguments);
  862. }
  863. else if(found !== undefined) {
  864. response = found;
  865. }
  866. if($.isArray(returnedValue)) {
  867. returnedValue.push(response);
  868. }
  869. else if(returnedValue !== undefined) {
  870. returnedValue = [returnedValue, response];
  871. }
  872. else if(response !== undefined) {
  873. returnedValue = response;
  874. }
  875. return found;
  876. }
  877. };
  878. if(methodInvoked) {
  879. if(instance === undefined) {
  880. module.initialize();
  881. }
  882. module.invoke(query);
  883. }
  884. else {
  885. if(instance !== undefined) {
  886. instance.invoke('destroy');
  887. }
  888. module.initialize();
  889. }
  890. })
  891. ;
  892. return (returnedValue !== undefined)
  893. ? returnedValue
  894. : this
  895. ;
  896. };
  897. $.fn.visibility.settings = {
  898. name : 'Visibility',
  899. namespace : 'visibility',
  900. className: {
  901. fixed: 'fixed'
  902. },
  903. observeChanges : true,
  904. debug : false,
  905. verbose : false,
  906. performance : true,
  907. offset : 0,
  908. includeMargin : false,
  909. context : window,
  910. // check position immediately on init
  911. initialCheck : true,
  912. // visibility check delay in ms (defaults to animationFrame)
  913. throttle : false,
  914. // special visibility type (image, fixed)
  915. type : false,
  916. // image only animation settings
  917. transition : false,
  918. duration : 1000,
  919. // array of callbacks for percentage
  920. onPassed : {},
  921. // standard callbacks
  922. onPassing : false,
  923. onTopVisible : false,
  924. onBottomVisible : false,
  925. onTopPassed : false,
  926. onBottomPassed : false,
  927. // reverse callbacks
  928. onPassingReverse : false,
  929. onTopVisibleReverse : false,
  930. onBottomVisibleReverse : false,
  931. onTopPassedReverse : false,
  932. onBottomPassedReverse : false,
  933. once : true,
  934. continuous : false,
  935. // utility callbacks
  936. onRefresh : function(){},
  937. onScroll : function(){},
  938. error : {
  939. method : 'The method you called is not defined.'
  940. }
  941. };
  942. })( jQuery, window , document );