From 64d9c0d627b9681bf39a7c5f30f7cad0b2cce2a8 Mon Sep 17 00:00:00 2001 From: Matthew Frey Date: Mon, 27 Jan 2014 15:19:26 -0800 Subject: [PATCH 1/9] Initial edits - removed support for really old browsers and made in view checks more modern --- jquery.inview.js | 109 +++++++++++-------------------------------- jquery.inview.min.js | 10 ++-- 2 files changed, 35 insertions(+), 84 deletions(-) diff --git a/jquery.inview.js b/jquery.inview.js index b2c29c1..041024f 100644 --- a/jquery.inview.js +++ b/jquery.inview.js @@ -1,11 +1,16 @@ /** - * author Christopher Blum - * - based on the idea of Remy Sharp, http://remysharp.com/2009/01/26/element-in-view-event-plugin/ - * - forked from http://github.com/zuk/jquery.inview/ + * Jquery Inview 2 + * Version: 0.1 + * Author: Matthew Frey (mmmeff) + * - forked from http://github.com/protonet/jquery.inview/ */ (function ($) { - var inviewObjects = {}, viewportSize, viewportOffset, - d = document, w = window, documentElement = d.documentElement, expando = $.expando, timer; + var inviewObjects = {}, + d = document, + w = window, + documentElement = d.documentElement, + expando = $.expando, + timer; $.event.special.inview = { add: function(data) { @@ -37,35 +42,8 @@ } }; - function getViewportSize() { - var mode, domObject, size = { height: w.innerHeight, width: w.innerWidth }; - - // if this is correct then return it. iPad has compat Mode, so will - // go into check clientHeight/clientWidth (which has the wrong value). - if (!size.height) { - mode = d.compatMode; - if (mode || !$.support.boxModel) { // IE, Gecko - domObject = mode === 'CSS1Compat' ? - documentElement : // Standards - d.body; // Quirks - size = { - height: domObject.clientHeight, - width: domObject.clientWidth - }; - } - } - - return size; - } - - function getViewportOffset() { - return { - top: w.pageYOffset || documentElement.scrollTop || d.body.scrollTop, - left: w.pageXOffset || documentElement.scrollLeft || d.body.scrollLeft - }; - } - function checkInView() { + // Fuck IE and its quirks, we're doing this the right way. var $elements = $(), elementsLength, i = 0; $.each(inviewObjects, function(i, inviewObject) { @@ -74,63 +52,32 @@ $elements = $elements.add(selector ? $element.find(selector) : $element); }); - elementsLength = $elements.length; - if (elementsLength) { - viewportSize = viewportSize || getViewportSize(); - viewportOffset = viewportOffset || getViewportOffset(); - - for (; i viewportOffset.top && - elementOffset.top < viewportOffset.top + viewportSize.height && - elementOffset.left + elementSize.width > viewportOffset.left && - elementOffset.left < viewportOffset.left + viewportSize.width) { - visiblePartX = (viewportOffset.left > elementOffset.left ? - 'right' : (viewportOffset.left + viewportSize.width) < (elementOffset.left + elementSize.width) ? - 'left' : 'both'); - visiblePartY = (viewportOffset.top > elementOffset.top ? - 'bottom' : (viewportOffset.top + viewportSize.height) < (elementOffset.top + elementSize.height) ? - 'top' : 'both'); - visiblePartsMerged = visiblePartX + "-" + visiblePartY; - if (!inView || inView !== visiblePartsMerged) { - $element.data('inview', visiblePartsMerged).trigger('inview', [true, visiblePartX, visiblePartY]); + if (rect.top >= 0 && + rect.left >= 0 && + rect.bottom <= (w.innerHeight || documentElement.clientHeight) && + rect.right <= (w.innerWidth || documentElement.clientWidth)) { + if (!inView) { + // object has entered viewport + $element.data('inview', true).trigger('inview', [true]); } } else if (inView) { + // object has left viewport $element.data('inview', false).trigger('inview', [false]); } } } } - - $(w).bind("scroll resize", function() { - viewportSize = viewportOffset = null; - }); - - // IE < 9 scrolls to focused elements without firing the "scroll" event - if (!documentElement.addEventListener && documentElement.attachEvent) { - documentElement.attachEvent("onfocusin", function() { - viewportOffset = null; - }); - } })(jQuery); \ No newline at end of file diff --git a/jquery.inview.min.js b/jquery.inview.min.js index 8102edc..c17b752 100644 --- a/jquery.inview.min.js +++ b/jquery.inview.min.js @@ -1,3 +1,7 @@ -(function(d){var p={},e,a,h=document,i=window,f=h.documentElement,j=d.expando;d.event.special.inview={add:function(a){p[a.guid+"-"+this[j]]={data:a,$element:d(this)}},remove:function(a){try{delete p[a.guid+"-"+this[j]]}catch(d){}}};d(i).bind("scroll resize",function(){e=a=null});!f.addEventListener&&f.attachEvent&&f.attachEvent("onfocusin",function(){a=null});setInterval(function(){var k=d(),j,n=0;d.each(p,function(a,b){var c=b.data.selector,d=b.$element;k=k.add(c?d.find(c):d)});if(j=k.length){var b; -if(!(b=e)){var g={height:i.innerHeight,width:i.innerWidth};if(!g.height&&((b=h.compatMode)||!d.support.boxModel))b="CSS1Compat"===b?f:h.body,g={height:b.clientHeight,width:b.clientWidth};b=g}e=b;for(a=a||{top:i.pageYOffset||f.scrollTop||h.body.scrollTop,left:i.pageXOffset||f.scrollLeft||h.body.scrollLeft};na.top&&c.topa.left&&c.leftc.left?"right":a.left+e.widthc.top?"bottom":a.top+e.heighti;i++)if(t[i])if(e.contains(d,t[i])){var a=t[i],r=a.data("inview"),c=a.getBoundingClientRect();c.top>=0&&c.left>=0&&c.bottom<=(l.innerHeight||d.clientHeight)&&c.right<=(l.innerWidth||d.clientWidth)?r||$element.data("inview",!0).trigger("inview",[!0]):r&&$element.data("inview",!1).trigger("inview",[!1])}else delete t[i]}var i,n={},a=document,l=window,d=a.documentElement,r=e.expando;e.event.special.inview={add:function(a){n[a.guid+"-"+this[r]]={data:a,$element:e(this)},i||e.isEmptyObject(n)||(i=setInterval(t,250))},remove:function(t){try{delete n[t.guid+"-"+this[r]]}catch(a){}e.isEmptyObject(n)&&(clearInterval(i),i=null)}}})(jQuery); \ No newline at end of file From 0f865758fa77b745da37e35913c47a4b79e0313d Mon Sep 17 00:00:00 2001 From: Matthew Frey Date: Mon, 27 Jan 2014 15:19:55 -0800 Subject: [PATCH 2/9] Updated read me --- README.textile | 72 ++++++-------------------------------------------- 1 file changed, 8 insertions(+), 64 deletions(-) diff --git a/README.textile b/README.textile index 2c36685..74c5094 100644 --- a/README.textile +++ b/README.textile @@ -1,11 +1,11 @@ -h1. Element 'inview' Event Plugin +h1. jQuery inview2 Event that is fired as soon as an element appears in the user's viewport. +Modified version of protonet's jquery.inview to use the more modern (and much faster) getBoundingClientRect() method. +Props to him for his work on the original inview, but I found myself in need of a better-performing solution. -*Author:* "Christopher Blum":http://twitter.com/ChristopherBlum -*Original idea and concept by:* "Remy Sharp":http://remysharp.com/2009/01/26/element-in-view-event-plugin/ -*Forked from:* "https://github.com/zuk/jquery.inview/":https://github.com/zuk/jquery.inview/ -*Demo* (loading lolcats when they scroll into view): "http://tifftiff.de/jquery.inview/example/live_event.html":http://tifftiff.de/jquery.inview/example/live_event.html +*Author:* Matthew Frey +*Forked from:* "https://github.com/protonet/jquery.inview/":https://github.com/protonet/jquery.inview/ *Requires:* jQuery 1.4+ h2. Usage @@ -15,19 +15,10 @@ The script makes use of the new $.contains method - so it will only work with jQ The event will only fire when the element comes in to view of the viewport, and out of view. It won't keep firing if the user scrolls and the element remains in view. The variable after the event argument indicates the visible state in the viewport. -The third variable visiblePartX detects which horizontal part of the element is visible to the user (possible values: left, right, both) -The fourth variable visiblePartY detects which vertical part of the element is visible to the user (possible values: top, bottom, both) -bc.. $('div').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { +bc.. $('div').bind('inview', function(event, isInView) { if (isInView) { // element is now visible in the viewport - if (visiblePartY == 'top') { - // top part of element is visible - } else if (visiblePartY == 'bottom') { - // bottom part of element is visible - } else { - // whole part of element is visible - } } else { // element has gone out of viewport } @@ -55,41 +46,9 @@ bc.. // Assuming that all images have set the 'data-src' attribute instead of t $this.removeAttr("data-src"); }); -h2. More complex example - -This way we can attach inview to some DIV in our code to, for example, detect when it FULLY readed by user (user sees it's bottom and top) and only after 1 seconds of view, so after we call some out stats function or whatever - -bc.. $(someMyOneDiv).bind('inview', function(e, isInView, visiblePartX, visiblePartY) { - var elem = $(this); - - if (elem.data('inviewtimer')) { - clearTimeout(elem.data('inviewtimer')); - elem.removeData('inviewtimer'); - } - - if (isInView) { - elem.data('inviewtimer', setTimeout(function() { - if (visiblePartY == 'top') { - elem.data('seenTop', true); - } else if (visiblePartY == 'bottom') { - elem.data('seenBottom', true); - } else { - elem.data('seenTop', true); - elem.data('seenBottom', true); - } - - if (elem.data('seenTop') && elem.data('seenBottom')) { - elem.unbind('inview'); - // here we will do WHAT WHE NEED (for ex. Call Ajax stats collector) - ... - } - }, 1000)); - } -}); - h2. How it works -An interval in the background checks the position of the elements against the viewport dimensions and the scroll position. +An interval in the background checks the position of the bounding rectangle of elements against the viewport dimensions and the scroll position. However, I wanted to create a utility that would only check the elements that were registered under the 'inview' event, i.e. I didn't want to keep checking the element list if we unbind from the event. @@ -102,22 +61,7 @@ h2. Use cases * Reduce http requests and traffic on server by loading assets (images, javascript, html, ...) only when they are visible to the user * Endless scrolling (twitter-like) * Tracking (eg. to see whether a user has read an entire article) -* ... h2. Browser Compatibility -h4. The Test Suite succeeds in the following browsers that were tested: - -* Firefox 3+ -* Safari 3+ -* Chrome 7+ -* Opera 10+ -* IE 6+ -* Mobile Safari on iPad 4.2.2 -* Fennec 4b on Android 2.2 -* Opera Mobile 10.1b on Android 2.2 - -h4. The Test Suite doesn't completely succeed but the demos in this repository work without problems in the following browsers: - -* Mobile WebKit on Android 2.2 -* Mobile WebKit on Palm Pre 1 \ No newline at end of file +Haven't had a chance to test this yet, but the cornerstone of this plugin, getBoundingClientRect, should work in any modern browser as well as IE7+ \ No newline at end of file From 210deb8267c9b9def6777a441e62b39f70c21358 Mon Sep 17 00:00:00 2001 From: Matthew Frey Date: Mon, 27 Jan 2014 15:21:54 -0800 Subject: [PATCH 3/9] Removing tests and updating gitignore --- .gitignore | 1 - test/index.html | 44 ------ test/test.js | 356 ------------------------------------------------ 3 files changed, 401 deletions(-) delete mode 100644 test/index.html delete mode 100644 test/test.js diff --git a/.gitignore b/.gitignore index 2117f73..e69de29 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +0,0 @@ -.tm_sync.config \ No newline at end of file diff --git a/test/index.html b/test/index.html deleted file mode 100644 index 58f5689..0000000 --- a/test/index.html +++ /dev/null @@ -1,44 +0,0 @@ - - - - - - QUnit Test Suite - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

QUnit Test Suite

-

-
-

-
    - - \ No newline at end of file diff --git a/test/test.js b/test/test.js deleted file mode 100644 index 598034d..0000000 --- a/test/test.js +++ /dev/null @@ -1,356 +0,0 @@ -QUnit.config.reorder = false; - -window['jQuery 1.6'].each(['jQuery 1.4', 'jQuery 1.5', 'jQuery 1.6', 'jQuery 1.7', 'jQuery 1.8'], function(i, version) { - var jQuery = window[version], - $ = jQuery; - - module('jquery.inview - ' + version, { - setup: function() { - $(window).scrollTop(0).scrollLeft(0); - - this.size = 20000; - this.container = $('
    ', { - "class": 'test-container' - }).appendTo("body"); - - this.element = $('
    ', { - html: 'testing ...', - "class": 'test-element' - }).css({ - background: '#eee', - width: '50px', - height: '50px', - position: 'absolute' - }); - - this.element2 = this.element.clone(); - }, - - teardown: function() { - $(window).scrollTop(0).scrollLeft(0); - - this.container.remove(); - this.element.remove(); - } - }); - - - asyncTest('Check vertical scrolling', function() { - expect(5); - - var element = this.element, - firstCall, - secondCall, - thirdCall, - inView; - - element.css({ left: 0, top: this.size - 50 + 'px' }); - element.appendTo('body'); - element.bind('inview.firstCall', function() { firstCall = true; }); - - setTimeout(function() { - $(window).scrollTop(0).scrollLeft(0); - ok(!firstCall, 'inview shouldn\'t be triggered initially when the element isn\'t in the viewport'); - element.unbind('inview.firstCall'); - element.bind('inview.secondCall', function(event, inViewParam) { - secondCall = true; - inView = inViewParam; - }); - - $(window).scrollTop(9999999); - - setTimeout(function() { - - ok(secondCall, 'Triggered handler after element appeared in viewport'); - ok(inView, 'Parameter, indicating whether the element is in the viewport, is set to "true"'); - element.unbind('inview.secondCall'); - element.bind('inview.thirdCall', function(event, inViewParam) { - thirdCall = true; - inView = inViewParam; - }); - - $(window).scrollTop(0).scrollLeft(0); - - setTimeout(function() { - ok(thirdCall, 'Triggered handler after element disappeared in viewport'); - strictEqual(inView, false, 'Parameter, indicating whether the element is in the viewport, is set to "false"'); - start(); - }, 1000); - - }, 1000); - - }, 1000); - }); - - - asyncTest('Check horizontal scrolling', function() { - expect(5); - - var element = this.element, - firstCall, - secondCall, - thirdCall, - inView; - - element.css({ top: 0, left: this.size - 50 + 'px' }); - element.appendTo('body'); - element.bind('inview.firstCall', function() { firstCall = true; }); - - setTimeout(function() { - $(window).scrollTop(0).scrollLeft(0); - - ok(!firstCall, 'inview shouldn\'t be triggered initially when the element isn\'t in the viewport'); - element.unbind('inview.firstCall'); - element.bind('inview.secondCall', function(event, inViewParam) { - secondCall = true; - inView = inViewParam; - }); - - $(window).scrollLeft(9999999); - - setTimeout(function() { - - ok(secondCall, 'Triggered handler after element appeared in viewport'); - ok(inView, 'Parameter, indicating whether the element is in the viewport, is set to "true"'); - element.unbind('inview.secondCall'); - element.bind('inview.thirdCall', function(event, inViewParam) { - thirdCall = true; - inView = inViewParam; - }); - - $(window).scrollTop(0).scrollLeft(0); - - setTimeout(function() { - ok(thirdCall, 'Triggered handler after element disappeared in viewport'); - strictEqual(inView, false, 'Parameter, indicating whether the element is in the viewport, is set to "false"'); - start(); - }, 1000); - - }, 1000); - - }, 1000); - }); - - - asyncTest('Move element into viewport without scrolling', function() { - expect(3); - - var element = this.element, calls = 0; - - element - .css({ left: '-500px', top: 0 }) - .appendTo('body') - .bind('inview', function(event) { calls++; }); - - setTimeout(function() { - - equal(calls, 0, 'Callback hasn\'t been fired since the element isn\'t in the viewport'); - element.css({ left: 0 }); - - setTimeout(function() { - - equal(calls, 1, 'Callback has been fired after the element appeared in the viewport'); - element.css({ left: '10000px' }); - - setTimeout(function() { - - equal(calls, 2, 'Callback has been fired after the element disappeared from viewport'); - start(); - - }, 1000); - - }, 1000); - - }, 1000); - }); - - - asyncTest('Check whether element which isn\'t in the dom tree triggers the callback', function() { - expect(0); - - this.element.bind('inview', function(event, isInView) { - ok(false, 'Callback shouldn\'t be fired since the element isn\'t even in the dom tree'); - start(); - }); - - setTimeout(function() { start(); }, 1000); - }); - - - asyncTest('Check whether element which is on the top outside of viewport is not firing the event', function() { - expect(0); - - this.element.bind('inview', function(event, isInView) { - ok(false, 'Callback shouldn\'t be fired since the element is outside of viewport'); - start(); - }); - - this.element.css({ - top: '-50px', - left: '50px' - }).appendTo('body'); - - setTimeout(function() { start(); }, 1000); - }); - - - asyncTest('Check whether element which is on the left outside of viewport is not firing the event', function() { - expect(0); - - this.element.bind('inview', function(event, isInView) { - ok(false, 'Callback shouldn\'t be fired since the element is outside of viewport'); - start(); - }); - - this.element.css({ - top: '50px', - left: '-50px' - }).appendTo('body'); - - setTimeout(function() { start(); }, 1000); - }); - - - asyncTest('Check visiblePartX & visiblePartY parameters #1', function() { - expect(2); - - this.element.css({ - top: '-25px', - left: '-25px' - }).appendTo('body'); - - this.element.bind('inview', function(event, isInView, visiblePartX, visiblePartY) { - equal(visiblePartX, 'right', 'visiblePartX has correct value'); - equal(visiblePartY, 'bottom', 'visiblePartY has correct value'); - start(); - }); - }); - - - asyncTest('Check visiblePartX & visiblePartY parameters #2', function() { - expect(2); - - this.element.css({ - top: '0', - left: '-25px' - }).appendTo('body'); - - this.element.bind('inview', function(event, isInView, visiblePartX, visiblePartY) { - equal(visiblePartX, 'right', 'visiblePartX has correct value'); - equal(visiblePartY, 'both', 'visiblePartY has correct value'); - start(); - }); - }); - - - asyncTest('Check visiblePartX & visiblePartY parameters #3', function() { - expect(2); - - this.element.css({ - top: '0', - left: '0' - }).appendTo('body'); - - this.element.bind('inview', function(event, isInView, visiblePartX, visiblePartY) { - equal(visiblePartX, 'both', 'visiblePartX has correct value'); - equal(visiblePartY, 'both', 'visiblePartY has correct value'); - start(); - }); - }); - - - asyncTest('Check "live" events', function() { - expect(3); - - var that = this, - elems = $("body .test-container > div.test-element"); - elems.live("inview", function(event) { - elems.die("inview"); - ok(true, "Live event correctly fired"); - equal(event.currentTarget, that.element[0], "event.currentTarget correctly set"); - equal(this, that.element[0], "Handler bound to target element"); - start(); - }); - - this.element.css({ - top: '0', - left: '0' - }).appendTo(this.container); - }); - - - asyncTest('Check "delegate" events', function() { - expect(3); - - var that = this; - this.container.delegate(".test-element", "inview", function(event) { - ok(true, "Delegated event correctly fired"); - equal(event.currentTarget, that.element[0], "event.currentTarget correctly set"); - equal(this, that.element[0], "Handler bound to target element"); - start(); - }); - - this.element.css({ - top: '0', - left: '0' - }).appendTo(this.container); - }); - - - asyncTest('Check namespaced "delegate" events', function() { - expect(1); - - this.container.delegate(".test-element", "inview.foo", function(event) { - ok(true, "Delegated event correctly fired"); - start(); - }); - - this.element.css({ - top: '0', - left: '0' - }).appendTo(this.container); - }); - - - asyncTest('Check multiple elements', function() { - expect(2); - - var i = 0; - - this.element.add(this.element2).css({ - top: '0', - left: '0' - }).appendTo(this.container); - - $('.test-element').bind('inview', function() { - ok(true); - if (++i == 2) { - start(); - } - }); - }); - - if (!("ontouchstart" in window)) { - asyncTest('Scroll to element via focus()', function() { - // This test will fail on iOS - - expect(1); - - var $input = $("").css({ - position: "absolute", - top: "7000px", - left: "5000px" - }).appendTo(this.container); - - $input.bind('inview', function() { - ok(true); - $input.remove(); - start(); - }); - - setTimeout(function() { - $input.focus(); - }, 1000); - }); - } -}); From 1c23be077441a9e7290f8bccfcb0f8d51210876f Mon Sep 17 00:00:00 2001 From: Matthew Frey Date: Mon, 27 Jan 2014 15:33:22 -0800 Subject: [PATCH 4/9] Fixing some typos --- jquery.inview.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/jquery.inview.js b/jquery.inview.js index 041024f..a051487 100644 --- a/jquery.inview.js +++ b/jquery.inview.js @@ -44,7 +44,7 @@ function checkInView() { // Fuck IE and its quirks, we're doing this the right way. - var $elements = $(), elementsLength, i = 0; + var $elements = $(); $.each(inviewObjects, function(i, inviewObject) { var selector = inviewObject.data.selector, @@ -52,7 +52,7 @@ $elements = $elements.add(selector ? $element.find(selector) : $element); }); - if (elements.length) { + if ($elements.length) { for (var i = 0; i < $elements.length; i++) { if (!$elements[i]) { continue; @@ -61,9 +61,9 @@ continue; } - var el = $elements[i], - inView = el.data('inview'), - rect = el.getBoundingClientRect(); + var $el = $($elements[i]), + inView = $el.data('inview'), + rect = $el[0].getBoundingClientRect(); if (rect.top >= 0 && rect.left >= 0 && @@ -71,11 +71,11 @@ rect.right <= (w.innerWidth || documentElement.clientWidth)) { if (!inView) { // object has entered viewport - $element.data('inview', true).trigger('inview', [true]); + $el.data('inview', true).trigger('inview', [true]); } } else if (inView) { // object has left viewport - $element.data('inview', false).trigger('inview', [false]); + $el.data('inview', false).trigger('inview', [false]); } } } From 855d859d713a0aac5bf98cbadf6fad12773e1d56 Mon Sep 17 00:00:00 2001 From: Matthew Frey Date: Mon, 27 Jan 2014 15:33:31 -0800 Subject: [PATCH 5/9] Increasing delay --- jquery.inview.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jquery.inview.js b/jquery.inview.js index a051487..ace27d3 100644 --- a/jquery.inview.js +++ b/jquery.inview.js @@ -27,7 +27,7 @@ // Don't waste cycles with an interval until we get at least one element that // has bound to the inview event. if (!timer && !$.isEmptyObject(inviewObjects)) { - timer = setInterval(checkInView, 250); + timer = setInterval(checkInView, 333); } }, From 88c994fbd1cfbccb9f7a71e7511f62f0e9465072 Mon Sep 17 00:00:00 2001 From: Matthew Frey Date: Mon, 27 Jan 2014 15:35:36 -0800 Subject: [PATCH 6/9] Renaming file and updating minified version --- jquery.inview.min.js | 7 ------- jquery.inview.js => jquery.inview2.js | 0 jquery.inview2.min.js | 7 +++++++ 3 files changed, 7 insertions(+), 7 deletions(-) delete mode 100644 jquery.inview.min.js rename jquery.inview.js => jquery.inview2.js (100%) create mode 100644 jquery.inview2.min.js diff --git a/jquery.inview.min.js b/jquery.inview.min.js deleted file mode 100644 index c17b752..0000000 --- a/jquery.inview.min.js +++ /dev/null @@ -1,7 +0,0 @@ -/** - * Jquery Inview 2 - * Version: 0.1 - * Author: Matthew Frey (mmmeff) - * - forked from http://github.com/protonet/jquery.inview/ - */ -(function(e){function t(){var t=e(),i=0;if(e.each(n,function(e,i){var n=i.data.selector,a=i.$element;t=t.add(n?a.find(n):a)}),elements.length)for(var i=0;t.length>i;i++)if(t[i])if(e.contains(d,t[i])){var a=t[i],r=a.data("inview"),c=a.getBoundingClientRect();c.top>=0&&c.left>=0&&c.bottom<=(l.innerHeight||d.clientHeight)&&c.right<=(l.innerWidth||d.clientWidth)?r||$element.data("inview",!0).trigger("inview",[!0]):r&&$element.data("inview",!1).trigger("inview",[!1])}else delete t[i]}var i,n={},a=document,l=window,d=a.documentElement,r=e.expando;e.event.special.inview={add:function(a){n[a.guid+"-"+this[r]]={data:a,$element:e(this)},i||e.isEmptyObject(n)||(i=setInterval(t,250))},remove:function(t){try{delete n[t.guid+"-"+this[r]]}catch(a){}e.isEmptyObject(n)&&(clearInterval(i),i=null)}}})(jQuery); \ No newline at end of file diff --git a/jquery.inview.js b/jquery.inview2.js similarity index 100% rename from jquery.inview.js rename to jquery.inview2.js diff --git a/jquery.inview2.min.js b/jquery.inview2.min.js new file mode 100644 index 0000000..e862678 --- /dev/null +++ b/jquery.inview2.min.js @@ -0,0 +1,7 @@ +/** + * Jquery Inview 2 + * Version: 0.1 + * Author: Matthew Frey (mmmeff) + * - forked from http://github.com/protonet/jquery.inview/ + */ +(function(e){function t(){var t=e();if(e.each(n,function(e,i){var n=i.data.selector,a=i.$element;t=t.add(n?a.find(n):a)}),t.length)for(var i=0;t.length>i;i++)if(t[i])if(e.contains(r,t[i])){var a=e(t[i]),c=a.data("inview"),l=a[0].getBoundingClientRect();l.top>=0&&l.left>=0&&l.bottom<=(d.innerHeight||r.clientHeight)&&l.right<=(d.innerWidth||r.clientWidth)?c||a.data("inview",!0).trigger("inview",[!0]):c&&a.data("inview",!1).trigger("inview",[!1])}else delete t[i]}var i,n={},a=document,d=window,r=a.documentElement,c=e.expando;e.event.special.inview={add:function(a){n[a.guid+"-"+this[c]]={data:a,$element:e(this)},i||e.isEmptyObject(n)||(i=setInterval(t,333))},remove:function(t){try{delete n[t.guid+"-"+this[c]]}catch(a){}e.isEmptyObject(n)&&(clearInterval(i),i=null)}}})(jQuery); \ No newline at end of file From ffe73991be44418705e3be2d4ad70cdf8a5e7180 Mon Sep 17 00:00:00 2001 From: Matthew Frey Date: Mon, 27 Jan 2014 15:36:34 -0800 Subject: [PATCH 7/9] Deleted examples until I get some time to rewrite them --- example/advanced.html | 46 ----------------- example/live_event.html | 98 ------------------------------------- example/simple_example.html | 49 ------------------- 3 files changed, 193 deletions(-) delete mode 100644 example/advanced.html delete mode 100644 example/live_event.html delete mode 100644 example/simple_example.html diff --git a/example/advanced.html b/example/advanced.html deleted file mode 100644 index 7fb0618..0000000 --- a/example/advanced.html +++ /dev/null @@ -1,46 +0,0 @@ - - - - jquery.inview - Example - - - - - - - Scroll to the middle of this page! -
    -
    visiblePartX:
    -
    visiblePartY:
    -
    - - - - \ No newline at end of file diff --git a/example/live_event.html b/example/live_event.html deleted file mode 100644 index f273f87..0000000 --- a/example/live_event.html +++ /dev/null @@ -1,98 +0,0 @@ - -jquery.inview - live events - - - - -

    Flickr search results for 'lolcat'

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/example/simple_example.html b/example/simple_example.html deleted file mode 100644 index 4a3507a..0000000 --- a/example/simple_example.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - jquery.inview - Example - - - - - - -

    jquery.inview - Example

    -

    Scroll to the right and to the bottom

    - - visible! - visible! - - - - \ No newline at end of file From 101bb8d10b087e82dc04e1e76317a057a0a1edd1 Mon Sep 17 00:00:00 2001 From: Matthew Frey Date: Mon, 27 Jan 2014 16:04:36 -0800 Subject: [PATCH 8/9] Capturing partially visible elements --- jquery.inview2.js | 12 +++++++----- jquery.inview2.min.js | 2 +- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/jquery.inview2.js b/jquery.inview2.js index ace27d3..0ac373f 100644 --- a/jquery.inview2.js +++ b/jquery.inview2.js @@ -63,12 +63,14 @@ var $el = $($elements[i]), inView = $el.data('inview'), - rect = $el[0].getBoundingClientRect(); + rect = $el[0].getBoundingClientRect(), + height = $el.height(), + width = $el.width(); - if (rect.top >= 0 && - rect.left >= 0 && - rect.bottom <= (w.innerHeight || documentElement.clientHeight) && - rect.right <= (w.innerWidth || documentElement.clientWidth)) { + if (rect.top >= (0 - height) && + rect.left >= (0 - width) && + rect.bottom <= ((w.innerHeight || documentElement.clientHeight) + height) && + rect.right <= ((w.innerWidth || documentElement.clientWidth) + width)) { if (!inView) { // object has entered viewport $el.data('inview', true).trigger('inview', [true]); diff --git a/jquery.inview2.min.js b/jquery.inview2.min.js index e862678..b5a4aca 100644 --- a/jquery.inview2.min.js +++ b/jquery.inview2.min.js @@ -4,4 +4,4 @@ * Author: Matthew Frey (mmmeff) * - forked from http://github.com/protonet/jquery.inview/ */ -(function(e){function t(){var t=e();if(e.each(n,function(e,i){var n=i.data.selector,a=i.$element;t=t.add(n?a.find(n):a)}),t.length)for(var i=0;t.length>i;i++)if(t[i])if(e.contains(r,t[i])){var a=e(t[i]),c=a.data("inview"),l=a[0].getBoundingClientRect();l.top>=0&&l.left>=0&&l.bottom<=(d.innerHeight||r.clientHeight)&&l.right<=(d.innerWidth||r.clientWidth)?c||a.data("inview",!0).trigger("inview",[!0]):c&&a.data("inview",!1).trigger("inview",[!1])}else delete t[i]}var i,n={},a=document,d=window,r=a.documentElement,c=e.expando;e.event.special.inview={add:function(a){n[a.guid+"-"+this[c]]={data:a,$element:e(this)},i||e.isEmptyObject(n)||(i=setInterval(t,333))},remove:function(t){try{delete n[t.guid+"-"+this[c]]}catch(a){}e.isEmptyObject(n)&&(clearInterval(i),i=null)}}})(jQuery); \ No newline at end of file +(function(e){function t(){var t=e();if(e.each(n,function(e,i){var n=i.data.selector,a=i.$element;t=t.add(n?a.find(n):a)}),t.length)for(var i=0;t.length>i;i++)if(t[i])if(e.contains(r,t[i])){var a=e(t[i]),c=a.data("inview"),l=a[0].getBoundingClientRect(),o=a.height(),h=a.width();l.top>=0-o&&l.left>=0-h&&l.bottom<=(d.innerHeight||r.clientHeight)+o&&l.right<=(d.innerWidth||r.clientWidth)+h?c||a.data("inview",!0).trigger("inview",[!0]):c&&a.data("inview",!1).trigger("inview",[!1])}else delete t[i]}var i,n={},a=document,d=window,r=a.documentElement,c=e.expando;e.event.special.inview={add:function(a){n[a.guid+"-"+this[c]]={data:a,$element:e(this)},i||e.isEmptyObject(n)||(i=setInterval(t,333))},remove:function(t){try{delete n[t.guid+"-"+this[c]]}catch(a){}e.isEmptyObject(n)&&(clearInterval(i),i=null)}}})(jQuery); \ No newline at end of file From a5d303da501ddacf3bb9a1d91cfee2abebc1cb3c Mon Sep 17 00:00:00 2001 From: Matthew Frey Date: Mon, 27 Jan 2014 16:46:18 -0800 Subject: [PATCH 9/9] Added margin control to events - detect if a viewport is x units outside of the viewport --- jquery.inview2.js | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/jquery.inview2.js b/jquery.inview2.js index 0ac373f..d171155 100644 --- a/jquery.inview2.js +++ b/jquery.inview2.js @@ -10,7 +10,10 @@ w = window, documentElement = d.documentElement, expando = $.expando, - timer; + timer, + // pixel count margins to wrap viewport (negative gives extra time for dom to render) + yMargin = -300, + xMargin = 0; $.event.special.inview = { add: function(data) { @@ -49,6 +52,7 @@ $.each(inviewObjects, function(i, inviewObject) { var selector = inviewObject.data.selector, $element = inviewObject.$element; + $elements = $elements.add(selector ? $element.find(selector) : $element); }); @@ -67,10 +71,10 @@ height = $el.height(), width = $el.width(); - if (rect.top >= (0 - height) && - rect.left >= (0 - width) && - rect.bottom <= ((w.innerHeight || documentElement.clientHeight) + height) && - rect.right <= ((w.innerWidth || documentElement.clientWidth) + width)) { + if (rect.top >= (0 - height + yMargin) && + rect.left >= (0 - width + xMargin) && + rect.bottom <= ((w.innerHeight || documentElement.clientHeight) + height - yMargin) && + rect.right <= ((w.innerWidth || documentElement.clientWidth) + width - xMargin)) { if (!inView) { // object has entered viewport $el.data('inview', true).trigger('inview', [true]);