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.

887 lines
27 KiB

9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 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
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
9 years ago
10 years ago
9 years ago
9 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
9 years ago
10 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 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
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
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
  1. /*!
  2. * # Semantic UI 2.1.0 - Sticky
  3. * http://github.com/semantic-org/semantic-ui/
  4. *
  5. *
  6. * Copyright 2015 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.sticky = 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 = ( $.isPlainObject(parameters) )
  28. ? $.extend(true, {}, $.fn.sticky.settings, parameters)
  29. : $.extend({}, $.fn.sticky.settings),
  30. className = settings.className,
  31. namespace = settings.namespace,
  32. error = settings.error,
  33. eventNamespace = '.' + namespace,
  34. moduleNamespace = 'module-' + namespace,
  35. $module = $(this),
  36. $window = $(window),
  37. $scroll = $(settings.scrollContext),
  38. $container,
  39. $context,
  40. selector = $module.selector || '',
  41. instance = $module.data(moduleNamespace),
  42. requestAnimationFrame = window.requestAnimationFrame
  43. || window.mozRequestAnimationFrame
  44. || window.webkitRequestAnimationFrame
  45. || window.msRequestAnimationFrame
  46. || function(callback) { setTimeout(callback, 0); },
  47. element = this,
  48. observer,
  49. module
  50. ;
  51. module = {
  52. initialize: function() {
  53. module.determineContainer();
  54. module.determineContext();
  55. module.verbose('Initializing sticky', settings, $container);
  56. module.save.positions();
  57. module.checkErrors();
  58. module.bind.events();
  59. if(settings.observeChanges) {
  60. module.observeChanges();
  61. }
  62. module.instantiate();
  63. },
  64. instantiate: function() {
  65. module.verbose('Storing instance of module', module);
  66. instance = module;
  67. $module
  68. .data(moduleNamespace, module)
  69. ;
  70. },
  71. destroy: function() {
  72. module.verbose('Destroying previous instance');
  73. module.reset();
  74. if(observer) {
  75. observer.disconnect();
  76. }
  77. $window
  78. .off('load' + eventNamespace, module.event.load)
  79. .off('resize' + eventNamespace, module.event.resize)
  80. ;
  81. $scroll
  82. .off('scrollchange' + eventNamespace, module.event.scrollchange)
  83. ;
  84. $module.removeData(moduleNamespace);
  85. },
  86. observeChanges: function() {
  87. var
  88. context = $context[0]
  89. ;
  90. if('MutationObserver' in window) {
  91. observer = new MutationObserver(function(mutations) {
  92. clearTimeout(module.timer);
  93. module.timer = setTimeout(function() {
  94. module.verbose('DOM tree modified, updating sticky menu', mutations);
  95. module.refresh();
  96. }, 100);
  97. });
  98. observer.observe(element, {
  99. childList : true,
  100. subtree : true
  101. });
  102. observer.observe(context, {
  103. childList : true,
  104. subtree : true
  105. });
  106. module.debug('Setting up mutation observer', observer);
  107. }
  108. },
  109. determineContainer: function() {
  110. $container = $module.offsetParent();
  111. },
  112. determineContext: function() {
  113. if(settings.context) {
  114. $context = $(settings.context);
  115. }
  116. else {
  117. $context = $container;
  118. }
  119. if($context.length === 0) {
  120. module.error(error.invalidContext, settings.context, $module);
  121. return;
  122. }
  123. },
  124. checkErrors: function() {
  125. if( module.is.hidden() ) {
  126. module.error(error.visible, $module);
  127. }
  128. if(module.cache.element.height > module.cache.context.height) {
  129. module.reset();
  130. module.error(error.elementSize, $module);
  131. return;
  132. }
  133. },
  134. bind: {
  135. events: function() {
  136. $window
  137. .on('load' + eventNamespace, module.event.load)
  138. .on('resize' + eventNamespace, module.event.resize)
  139. ;
  140. // pub/sub pattern
  141. $scroll
  142. .off('scroll' + eventNamespace)
  143. .on('scroll' + eventNamespace, module.event.scroll)
  144. .on('scrollchange' + eventNamespace, module.event.scrollchange)
  145. ;
  146. }
  147. },
  148. event: {
  149. load: function() {
  150. module.verbose('Page contents finished loading');
  151. requestAnimationFrame(module.refresh);
  152. },
  153. resize: function() {
  154. module.verbose('Window resized');
  155. requestAnimationFrame(module.refresh);
  156. },
  157. scroll: function() {
  158. requestAnimationFrame(function() {
  159. $scroll.triggerHandler('scrollchange' + eventNamespace, $scroll.scrollTop() );
  160. });
  161. },
  162. scrollchange: function(event, scrollPosition) {
  163. module.stick(scrollPosition);
  164. settings.onScroll.call(element);
  165. }
  166. },
  167. refresh: function(hardRefresh) {
  168. module.reset();
  169. if(!settings.context) {
  170. module.determineContext();
  171. }
  172. if(hardRefresh) {
  173. module.determineContainer();
  174. }
  175. module.save.positions();
  176. module.stick();
  177. settings.onReposition.call(element);
  178. },
  179. supports: {
  180. sticky: function() {
  181. var
  182. $element = $('<div/>'),
  183. element = $element[0]
  184. ;
  185. $element.addClass(className.supported);
  186. return($element.css('position').match('sticky'));
  187. }
  188. },
  189. save: {
  190. lastScroll: function(scroll) {
  191. module.lastScroll = scroll;
  192. },
  193. elementScroll: function(scroll) {
  194. module.elementScroll = scroll;
  195. },
  196. positions: function() {
  197. var
  198. window = {
  199. height: $window.height()
  200. },
  201. element = {
  202. margin: {
  203. top : parseInt($module.css('margin-top'), 10),
  204. bottom : parseInt($module.css('margin-bottom'), 10),
  205. },
  206. offset : $module.offset(),
  207. width : $module.outerWidth(),
  208. height : $module.outerHeight()
  209. },
  210. context = {
  211. offset : $context.offset(),
  212. height : $context.outerHeight()
  213. },
  214. container = {
  215. height: $container.outerHeight()
  216. }
  217. ;
  218. module.cache = {
  219. fits : ( element.height < window.height ),
  220. window: {
  221. height: window.height
  222. },
  223. element: {
  224. margin : element.margin,
  225. top : element.offset.top - element.margin.top,
  226. left : element.offset.left,
  227. width : element.width,
  228. height : element.height,
  229. bottom : element.offset.top + element.height
  230. },
  231. context: {
  232. top : context.offset.top,
  233. height : context.height,
  234. bottom : context.offset.top + context.height
  235. }
  236. };
  237. module.set.containerSize();
  238. module.set.size();
  239. module.stick();
  240. module.debug('Caching element positions', module.cache);
  241. }
  242. },
  243. get: {
  244. direction: function(scroll) {
  245. var
  246. direction = 'down'
  247. ;
  248. scroll = scroll || $scroll.scrollTop();
  249. if(module.lastScroll !== undefined) {
  250. if(module.lastScroll < scroll) {
  251. direction = 'down';
  252. }
  253. else if(module.lastScroll > scroll) {
  254. direction = 'up';
  255. }
  256. }
  257. return direction;
  258. },
  259. scrollChange: function(scroll) {
  260. scroll = scroll || $scroll.scrollTop();
  261. return (module.lastScroll)
  262. ? (scroll - module.lastScroll)
  263. : 0
  264. ;
  265. },
  266. currentElementScroll: function() {
  267. if(module.elementScroll) {
  268. return module.elementScroll;
  269. }
  270. return ( module.is.top() )
  271. ? Math.abs(parseInt($module.css('top'), 10)) || 0
  272. : Math.abs(parseInt($module.css('bottom'), 10)) || 0
  273. ;
  274. },
  275. elementScroll: function(scroll) {
  276. scroll = scroll || $scroll.scrollTop();
  277. var
  278. element = module.cache.element,
  279. window = module.cache.window,
  280. delta = module.get.scrollChange(scroll),
  281. maxScroll = (element.height - window.height + settings.offset),
  282. elementScroll = module.get.currentElementScroll(),
  283. possibleScroll = (elementScroll + delta)
  284. ;
  285. if(module.cache.fits || possibleScroll < 0) {
  286. elementScroll = 0;
  287. }
  288. else if(possibleScroll > maxScroll ) {
  289. elementScroll = maxScroll;
  290. }
  291. else {
  292. elementScroll = possibleScroll;
  293. }
  294. return elementScroll;
  295. }
  296. },
  297. remove: {
  298. lastScroll: function() {
  299. delete module.lastScroll;
  300. },
  301. elementScroll: function(scroll) {
  302. delete module.elementScroll;
  303. },
  304. offset: function() {
  305. $module.css('margin-top', '');
  306. }
  307. },
  308. set: {
  309. offset: function() {
  310. module.verbose('Setting offset on element', settings.offset);
  311. $module
  312. .css('margin-top', settings.offset)
  313. ;
  314. },
  315. containerSize: function() {
  316. var
  317. tagName = $container.get(0).tagName
  318. ;
  319. if(tagName === 'HTML' || tagName == 'body') {
  320. // this can trigger for too many reasons
  321. //module.error(error.container, tagName, $module);
  322. module.determineContainer();
  323. }
  324. else {
  325. if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) {
  326. module.debug('Context has padding, specifying exact height for container', module.cache.context.height);
  327. $container.css({
  328. height: module.cache.context.height
  329. });
  330. }
  331. }
  332. },
  333. minimumSize: function() {
  334. var
  335. element = module.cache.element
  336. ;
  337. $container
  338. .css('min-height', element.height)
  339. ;
  340. },
  341. scroll: function(scroll) {
  342. module.debug('Setting scroll on element', scroll);
  343. if(module.elementScroll == scroll) {
  344. return;
  345. }
  346. if( module.is.top() ) {
  347. $module
  348. .css('bottom', '')
  349. .css('top', -scroll)
  350. ;
  351. }
  352. if( module.is.bottom() ) {
  353. $module
  354. .css('top', '')
  355. .css('bottom', scroll)
  356. ;
  357. }
  358. },
  359. size: function() {
  360. if(module.cache.element.height !== 0 && module.cache.element.width !== 0) {
  361. element.style.setProperty('width', module.cache.element.width + 'px', 'important');
  362. element.style.setProperty('height', module.cache.element.height + 'px', 'important');
  363. }
  364. }
  365. },
  366. is: {
  367. top: function() {
  368. return $module.hasClass(className.top);
  369. },
  370. bottom: function() {
  371. return $module.hasClass(className.bottom);
  372. },
  373. initialPosition: function() {
  374. return (!module.is.fixed() && !module.is.bound());
  375. },
  376. hidden: function() {
  377. return (!$module.is(':visible'));
  378. },
  379. bound: function() {
  380. return $module.hasClass(className.bound);
  381. },
  382. fixed: function() {
  383. return $module.hasClass(className.fixed);
  384. }
  385. },
  386. stick: function(scroll) {
  387. var
  388. cachedPosition = scroll || $scroll.scrollTop(),
  389. cache = module.cache,
  390. fits = cache.fits,
  391. element = cache.element,
  392. window = cache.window,
  393. context = cache.context,
  394. offset = (module.is.bottom() && settings.pushing)
  395. ? settings.bottomOffset
  396. : settings.offset,
  397. scroll = {
  398. top : cachedPosition + offset,
  399. bottom : cachedPosition + offset + window.height
  400. },
  401. direction = module.get.direction(scroll.top),
  402. elementScroll = (fits)
  403. ? 0
  404. : module.get.elementScroll(scroll.top),
  405. // shorthand
  406. doesntFit = !fits,
  407. elementVisible = (element.height !== 0)
  408. ;
  409. if(elementVisible) {
  410. if( module.is.initialPosition() ) {
  411. if(scroll.top >= context.bottom) {
  412. module.debug('Initial element position is bottom of container');
  413. module.bindBottom();
  414. }
  415. else if(scroll.top > element.top) {
  416. if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
  417. module.debug('Initial element position is bottom of container');
  418. module.bindBottom();
  419. }
  420. else {
  421. module.debug('Initial element position is fixed');
  422. module.fixTop();
  423. }
  424. }
  425. }
  426. else if( module.is.fixed() ) {
  427. // currently fixed top
  428. if( module.is.top() ) {
  429. if( scroll.top <= element.top ) {
  430. module.debug('Fixed element reached top of container');
  431. module.setInitialPosition();
  432. }
  433. else if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
  434. module.debug('Fixed element reached bottom of container');
  435. module.bindBottom();
  436. }
  437. // scroll element if larger than screen
  438. else if(doesntFit) {
  439. module.set.scroll(elementScroll);
  440. module.save.lastScroll(scroll.top);
  441. module.save.elementScroll(elementScroll);
  442. }
  443. }
  444. // currently fixed bottom
  445. else if(module.is.bottom() ) {
  446. // top edge
  447. if( (scroll.bottom - element.height) <= element.top) {
  448. module.debug('Bottom fixed rail has reached top of container');
  449. module.setInitialPosition();
  450. }
  451. // bottom edge
  452. else if(scroll.bottom >= context.bottom) {
  453. module.debug('Bottom fixed rail has reached bottom of container');
  454. module.bindBottom();
  455. }
  456. // scroll element if larger than screen
  457. else if(doesntFit) {
  458. module.set.scroll(elementScroll);
  459. module.save.lastScroll(scroll.top);
  460. module.save.elementScroll(elementScroll);
  461. }
  462. }
  463. }
  464. else if( module.is.bottom() ) {
  465. if(settings.pushing) {
  466. if(module.is.bound() && scroll.bottom <= context.bottom ) {
  467. module.debug('Fixing bottom attached element to bottom of browser.');
  468. module.fixBottom();
  469. }
  470. }
  471. else {
  472. if(module.is.bound() && (scroll.top <= context.bottom - element.height) ) {
  473. module.debug('Fixing bottom attached element to top of browser.');
  474. module.fixTop();
  475. }
  476. }
  477. }
  478. }
  479. },
  480. bindTop: function() {
  481. module.debug('Binding element to top of parent container');
  482. module.remove.offset();
  483. $module
  484. .css({
  485. left : '',
  486. top : '',
  487. marginBottom : ''
  488. })
  489. .removeClass(className.fixed)
  490. .removeClass(className.bottom)
  491. .addClass(className.bound)
  492. .addClass(className.top)
  493. ;
  494. settings.onTop.call(element);
  495. settings.onUnstick.call(element);
  496. },
  497. bindBottom: function() {
  498. module.debug('Binding element to bottom of parent container');
  499. module.remove.offset();
  500. $module
  501. .css({
  502. left : '',
  503. top : ''
  504. })
  505. .removeClass(className.fixed)
  506. .removeClass(className.top)
  507. .addClass(className.bound)
  508. .addClass(className.bottom)
  509. ;
  510. settings.onBottom.call(element);
  511. settings.onUnstick.call(element);
  512. },
  513. setInitialPosition: function() {
  514. module.debug('Returning to initial position');
  515. module.unfix();
  516. module.unbind();
  517. },
  518. fixTop: function() {
  519. module.debug('Fixing element to top of page');
  520. module.set.minimumSize();
  521. module.set.offset();
  522. $module
  523. .css({
  524. left : module.cache.element.left,
  525. bottom : '',
  526. marginBottom : ''
  527. })
  528. .removeClass(className.bound)
  529. .removeClass(className.bottom)
  530. .addClass(className.fixed)
  531. .addClass(className.top)
  532. ;
  533. settings.onStick.call(element);
  534. },
  535. fixBottom: function() {
  536. module.debug('Sticking element to bottom of page');
  537. module.set.minimumSize();
  538. module.set.offset();
  539. $module
  540. .css({
  541. left : module.cache.element.left,
  542. bottom : '',
  543. marginBottom : ''
  544. })
  545. .removeClass(className.bound)
  546. .removeClass(className.top)
  547. .addClass(className.fixed)
  548. .addClass(className.bottom)
  549. ;
  550. settings.onStick.call(element);
  551. },
  552. unbind: function() {
  553. if( module.is.bound() ) {
  554. module.debug('Removing container bound position on element');
  555. module.remove.offset();
  556. $module
  557. .removeClass(className.bound)
  558. .removeClass(className.top)
  559. .removeClass(className.bottom)
  560. ;
  561. }
  562. },
  563. unfix: function() {
  564. if( module.is.fixed() ) {
  565. module.debug('Removing fixed position on element');
  566. module.remove.offset();
  567. $module
  568. .removeClass(className.fixed)
  569. .removeClass(className.top)
  570. .removeClass(className.bottom)
  571. ;
  572. settings.onUnstick.call(element);
  573. }
  574. },
  575. reset: function() {
  576. module.debug('Reseting elements position');
  577. module.unbind();
  578. module.unfix();
  579. module.resetCSS();
  580. module.remove.offset();
  581. module.remove.lastScroll();
  582. },
  583. resetCSS: function() {
  584. $module
  585. .css({
  586. width : '',
  587. height : ''
  588. })
  589. ;
  590. $container
  591. .css({
  592. height: ''
  593. })
  594. ;
  595. },
  596. setting: function(name, value) {
  597. if( $.isPlainObject(name) ) {
  598. $.extend(true, settings, name);
  599. }
  600. else if(value !== undefined) {
  601. settings[name] = value;
  602. }
  603. else {
  604. return settings[name];
  605. }
  606. },
  607. internal: function(name, value) {
  608. if( $.isPlainObject(name) ) {
  609. $.extend(true, module, name);
  610. }
  611. else if(value !== undefined) {
  612. module[name] = value;
  613. }
  614. else {
  615. return module[name];
  616. }
  617. },
  618. debug: function() {
  619. if(settings.debug) {
  620. if(settings.performance) {
  621. module.performance.log(arguments);
  622. }
  623. else {
  624. module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
  625. module.debug.apply(console, arguments);
  626. }
  627. }
  628. },
  629. verbose: function() {
  630. if(settings.verbose && settings.debug) {
  631. if(settings.performance) {
  632. module.performance.log(arguments);
  633. }
  634. else {
  635. module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
  636. module.verbose.apply(console, arguments);
  637. }
  638. }
  639. },
  640. error: function() {
  641. module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
  642. module.error.apply(console, arguments);
  643. },
  644. performance: {
  645. log: function(message) {
  646. var
  647. currentTime,
  648. executionTime,
  649. previousTime
  650. ;
  651. if(settings.performance) {
  652. currentTime = new Date().getTime();
  653. previousTime = time || currentTime;
  654. executionTime = currentTime - previousTime;
  655. time = currentTime;
  656. performance.push({
  657. 'Name' : message[0],
  658. 'Arguments' : [].slice.call(message, 1) || '',
  659. 'Element' : element,
  660. 'Execution Time' : executionTime
  661. });
  662. }
  663. clearTimeout(module.performance.timer);
  664. module.performance.timer = setTimeout(module.performance.display, 0);
  665. },
  666. display: function() {
  667. var
  668. title = settings.name + ':',
  669. totalTime = 0
  670. ;
  671. time = false;
  672. clearTimeout(module.performance.timer);
  673. $.each(performance, function(index, data) {
  674. totalTime += data['Execution Time'];
  675. });
  676. title += ' ' + totalTime + 'ms';
  677. if(moduleSelector) {
  678. title += ' \'' + moduleSelector + '\'';
  679. }
  680. if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
  681. console.groupCollapsed(title);
  682. if(console.table) {
  683. console.table(performance);
  684. }
  685. else {
  686. $.each(performance, function(index, data) {
  687. console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
  688. });
  689. }
  690. console.groupEnd();
  691. }
  692. performance = [];
  693. }
  694. },
  695. invoke: function(query, passedArguments, context) {
  696. var
  697. object = instance,
  698. maxDepth,
  699. found,
  700. response
  701. ;
  702. passedArguments = passedArguments || queryArguments;
  703. context = element || context;
  704. if(typeof query == 'string' && object !== undefined) {
  705. query = query.split(/[\. ]/);
  706. maxDepth = query.length - 1;
  707. $.each(query, function(depth, value) {
  708. var camelCaseValue = (depth != maxDepth)
  709. ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
  710. : query
  711. ;
  712. if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
  713. object = object[camelCaseValue];
  714. }
  715. else if( object[camelCaseValue] !== undefined ) {
  716. found = object[camelCaseValue];
  717. return false;
  718. }
  719. else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
  720. object = object[value];
  721. }
  722. else if( object[value] !== undefined ) {
  723. found = object[value];
  724. return false;
  725. }
  726. else {
  727. return false;
  728. }
  729. });
  730. }
  731. if ( $.isFunction( found ) ) {
  732. response = found.apply(context, passedArguments);
  733. }
  734. else if(found !== undefined) {
  735. response = found;
  736. }
  737. if($.isArray(returnedValue)) {
  738. returnedValue.push(response);
  739. }
  740. else if(returnedValue !== undefined) {
  741. returnedValue = [returnedValue, response];
  742. }
  743. else if(response !== undefined) {
  744. returnedValue = response;
  745. }
  746. return found;
  747. }
  748. };
  749. if(methodInvoked) {
  750. if(instance === undefined) {
  751. module.initialize();
  752. }
  753. module.invoke(query);
  754. }
  755. else {
  756. if(instance !== undefined) {
  757. instance.invoke('destroy');
  758. }
  759. module.initialize();
  760. }
  761. })
  762. ;
  763. return (returnedValue !== undefined)
  764. ? returnedValue
  765. : this
  766. ;
  767. };
  768. $.fn.sticky.settings = {
  769. name : 'Sticky',
  770. namespace : 'sticky',
  771. debug : false,
  772. verbose : true,
  773. performance : true,
  774. // whether to stick in the opposite direction on scroll up
  775. pushing : false,
  776. context : false,
  777. // Context to watch scroll events
  778. scrollContext : window,
  779. // Offset to adjust scroll
  780. offset : 0,
  781. // Offset to adjust scroll when attached to bottom of screen
  782. bottomOffset : 0,
  783. jitter : 5, // will only set container height if difference between context and container is larger than this number
  784. // Whether to automatically observe changes with Mutation Observers
  785. observeChanges : false,
  786. // Called when position is recalculated
  787. onReposition : function(){},
  788. // Called on each scroll
  789. onScroll : function(){},
  790. // Called when element is stuck to viewport
  791. onStick : function(){},
  792. // Called when element is unstuck from viewport
  793. onUnstick : function(){},
  794. // Called when element reaches top of context
  795. onTop : function(){},
  796. // Called when element reaches bottom of context
  797. onBottom : function(){},
  798. error : {
  799. container : 'Sticky element must be inside a relative container',
  800. visible : 'Element is hidden, you must call refresh after element becomes visible',
  801. method : 'The method you called is not defined.',
  802. invalidContext : 'Context specified does not exist',
  803. elementSize : 'Sticky element is larger than its container, cannot create sticky.'
  804. },
  805. className : {
  806. bound : 'bound',
  807. fixed : 'fixed',
  808. supported : 'native',
  809. top : 'top',
  810. bottom : 'bottom'
  811. }
  812. };
  813. })( jQuery, window , document );