diff --git a/demo/index.html b/demo/index.html index 32e3347..6a55d5e 100644 --- a/demo/index.html +++ b/demo/index.html @@ -61,6 +61,11 @@

Why?

+

How?

+
<p ui-scrollpoint>They see me scrollin...</p>
+

You can optionally pass a number to + ui-scrollpoint which would override the detected y-offset of the element. Values can be either absolute + 600 or offset from the calculated value -50 or +100.

A scrollpoint with a target set on a parent scrollable div

@@ -105,12 +110,37 @@

Resetting

+
+
+

Using a variable

+
+
+

They see me scrollin...

+

They see me scrollin...

+

They see me scrollin...

+

They see me scrollin...

+

They see me scrollin...

+

Scrollpoint * 2

+

Scrollpoint + 50

+

Scrollpoint * -1

+
+
-

How?

-
<p ui-scrollpoint>They see me scrollin...</p>
-

You can optionally pass a number to - ui-scrollpoint which would override the detected y-offset of the element. Values can be either absolute - 600 or offset from the calculated value -50 or +100.

+
+
+
+
+

+ You can pass a variable to change de detected y-offset of the element.
+ The element will be updated accordingly if the value is valid.
+ Example: <div ui-scrollpoint={{ scrollpoint }}"></div> +

+

+ + +

