diff --git a/angular-inview.js b/angular-inview.js index f890f06..c911f11 100644 --- a/angular-inview.js +++ b/angular-inview.js @@ -73,6 +73,13 @@ function inViewDirective ($parse) { if (options.throttle) { viewportEventSignal = viewportEventSignal.throttle(options.throttle); } + // Apply a default short throttle when requiring an offset parent. + // This should allow time for a digest cycle to take place which may + // be significant if the event triggered changed the visiblity of the + // offset parent + else if (options.requireOffsetParent) { + viewportEventSignal = viewportEventSignal.throttle(100); + } // Map to viewport intersection and in-view informations var inviewInfoSignal = viewportEventSignal @@ -93,8 +100,13 @@ function inViewDirective ($parse) { } viewportRect = offsetRect(viewportRect, options.viewportOffset); var elementRect = offsetRect(element[0].getBoundingClientRect(), options.offset); + var inView = intersectRect(elementRect, viewportRect); + + if (inView && options.requireOffsetParent) { + inView = element[0].offsetParent !== null; + } var info = { - inView: intersectRect(elementRect, viewportRect), + inView: inView, event: event, element: element, elementRect: elementRect, @@ -378,4 +390,4 @@ if (typeof define === 'function' && define.amd) { module.exports = angularInviewModule; } -})(); \ No newline at end of file +})(); diff --git a/angular-inview.spec.js b/angular-inview.spec.js index 071f6d0..ef8a4cc 100644 --- a/angular-inview.spec.js +++ b/angular-inview.spec.js @@ -302,6 +302,79 @@ describe("angular-inview", function() { }); + describe("requiring an offsetParent", function() { + it("should trigger for visible elements as normal", function(done) { + makeTestForHtml( + '
' + + '
' + ) + .then(function (test) { + expect(test.spy.calls.count()).toBe(1); + expect(test.spy).toHaveBeenCalledWith(true); + }) + .then(done); + }); + + it("should not trigger for elements with hidden parents", function(done) { + makeTestForHtml( + '
' + + '
' + + '
' + + '
' + ) + .then(function (test) { + expect(test.spy).not.toHaveBeenCalled(); + }) + .then(done); + }); + + it("should report positive when the parent becomes visible", function(done) { + makeTestForHtml( + '
' + + '
' + + '
' + + '
' + ) + .then(function (test) { + expect(test.spy).not.toHaveBeenCalled(); + test.element.removeAttr('style'); + angular.element(window).triggerHandler('click'); + return test; + }) + .then(lazyWait(150)) + .then(function (test) { + expect(test.spy.calls.count()).toEqual(1); + expect(test.spy).toHaveBeenCalledWith(true); + }) + .then(done); + }); + + it("should report negative when the parent becomes hidden", function(done) { + makeTestForHtml( + '
' + + '
' + + '
' + + '
' + ) + .then(function (test) { + test.spy.calls.reset(); + test.element.attr('style', 'display: none;'); + angular.element(window).triggerHandler('click'); + return test; + }) + .then(lazyWait(150)) + .then(function (test) { + expect(test.spy.calls.count()).toEqual(1); + expect(test.spy).toHaveBeenCalledWith(false); + }) + .then(done); + }); + }) + // A test object has the properties: // // - `element`: An angular element inserted in the test page @@ -405,5 +478,4 @@ describe("angular-inview", function() { }); } } - }); diff --git a/package.json b/package.json index 0a313c5..94c6906 100644 --- a/package.json +++ b/package.json @@ -22,14 +22,15 @@ }, "homepage": "https://github.com/thenikso/angular-inview#readme", "peerDependencies": { - "angular": "^1.5.8" + "angular": "^1.5.8", + "jasmine-core": "^2.5.2" }, "devDependencies": { "docco": "^0.7.0", "gh-pages": "^0.11.0", - "karma": "^0.12.24", - "karma-chrome-launcher": "^0.1.5", - "karma-jasmine": "~0.2", + "karma": "^1.3.0", + "karma-chrome-launcher": "^2.0.0", + "karma-jasmine": "^1.0.2", "angular-mocks": "^1.5.8" } }