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.

916 lines
29 KiB

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