From 5994d08556fdfcbaca27b235b86bfc715b679f85 Mon Sep 17 00:00:00 2001 From: Ian Clark Date: Fri, 11 Nov 2016 17:15:07 +0000 Subject: [PATCH 1/2] Add `requireOffsetParent` option --- angular-inview.js | 9 +++-- angular-inview.spec.js | 74 +++++++++++++++++++++++++++++++++++++++++- package.json | 9 ++--- 3 files changed, 85 insertions(+), 7 deletions(-) diff --git a/angular-inview.js b/angular-inview.js index f890f06..a8a1246 100644 --- a/angular-inview.js +++ b/angular-inview.js @@ -93,8 +93,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 +383,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..76d846c 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(100)) + .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(100)) + .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" } } From e6ac8bb4ab576809ef957c1dc8bccc962991c946 Mon Sep 17 00:00:00 2001 From: Ian Clark Date: Fri, 11 Nov 2016 18:11:35 +0000 Subject: [PATCH 2/2] Apply a default throttle to allow for a digest cycle to take place --- angular-inview.js | 7 +++++++ angular-inview.spec.js | 4 ++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/angular-inview.js b/angular-inview.js index a8a1246..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 diff --git a/angular-inview.spec.js b/angular-inview.spec.js index 76d846c..ef8a4cc 100644 --- a/angular-inview.spec.js +++ b/angular-inview.spec.js @@ -344,7 +344,7 @@ describe("angular-inview", function() { angular.element(window).triggerHandler('click'); return test; }) - .then(lazyWait(100)) + .then(lazyWait(150)) .then(function (test) { expect(test.spy.calls.count()).toEqual(1); expect(test.spy).toHaveBeenCalledWith(true); @@ -366,7 +366,7 @@ describe("angular-inview", function() { angular.element(window).triggerHandler('click'); return test; }) - .then(lazyWait(100)) + .then(lazyWait(150)) .then(function (test) { expect(test.spy.calls.count()).toEqual(1); expect(test.spy).toHaveBeenCalledWith(false);