MediaWiki:Gadget-jquery.in-view.js

From wikishia

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
// A few bugs fixed by [[User:Rillke]] (including undefined variable j, wrong calculation of offsetTop, ...)
// Original description follows:
// / <reference path="jquery-1.4.2.min.js"/>
/*
@author Daniel Gidman
released under GNU General Public License v3
http://www.gnu.org/licenses/gpl.html
version 1
September 2, 2010
*/
/*
 * @description
 *  adds a ":in-view"- "property" (returns (bool) whether at least one element is visible
 *  adds a .visible()- method to each jQuery node-object that returns all elements of the set of selected elements that are actually visible (= on screen and not hidden)
 *  useful for loading contents on demand and other stuff
 * @example
 *  $('selector').visible().fadeIn();
 * @example
 *  if $('selector:in-view') loadOnDemand();
 *
 */
/*global jQuery:false*/
/*jshint curly:false*/ 
(function ($) {
	'use strict';
	$.fn.inView = $.fn.visible = function () {
		// / <summary>Filter that checks if the item(s) is visible within the page. Returns set of visible elements</summary>
		// / <returns type="jQuery" />
		// sanity check aborts when no elements visible
		return this.filter(":visible").filter(function () {
			var add = true,
				elem = this,
				$el = $(this),
				
				// 1) select only scrollable parents
				$ps = $el.parents().filter(function () {
					return (this.scrollHeight > this.offsetHeight || this.scrollWidth > this.offsetWidth);
				});
				
			// 2) loop through the parent elements checking that 
			// each scrollable element is visible in parent.
			$ps.each(function (i, p) {
				var elOffs = $el.offset(),
					$p = $(p),
					pOffs = $p.offset();
					
				// HTML had a negative offset and then it changed completely (to 0)
				if ($p.filter('html').length) {
					pOffs.top = $p.scrollTop();
					pOffs.left = $p.scrollLeft();
				}
				add = add && (elOffs.top >= pOffs.top && // is above viewport?
				$el.height() + elOffs.top - pOffs.top <= $p.height() && // is below viewport?
				elOffs.left >= pOffs.left && // is left from viewport?
				$el.width() + elOffs.left - pOffs.left <= $p.width()); // is right from viewport?
				
				$el = $p;
				if (!add) return false;
			});
			return add;
		});
	};
	$.extend($.expr.pseudos, {
		"in-view": function (a, i, m) {
			return $(a).visible().length > 0;
		}
	});
})(jQuery);