├── .gitignore ├── bower.json ├── LICENSE ├── example ├── simple_example.html ├── advanced.html └── live_event.html ├── jquery.inview.min.js ├── test ├── index.html └── test.js ├── README.textile └── jquery.inview.js /.gitignore: -------------------------------------------------------------------------------- 1 | .tm_sync.config -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "protonet/jquery.inview", 3 | "version": "1.0.0", 4 | "main": "jquery.inview.js", 5 | "description": "jQuery event that is fired as soon as an element appears in the user's viewport." 6 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. -------------------------------------------------------------------------------- /example/simple_example.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jquery.inview - Example 5 | 6 | 7 | 8 | 31 | 32 | 33 |

jquery.inview - Example

34 |

Scroll to the right and to the bottom

35 | 36 | visible! 37 | visible! 38 | 39 | 48 | 49 | -------------------------------------------------------------------------------- /example/advanced.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | jquery.inview - Example 5 | 6 | 7 | 8 | 27 | 28 | 29 | Scroll to the middle of this page! 30 |
31 |
visiblePartX:
32 |
visiblePartY:
33 |
34 | 35 | 45 | 46 | -------------------------------------------------------------------------------- /jquery.inview.min.js: -------------------------------------------------------------------------------- 1 | !function(t){"function"==typeof define&&define.amd?define(["jquery"],t):t(jQuery)}(function(t){function e(){var e,i,n={height:r.innerHeight,width:r.innerWidth};return n.height||(e=f.compatMode,(e||!t.support.boxModel)&&(i="CSS1Compat"===e?a:f.body,n={height:i.clientHeight,width:i.clientWidth})),n}function i(){return{top:r.pageYOffset||a.scrollTop||f.body.scrollTop,left:r.pageXOffset||a.scrollLeft||f.body.scrollLeft}}function n(){var n,l=t(),f=0;if(t.each(d,function(t,e){var i=e.data.selector,n=e.$element;l=l.add(i?n.find(i):n)}),n=l.length)for(o=o||e(),h=h||i();n>f;f++)if(t.contains(a,l[f])){var r,c,u,p=t(l[f]),s={height:p.height(),width:p.width()},g=p.offset(),v=p.data("inview");if(!h||!o)return;g.top+s.height>h.top&&g.toph.left&&g.leftg.left?"right":h.left+o.widthg.top?"bottom":h.top+o.height 2 | 3 | 4 | 5 | 6 | QUnit Test Suite 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 |

QUnit Test Suite

39 |

40 |
41 |

42 |
    43 | 44 | -------------------------------------------------------------------------------- /README.textile: -------------------------------------------------------------------------------- 1 | h1. Element 'inview' Event Plugin 2 | 3 | Event that is fired as soon as an element appears in the user's viewport. 4 | 5 | *Author:* "Christopher Blum":http://twitter.com/ChristopherBlum 6 | *Original idea and concept by:* "Remy Sharp":http://remysharp.com/2009/01/26/element-in-view-event-plugin/ 7 | *Forked from:* "https://github.com/zuk/jquery.inview/":https://github.com/zuk/jquery.inview/ 8 | *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 9 | *Requires:* jQuery 1.4+ 10 | 11 | h2. Usage 12 | 13 | The script makes use of the new $.contains method - so it will only work with jQuery 1.4 upwards. If you need to use it with older versions of jQuery, drop a comment, and I'll post an alternative. 14 | 15 | 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. 16 | 17 | The variable after the event argument indicates the visible state in the viewport. 18 | The third variable visiblePartX detects which horizontal part of the element is visible to the user (possible values: left, right, both) 19 | The fourth variable visiblePartY detects which vertical part of the element is visible to the user (possible values: top, bottom, both) 20 | 21 | bc.. $('div').bind('inview', function(event, isInView, visiblePartX, visiblePartY) { 22 | if (isInView) { 23 | // element is now visible in the viewport 24 | if (visiblePartY == 'top') { 25 | // top part of element is visible 26 | } else if (visiblePartY == 'bottom') { 27 | // bottom part of element is visible 28 | } else { 29 | // whole part of element is visible 30 | } 31 | } else { 32 | // element has gone out of viewport 33 | } 34 | }); 35 | 36 | p. To stop listening for the event - simply unbind: 37 | 38 | bc.. $('div').unbind('inview'); 39 | 40 | p. Remember you can also bind once: 41 | 42 | bc.. $('div').one('inview', fn); 43 | 44 | h2. Live events 45 | 46 | Yep, inview events can also be used with .live/.delegate methods. 47 | _Please note that this could slow down your app when the selector is too complex and/or matches a huge set of elements._ 48 | The following code snippet only loads images when they appear in the browser's viewport. 49 | 50 | bc.. // Assuming that all images have set the 'data-src' attribute instead of the 'src'attribute 51 | $("img[data-src]").live("inview", function() { 52 | var $this = $(this); 53 | $this.attr("src", $this.attr("data-src")); 54 | // Remove it from the set of matching elements in order to avoid that the handler gets re-executed 55 | $this.removeAttr("data-src"); 56 | }); 57 | 58 | h2. More complex example 59 | 60 | 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 61 | 62 | bc.. $(someMyOneDiv).bind('inview', function(e, isInView, visiblePartX, visiblePartY) { 63 | var elem = $(this); 64 | 65 | if (elem.data('inviewtimer')) { 66 | clearTimeout(elem.data('inviewtimer')); 67 | elem.removeData('inviewtimer'); 68 | } 69 | 70 | if (isInView) { 71 | elem.data('inviewtimer', setTimeout(function() { 72 | if (visiblePartY == 'top') { 73 | elem.data('seenTop', true); 74 | } else if (visiblePartY == 'bottom') { 75 | elem.data('seenBottom', true); 76 | } else { 77 | elem.data('seenTop', true); 78 | elem.data('seenBottom', true); 79 | } 80 | 81 | if (elem.data('seenTop') && elem.data('seenBottom')) { 82 | elem.unbind('inview'); 83 | // here we will do WHAT WHE NEED (for ex. Call Ajax stats collector) 84 | ... 85 | } 86 | }, 1000)); 87 | } 88 | }); 89 | 90 | h2. How it works 91 | 92 | An interval in the background checks the position of the elements against the viewport dimensions and the scroll position. 93 | 94 | 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. 95 | 96 | This is achieved by dipping in to the $.cache store within jQuery, and looping through, looking for the elements tied to the 'inview' event. 97 | 98 | This way the user can treat it like a native event on the page. 99 | 100 | h2. Use cases 101 | 102 | * Reduce http requests and traffic on server by loading assets (images, javascript, html, ...) only when they are visible to the user 103 | * Endless scrolling (twitter-like) 104 | * Tracking (eg. to see whether a user has read an entire article) 105 | * ... 106 | 107 | h2. Browser Compatibility 108 | 109 | h4. The Test Suite succeeds in the following browsers that were tested: 110 | 111 | * Firefox 3+ 112 | * Safari 3+ 113 | * Chrome 7+ 114 | * Opera 10+ 115 | * IE 6+ 116 | * Mobile Safari on iPad 4.2.2 117 | * Fennec 4b on Android 2.2 118 | * Opera Mobile 10.1b on Android 2.2 119 | 120 | h4. The Test Suite doesn't completely succeed but the demos in this repository work without problems in the following browsers: 121 | 122 | * Mobile WebKit on Android 2.2 123 | * Mobile WebKit on Palm Pre 1 -------------------------------------------------------------------------------- /jquery.inview.js: -------------------------------------------------------------------------------- 1 | /** 2 | * author Christopher Blum 3 | * - based on the idea of Remy Sharp, http://remysharp.com/2009/01/26/element-in-view-event-plugin/ 4 | * - forked from http://github.com/zuk/jquery.inview/ 5 | */ 6 | (function (factory) { 7 | if (typeof define === 'function' && define.amd) { 8 | // AMD. Register as an anonymous module. 9 | define(['jquery'], factory); 10 | } else { 11 | // Browser globals 12 | factory(jQuery); 13 | } 14 | }(function ($) { 15 | var inviewObjects = {}, viewportSize, viewportOffset, 16 | d = document, w = window, documentElement = d.documentElement, expando = $.expando, timer; 17 | 18 | $.event.special.inview = { 19 | add: function(data) { 20 | inviewObjects[data.guid + "-" + this[expando]] = { data: data, $element: $(this) }; 21 | 22 | // Use setInterval in order to also make sure this captures elements within 23 | // "overflow:scroll" elements or elements that appeared in the dom tree due to 24 | // dom manipulation and reflow 25 | // old: $(window).scroll(checkInView); 26 | // 27 | // By the way, iOS (iPad, iPhone, ...) seems to not execute, or at least delays 28 | // intervals while the user scrolls. Therefore the inview event might fire a bit late there 29 | // 30 | // Don't waste cycles with an interval until we get at least one element that 31 | // has bound to the inview event. 32 | if (!timer && !$.isEmptyObject(inviewObjects)) { 33 | timer = setInterval(checkInView, 250); 34 | } 35 | }, 36 | 37 | remove: function(data) { 38 | try { delete inviewObjects[data.guid + "-" + this[expando]]; } catch(e) {} 39 | 40 | // Clear interval when we no longer have any elements listening 41 | if ($.isEmptyObject(inviewObjects)) { 42 | clearInterval(timer); 43 | timer = null; 44 | } 45 | } 46 | }; 47 | 48 | function getViewportSize() { 49 | var mode, domObject, size = { height: w.innerHeight, width: w.innerWidth }; 50 | 51 | // if this is correct then return it. iPad has compat Mode, so will 52 | // go into check clientHeight/clientWidth (which has the wrong value). 53 | if (!size.height) { 54 | mode = d.compatMode; 55 | if (mode || !$.support.boxModel) { // IE, Gecko 56 | domObject = mode === 'CSS1Compat' ? 57 | documentElement : // Standards 58 | d.body; // Quirks 59 | size = { 60 | height: domObject.clientHeight, 61 | width: domObject.clientWidth 62 | }; 63 | } 64 | } 65 | 66 | return size; 67 | } 68 | 69 | function getViewportOffset() { 70 | return { 71 | top: w.pageYOffset || documentElement.scrollTop || d.body.scrollTop, 72 | left: w.pageXOffset || documentElement.scrollLeft || d.body.scrollLeft 73 | }; 74 | } 75 | 76 | function checkInView() { 77 | var $elements = $(), elementsLength, i = 0; 78 | 79 | $.each(inviewObjects, function(i, inviewObject) { 80 | var selector = inviewObject.data.selector, 81 | $element = inviewObject.$element; 82 | $elements = $elements.add(selector ? $element.find(selector) : $element); 83 | }); 84 | 85 | elementsLength = $elements.length; 86 | if (elementsLength) { 87 | viewportSize = viewportSize || getViewportSize(); 88 | viewportOffset = viewportOffset || getViewportOffset(); 89 | 90 | for (; i viewportOffset.top && 114 | elementOffset.top < viewportOffset.top + viewportSize.height && 115 | elementOffset.left + elementSize.width > viewportOffset.left && 116 | elementOffset.left < viewportOffset.left + viewportSize.width) { 117 | visiblePartX = (viewportOffset.left > elementOffset.left ? 118 | 'right' : (viewportOffset.left + viewportSize.width) < (elementOffset.left + elementSize.width) ? 119 | 'left' : 'both'); 120 | visiblePartY = (viewportOffset.top > elementOffset.top ? 121 | 'bottom' : (viewportOffset.top + viewportSize.height) < (elementOffset.top + elementSize.height) ? 122 | 'top' : 'both'); 123 | visiblePartsMerged = visiblePartX + "-" + visiblePartY; 124 | if (!inView || inView !== visiblePartsMerged) { 125 | $element.data('inview', visiblePartsMerged).trigger('inview', [true, visiblePartX, visiblePartY]); 126 | } 127 | } else if (inView) { 128 | $element.data('inview', false).trigger('inview', [false]); 129 | } 130 | } 131 | } 132 | } 133 | 134 | $(w).bind("scroll resize scrollstop", function() { 135 | viewportSize = viewportOffset = null; 136 | }); 137 | 138 | // IE < 9 scrolls to focused elements without firing the "scroll" event 139 | if (!documentElement.addEventListener && documentElement.attachEvent) { 140 | documentElement.attachEvent("onfocusin", function() { 141 | viewportOffset = null; 142 | }); 143 | } 144 | })); 145 | -------------------------------------------------------------------------------- /test/test.js: -------------------------------------------------------------------------------- 1 | QUnit.config.reorder = false; 2 | 3 | window['jQuery 1.6'].each(['jQuery 1.4', 'jQuery 1.5', 'jQuery 1.6', 'jQuery 1.7', 'jQuery 1.8'], function(i, version) { 4 | var jQuery = window[version], 5 | $ = jQuery; 6 | 7 | module('jquery.inview - ' + version, { 8 | setup: function() { 9 | $(window).scrollTop(0).scrollLeft(0); 10 | 11 | this.size = 20000; 12 | this.container = $('
    ', { 13 | "class": 'test-container' 14 | }).appendTo("body"); 15 | 16 | this.element = $('
    ', { 17 | html: 'testing ...', 18 | "class": 'test-element' 19 | }).css({ 20 | background: '#eee', 21 | width: '50px', 22 | height: '50px', 23 | position: 'absolute' 24 | }); 25 | 26 | this.element2 = this.element.clone(); 27 | }, 28 | 29 | teardown: function() { 30 | $(window).scrollTop(0).scrollLeft(0); 31 | 32 | this.container.remove(); 33 | this.element.remove(); 34 | } 35 | }); 36 | 37 | 38 | asyncTest('Check vertical scrolling', function() { 39 | expect(5); 40 | 41 | var element = this.element, 42 | firstCall, 43 | secondCall, 44 | thirdCall, 45 | inView; 46 | 47 | element.css({ left: 0, top: this.size - 50 + 'px' }); 48 | element.appendTo('body'); 49 | element.bind('inview.firstCall', function() { firstCall = true; }); 50 | 51 | setTimeout(function() { 52 | $(window).scrollTop(0).scrollLeft(0); 53 | ok(!firstCall, 'inview shouldn\'t be triggered initially when the element isn\'t in the viewport'); 54 | element.unbind('inview.firstCall'); 55 | element.bind('inview.secondCall', function(event, inViewParam) { 56 | secondCall = true; 57 | inView = inViewParam; 58 | }); 59 | 60 | $(window).scrollTop(9999999); 61 | 62 | setTimeout(function() { 63 | 64 | ok(secondCall, 'Triggered handler after element appeared in viewport'); 65 | ok(inView, 'Parameter, indicating whether the element is in the viewport, is set to "true"'); 66 | element.unbind('inview.secondCall'); 67 | element.bind('inview.thirdCall', function(event, inViewParam) { 68 | thirdCall = true; 69 | inView = inViewParam; 70 | }); 71 | 72 | $(window).scrollTop(0).scrollLeft(0); 73 | 74 | setTimeout(function() { 75 | ok(thirdCall, 'Triggered handler after element disappeared in viewport'); 76 | strictEqual(inView, false, 'Parameter, indicating whether the element is in the viewport, is set to "false"'); 77 | start(); 78 | }, 1000); 79 | 80 | }, 1000); 81 | 82 | }, 1000); 83 | }); 84 | 85 | 86 | asyncTest('Check horizontal scrolling', function() { 87 | expect(5); 88 | 89 | var element = this.element, 90 | firstCall, 91 | secondCall, 92 | thirdCall, 93 | inView; 94 | 95 | element.css({ top: 0, left: this.size - 50 + 'px' }); 96 | element.appendTo('body'); 97 | element.bind('inview.firstCall', function() { firstCall = true; }); 98 | 99 | setTimeout(function() { 100 | $(window).scrollTop(0).scrollLeft(0); 101 | 102 | ok(!firstCall, 'inview shouldn\'t be triggered initially when the element isn\'t in the viewport'); 103 | element.unbind('inview.firstCall'); 104 | element.bind('inview.secondCall', function(event, inViewParam) { 105 | secondCall = true; 106 | inView = inViewParam; 107 | }); 108 | 109 | $(window).scrollLeft(9999999); 110 | 111 | setTimeout(function() { 112 | 113 | ok(secondCall, 'Triggered handler after element appeared in viewport'); 114 | ok(inView, 'Parameter, indicating whether the element is in the viewport, is set to "true"'); 115 | element.unbind('inview.secondCall'); 116 | element.bind('inview.thirdCall', function(event, inViewParam) { 117 | thirdCall = true; 118 | inView = inViewParam; 119 | }); 120 | 121 | $(window).scrollTop(0).scrollLeft(0); 122 | 123 | setTimeout(function() { 124 | ok(thirdCall, 'Triggered handler after element disappeared in viewport'); 125 | strictEqual(inView, false, 'Parameter, indicating whether the element is in the viewport, is set to "false"'); 126 | start(); 127 | }, 1000); 128 | 129 | }, 1000); 130 | 131 | }, 1000); 132 | }); 133 | 134 | 135 | asyncTest('Move element into viewport without scrolling', function() { 136 | expect(3); 137 | 138 | var element = this.element, calls = 0; 139 | 140 | element 141 | .css({ left: '-500px', top: 0 }) 142 | .appendTo('body') 143 | .bind('inview', function(event) { calls++; }); 144 | 145 | setTimeout(function() { 146 | 147 | equal(calls, 0, 'Callback hasn\'t been fired since the element isn\'t in the viewport'); 148 | element.css({ left: 0 }); 149 | 150 | setTimeout(function() { 151 | 152 | equal(calls, 1, 'Callback has been fired after the element appeared in the viewport'); 153 | element.css({ left: '10000px' }); 154 | 155 | setTimeout(function() { 156 | 157 | equal(calls, 2, 'Callback has been fired after the element disappeared from viewport'); 158 | start(); 159 | 160 | }, 1000); 161 | 162 | }, 1000); 163 | 164 | }, 1000); 165 | }); 166 | 167 | 168 | asyncTest('Check whether element which isn\'t in the dom tree triggers the callback', function() { 169 | expect(0); 170 | 171 | this.element.bind('inview', function(event, isInView) { 172 | ok(false, 'Callback shouldn\'t be fired since the element isn\'t even in the dom tree'); 173 | start(); 174 | }); 175 | 176 | setTimeout(function() { start(); }, 1000); 177 | }); 178 | 179 | 180 | asyncTest('Check whether element which is on the top outside of viewport is not firing the event', function() { 181 | expect(0); 182 | 183 | this.element.bind('inview', function(event, isInView) { 184 | ok(false, 'Callback shouldn\'t be fired since the element is outside of viewport'); 185 | start(); 186 | }); 187 | 188 | this.element.css({ 189 | top: '-50px', 190 | left: '50px' 191 | }).appendTo('body'); 192 | 193 | setTimeout(function() { start(); }, 1000); 194 | }); 195 | 196 | 197 | asyncTest('Check whether element which is on the left outside of viewport is not firing the event', function() { 198 | expect(0); 199 | 200 | this.element.bind('inview', function(event, isInView) { 201 | ok(false, 'Callback shouldn\'t be fired since the element is outside of viewport'); 202 | start(); 203 | }); 204 | 205 | this.element.css({ 206 | top: '50px', 207 | left: '-50px' 208 | }).appendTo('body'); 209 | 210 | setTimeout(function() { start(); }, 1000); 211 | }); 212 | 213 | 214 | asyncTest('Check visiblePartX & visiblePartY parameters #1', function() { 215 | expect(2); 216 | 217 | this.element.css({ 218 | top: '-25px', 219 | left: '-25px' 220 | }).appendTo('body'); 221 | 222 | this.element.bind('inview', function(event, isInView, visiblePartX, visiblePartY) { 223 | equal(visiblePartX, 'right', 'visiblePartX has correct value'); 224 | equal(visiblePartY, 'bottom', 'visiblePartY has correct value'); 225 | start(); 226 | }); 227 | }); 228 | 229 | 230 | asyncTest('Check visiblePartX & visiblePartY parameters #2', function() { 231 | expect(2); 232 | 233 | this.element.css({ 234 | top: '0', 235 | left: '-25px' 236 | }).appendTo('body'); 237 | 238 | this.element.bind('inview', function(event, isInView, visiblePartX, visiblePartY) { 239 | equal(visiblePartX, 'right', 'visiblePartX has correct value'); 240 | equal(visiblePartY, 'both', 'visiblePartY has correct value'); 241 | start(); 242 | }); 243 | }); 244 | 245 | 246 | asyncTest('Check visiblePartX & visiblePartY parameters #3', function() { 247 | expect(2); 248 | 249 | this.element.css({ 250 | top: '0', 251 | left: '0' 252 | }).appendTo('body'); 253 | 254 | this.element.bind('inview', function(event, isInView, visiblePartX, visiblePartY) { 255 | equal(visiblePartX, 'both', 'visiblePartX has correct value'); 256 | equal(visiblePartY, 'both', 'visiblePartY has correct value'); 257 | start(); 258 | }); 259 | }); 260 | 261 | 262 | asyncTest('Check "live" events', function() { 263 | expect(3); 264 | 265 | var that = this, 266 | elems = $("body .test-container > div.test-element"); 267 | elems.live("inview", function(event) { 268 | elems.die("inview"); 269 | ok(true, "Live event correctly fired"); 270 | equal(event.currentTarget, that.element[0], "event.currentTarget correctly set"); 271 | equal(this, that.element[0], "Handler bound to target element"); 272 | start(); 273 | }); 274 | 275 | this.element.css({ 276 | top: '0', 277 | left: '0' 278 | }).appendTo(this.container); 279 | }); 280 | 281 | 282 | asyncTest('Check "delegate" events', function() { 283 | expect(3); 284 | 285 | var that = this; 286 | this.container.delegate(".test-element", "inview", function(event) { 287 | ok(true, "Delegated event correctly fired"); 288 | equal(event.currentTarget, that.element[0], "event.currentTarget correctly set"); 289 | equal(this, that.element[0], "Handler bound to target element"); 290 | start(); 291 | }); 292 | 293 | this.element.css({ 294 | top: '0', 295 | left: '0' 296 | }).appendTo(this.container); 297 | }); 298 | 299 | 300 | asyncTest('Check namespaced "delegate" events', function() { 301 | expect(1); 302 | 303 | this.container.delegate(".test-element", "inview.foo", function(event) { 304 | ok(true, "Delegated event correctly fired"); 305 | start(); 306 | }); 307 | 308 | this.element.css({ 309 | top: '0', 310 | left: '0' 311 | }).appendTo(this.container); 312 | }); 313 | 314 | 315 | asyncTest('Check multiple elements', function() { 316 | expect(2); 317 | 318 | var i = 0; 319 | 320 | this.element.add(this.element2).css({ 321 | top: '0', 322 | left: '0' 323 | }).appendTo(this.container); 324 | 325 | $('.test-element').bind('inview', function() { 326 | ok(true); 327 | if (++i == 2) { 328 | start(); 329 | } 330 | }); 331 | }); 332 | 333 | if (!("ontouchstart" in window)) { 334 | asyncTest('Scroll to element via focus()', function() { 335 | // This test will fail on iOS 336 | 337 | expect(1); 338 | 339 | var $input = $("").css({ 340 | position: "absolute", 341 | top: "7000px", 342 | left: "5000px" 343 | }).appendTo(this.container); 344 | 345 | $input.bind('inview', function() { 346 | ok(true); 347 | $input.remove(); 348 | start(); 349 | }); 350 | 351 | setTimeout(function() { 352 | $input.focus(); 353 | }, 1000); 354 | }); 355 | } 356 | }); 357 | -------------------------------------------------------------------------------- /example/live_event.html: -------------------------------------------------------------------------------- 1 | 2 | jquery.inview - live events 3 | 17 | 18 | 19 | 38 |

    Flickr search results for 'lolcat'

    39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | --------------------------------------------------------------------------------