+
+
diff --git a/dist/scrollpoint.js b/dist/scrollpoint.js index 18ae818..101aa45 100644 --- a/dist/scrollpoint.js +++ b/dist/scrollpoint.js @@ -1,7 +1,7 @@ /*! * angular-ui-scrollpoint * https://github.com/angular-ui/ui-scrollpoint - * Version: 1.1.0 - 2015-10-27T02:32:30.503Z + * Version: 1.1.0 - 2015-11-10T10:12:58.696Z * License: MIT */ @@ -13,7 +13,7 @@ * @param [offset] {int} optional Y-offset to override the detected offset. * Takes 300 (absolute) or -300 or +300 (relative to detected) */ -angular.module('ui.scrollpoint', []).directive('uiScrollpoint', ['$window', function($window) { +angular.module('ui.scrollpoint', []).directive('uiScrollpoint', ['$window', function ($window) { function getWindowScrollTop() { if (angular.isDefined($window.pageYOffset)) { @@ -25,31 +25,45 @@ angular.module('ui.scrollpoint', []).directive('uiScrollpoint', ['$window', func } return { require: '^?uiScrollpointTarget', - link: function(scope, elm, attrs, uiScrollpointTarget) { + scope: { + uiScrollpoint: '@' + }, + link: function (scope, elm, attrs, uiScrollpointTarget) { var absolute = true, - shift = 0, - fixLimit, - $target = uiScrollpointTarget && uiScrollpointTarget.$element || angular.element($window); - - if (!attrs.uiScrollpoint) { - absolute = false; - } else if (typeof (attrs.uiScrollpoint) === 'string') { - // charAt is generally faster than indexOf: http://jsperf.com/indexof-vs-charat - if (attrs.uiScrollpoint.charAt(0) === '-') { - absolute = false; - shift = -parseFloat(attrs.uiScrollpoint.substr(1)); - } else if (attrs.uiScrollpoint.charAt(0) === '+') { + shift = 0, + fixLimit, + $target = uiScrollpointTarget && uiScrollpointTarget.$element || angular.element($window); + + function setup(scrollpoint) { + if (!scrollpoint) { absolute = false; - shift = parseFloat(attrs.uiScrollpoint.substr(1)); + } else if (typeof (scrollpoint) === 'string') { + // charAt is generally faster than indexOf: http://jsperf.com/indexof-vs-charat + if (scrollpoint.charAt(0) === '-') { + absolute = false; + shift = -parseFloat(scrollpoint.substr(1)); + } else if (scrollpoint.charAt(0) === '+') { + absolute = false; + shift = parseFloat(scrollpoint.substr(1)); + } else { + var parsed = parseFloat(scrollpoint); + if (!isNaN(parsed) && isFinite(parsed)) { + absolute = true; + shift = parsed; + } + } + } else if (typeof (scrollpoint) === 'number') { + setup(scrollpoint.toString()); + return; } + fixLimit = absolute ? scope.uiScrollpoint : elm[0].offsetTop + shift; } - - fixLimit = absolute ? attrs.uiScrollpoint : elm[0].offsetTop + shift; - + setup(scope.uiScrollpoint); + function onScroll() { - - var limit = absolute ? attrs.uiScrollpoint : elm[0].offsetTop + shift; - + + var limit = absolute ? scope.uiScrollpoint : elm[0].offsetTop + shift; + // if pageYOffset is defined use it, otherwise use other crap for IE var offset = uiScrollpointTarget ? $target[0].scrollTop : getWindowScrollTop(); if (!elm.hasClass('ui-scrollpoint') && offset > limit) { @@ -59,29 +73,34 @@ angular.module('ui.scrollpoint', []).directive('uiScrollpoint', ['$window', func elm.removeClass('ui-scrollpoint'); } } - + function reset() { elm.removeClass('ui-scrollpoint'); - fixLimit = absolute ? attrs.uiScrollpoint : elm[0].offsetTop + shift; + fixLimit = absolute ? scope.uiScrollpoint : elm[0].offsetTop + shift; onScroll(); } - + scope.$on('scrollpointShouldReset', reset); - + $target.on('scroll', onScroll); onScroll(); // sets the initial state - + // Unbind scroll event handler when directive is removed - scope.$on('$destroy', function() { + scope.$on('$destroy', function () { $target.off('scroll', onScroll); }); + + scope.$watch('uiScrollpoint', function (newScrollpoint) { + setup(newScrollpoint); + onScroll(); + }); } }; - }]).directive('uiScrollpointTarget', [function() { + }]).directive('uiScrollpointTarget', [function () { return { - controller: ['$element', function($element) { - this.$element = $element; - }] + controller: ['$element', function ($element) { + this.$element = $element; + }] }; }]); diff --git a/dist/scrollpoint.min.js b/dist/scrollpoint.min.js index 9653df6..65e0dad 100644 --- a/dist/scrollpoint.min.js +++ b/dist/scrollpoint.min.js @@ -1,7 +1,7 @@ /*! * angular-ui-scrollpoint * https://github.com/angular-ui/ui-scrollpoint - * Version: 1.1.0 - 2015-10-27T02:32:30.503Z + * Version: 1.1.0 - 2015-11-10T10:12:58.696Z * License: MIT */ -!function(){"use strict";angular.module("ui.scrollpoint",[]).directive("uiScrollpoint",["$window",function(o){function t(){if(angular.isDefined(o.pageYOffset))return o.pageYOffset;var t=document.compatMode&&"BackCompat"!==document.compatMode?document.documentElement:document.body;return t.scrollTop}return{require:"^?uiScrollpointTarget",link:function(l,n,i,r){function e(){var o=s?i.uiScrollpoint:n[0].offsetTop+p,l=r?a[0].scrollTop:t();!n.hasClass("ui-scrollpoint")&&l>o?(n.addClass("ui-scrollpoint"),u=o):n.hasClass("ui-scrollpoint")&&u>l&&n.removeClass("ui-scrollpoint")}function c(){n.removeClass("ui-scrollpoint"),u=s?i.uiScrollpoint:n[0].offsetTop+p,e()}var u,s=!0,p=0,a=r&&r.$element||angular.element(o);i.uiScrollpoint?"string"==typeof i.uiScrollpoint&&("-"===i.uiScrollpoint.charAt(0)?(s=!1,p=-parseFloat(i.uiScrollpoint.substr(1))):"+"===i.uiScrollpoint.charAt(0)&&(s=!1,p=parseFloat(i.uiScrollpoint.substr(1)))):s=!1,u=s?i.uiScrollpoint:n[0].offsetTop+p,l.$on("scrollpointShouldReset",c),a.on("scroll",e),e(),l.$on("$destroy",function(){a.off("scroll",e)})}}}]).directive("uiScrollpointTarget",[function(){return{controller:["$element",function(o){this.$element=o}]}}])}(); \ No newline at end of file +!function(){"use strict";angular.module("ui.scrollpoint",[]).directive("uiScrollpoint",["$window",function(o){function t(){if(angular.isDefined(o.pageYOffset))return o.pageYOffset;var t=document.compatMode&&"BackCompat"!==document.compatMode?document.documentElement:document.body;return t.scrollTop}return{require:"^?uiScrollpointTarget",scope:{uiScrollpoint:"@"},link:function(e,n,i,l){function r(o){if(o){if("string"==typeof o)if("-"===o.charAt(0))a=!1,f=-parseFloat(o.substr(1));else if("+"===o.charAt(0))a=!1,f=parseFloat(o.substr(1));else{var t=parseFloat(o);!isNaN(t)&&isFinite(t)&&(a=!0,f=t)}else if("number"==typeof o)return void r(o.toString())}else a=!1;u=a?e.uiScrollpoint:n[0].offsetTop+f}function s(){var o=a?e.uiScrollpoint:n[0].offsetTop+f,i=l?p[0].scrollTop:t();!n.hasClass("ui-scrollpoint")&&i>o?(n.addClass("ui-scrollpoint"),u=o):n.hasClass("ui-scrollpoint")&&u>i&&n.removeClass("ui-scrollpoint")}function c(){n.removeClass("ui-scrollpoint"),u=a?e.uiScrollpoint:n[0].offsetTop+f,s()}var u,a=!0,f=0,p=l&&l.$element||angular.element(o);r(e.uiScrollpoint),e.$on("scrollpointShouldReset",c),p.on("scroll",s),s(),e.$on("$destroy",function(){p.off("scroll",s)}),e.$watch("uiScrollpoint",function(o){r(o),s()})}}}]).directive("uiScrollpointTarget",[function(){return{controller:["$element",function(o){this.$element=o}]}}])}(); \ No newline at end of file diff --git a/src/scrollpoint.js b/src/scrollpoint.js index 0989159..34365fd 100644 --- a/src/scrollpoint.js +++ b/src/scrollpoint.js @@ -3,7 +3,7 @@ * @param [offset] {int} optional Y-offset to override the detected offset. * Takes 300 (absolute) or -300 or +300 (relative to detected) */ -angular.module('ui.scrollpoint', []).directive('uiScrollpoint', ['$window', function($window) { +angular.module('ui.scrollpoint', []).directive('uiScrollpoint', ['$window', function ($window) { function getWindowScrollTop() { if (angular.isDefined($window.pageYOffset)) { @@ -15,31 +15,45 @@ angular.module('ui.scrollpoint', []).directive('uiScrollpoint', ['$window', func } return { require: '^?uiScrollpointTarget', - link: function(scope, elm, attrs, uiScrollpointTarget) { + scope: { + uiScrollpoint: '@' + }, + link: function (scope, elm, attrs, uiScrollpointTarget) { var absolute = true, - shift = 0, - fixLimit, - $target = uiScrollpointTarget && uiScrollpointTarget.$element || angular.element($window); - - if (!attrs.uiScrollpoint) { - absolute = false; - } else if (typeof (attrs.uiScrollpoint) === 'string') { - // charAt is generally faster than indexOf: http://jsperf.com/indexof-vs-charat - if (attrs.uiScrollpoint.charAt(0) === '-') { - absolute = false; - shift = -parseFloat(attrs.uiScrollpoint.substr(1)); - } else if (attrs.uiScrollpoint.charAt(0) === '+') { + shift = 0, + fixLimit, + $target = uiScrollpointTarget && uiScrollpointTarget.$element || angular.element($window); + + function setup(scrollpoint) { + if (!scrollpoint) { absolute = false; - shift = parseFloat(attrs.uiScrollpoint.substr(1)); + } else if (typeof (scrollpoint) === 'string') { + // charAt is generally faster than indexOf: http://jsperf.com/indexof-vs-charat + if (scrollpoint.charAt(0) === '-') { + absolute = false; + shift = -parseFloat(scrollpoint.substr(1)); + } else if (scrollpoint.charAt(0) === '+') { + absolute = false; + shift = parseFloat(scrollpoint.substr(1)); + } else { + var parsed = parseFloat(scrollpoint); + if (!isNaN(parsed) && isFinite(parsed)) { + absolute = true; + shift = parsed; + } + } + } else if (typeof (scrollpoint) === 'number') { + setup(scrollpoint.toString()); + return; } + fixLimit = absolute ? scope.uiScrollpoint : elm[0].offsetTop + shift; } - - fixLimit = absolute ? attrs.uiScrollpoint : elm[0].offsetTop + shift; - + setup(scope.uiScrollpoint); + function onScroll() { - - var limit = absolute ? attrs.uiScrollpoint : elm[0].offsetTop + shift; - + + var limit = absolute ? scope.uiScrollpoint : elm[0].offsetTop + shift; + // if pageYOffset is defined use it, otherwise use other crap for IE var offset = uiScrollpointTarget ? $target[0].scrollTop : getWindowScrollTop(); if (!elm.hasClass('ui-scrollpoint') && offset > limit) { @@ -49,28 +63,33 @@ angular.module('ui.scrollpoint', []).directive('uiScrollpoint', ['$window', func elm.removeClass('ui-scrollpoint'); } } - + function reset() { elm.removeClass('ui-scrollpoint'); - fixLimit = absolute ? attrs.uiScrollpoint : elm[0].offsetTop + shift; + fixLimit = absolute ? scope.uiScrollpoint : elm[0].offsetTop + shift; onScroll(); } - + scope.$on('scrollpointShouldReset', reset); - + $target.on('scroll', onScroll); onScroll(); // sets the initial state - + // Unbind scroll event handler when directive is removed - scope.$on('$destroy', function() { + scope.$on('$destroy', function () { $target.off('scroll', onScroll); }); + + scope.$watch('uiScrollpoint', function (newScrollpoint) { + setup(newScrollpoint); + onScroll(); + }); } }; - }]).directive('uiScrollpointTarget', [function() { + }]).directive('uiScrollpointTarget', [function () { return { - controller: ['$element', function($element) { - this.$element = $element; - }] + controller: ['$element', function ($element) { + this.$element = $element; + }] }; }]); diff --git a/test/scrollpointSpec.js b/test/scrollpointSpec.js index 48e205e..5f461ed 100644 --- a/test/scrollpointSpec.js +++ b/test/scrollpointSpec.js @@ -1,4 +1,4 @@ -/*global describe, beforeEach, module, inject, it, spyOn, expect, $ */ +/*global describe, beforeEach, afterAll, module, inject, it, spyOn, expect, $, angular */ describe('uiScrollpoint', function () { 'use strict'; @@ -70,4 +70,44 @@ describe('uiScrollpoint', function () { expect(element.hasClass('ui-scrollpoint')).toBe(true); }); }); + describe('using a scope variable', function() { + var element; + beforeEach(function() { + element = $compile('
')(scope); + }); + afterAll(function() { + scope.scrollpoint = undefined; + }); + it('should add/remove the ui-scrollpoint class depending on the value of the scrollpoint variable', function () { + // number (absolute) + scope.scrollpoint = 100; + scope.$digest(); + expect(element.hasClass('ui-scrollpoint')).toBe(false); + expect(element.attr('ui-scrollpoint')).toBe('100'); + + // string (absolute) + scope.scrollpoint = "100"; + scope.$digest(); + expect(element.hasClass('ui-scrollpoint')).toBe(false); + expect(element.attr('ui-scrollpoint')).toBe('100'); + + // string (plus relative) + scope.scrollpoint = "+100"; + scope.$digest(); + expect(element.hasClass('ui-scrollpoint')).toBe(false); + expect(element.attr('ui-scrollpoint')).toBe('+100'); + + // number (minus relative) + scope.scrollpoint = -100; + scope.$digest(); + expect(element.hasClass('ui-scrollpoint')).toBe(true); + expect(element.attr('ui-scrollpoint')).toBe('-100'); + + // string (minus relative) + scope.scrollpoint = "-100"; + scope.$digest(); + expect(element.hasClass('ui-scrollpoint')).toBe(true); + expect(element.attr('ui-scrollpoint')).toBe('-100'); + }); + }); });