Git Product home page Git Product logo

ngscrollspy's Introduction

#ngScrollSpy No Maintenance Intended

#ATTENTION: This is AbandonWare. The author (me) has stopped using AngularJS in both private life and work life. If you are interested in maintain this and develop it further, contact me and I will link to your repo.

##Former users of this library have moved to and recommended Angular Strap. Hope that will work for you.

###What is it? A continuation of a previous project of mine, ngPagemenu, that adds features such as more defined api to work with the scroll event and an affix directive.

###What functionality does it provide?

  • ScrollSpy: a service that provides an saner api to work with the scroll event.
  • affix: a directive to affix an DOM element to a boundary of the browser window.
  • pagemenu and pageitems: two directives to build a menu from the contents in the page.

###The ScrollSpy service The ScrollSpy service provides an api to work with the scroll event. It builds up the two following objects that represent the event:

####The Scroll Data Object { width, // width of browser window height, // height of browser window maxWidth, // width of document maxHeight, // height of document posX, // x position posY, // y position hasOverscroll, // did we overscroll? overscrollLeft, // did we overscroll to the left? overscrollRight, // did we overscroll to the right? overscrollTop, // did we overscroll to the top? overscrollBottom // did we overscroll to the bottom? }

####The Scroll Delta Object { width, // the difference in width from last scroll event height, // the difference in height from last scroll event maxWidth, // the difference in document width from last scroll event maxHeight // the difference in document height from last scroll event posX, // the difference in x posiiton from last scroll event posY, // the difference in y position from last scroll event velocityX, // the velocity of the change in the x position velocityY // the velocity of the change in the y position } The data is normalized, e.g. any overscroll data is removed and instead flags are added to the data. The velocity is calculated as poistion delta divided by window size, e.g. (curY - prevY) / height.

#####Registering a scroll handler

ScrollSpy.addHandler(cond,handler) { return handler-id }:
cond: function(ScrollData, ScrollDelta) { return true/false }
handler: function(ScrollData, ScrollDelta)

A generic function to add a scroll handler. The cond function return true or false based on the data in the two parameters it receives. If the cond function returns true the handler get's called with the two objects. The addHandler function returns an id to the handler. Use the id to clean up once the handler is no longer needed. In most cases you should not use this hook unless you need very special condition logic.

#####Cleanup on destroy event

ScrollSpy.removeHandler(id):

Remove handler. Use this to clean up once you don't need to receive the event any more.

#####Trigger the scroll event

ScrollSpy.trigger(): 

Use this function to programatically trigger a scroll event. Sets the property isForced to true while the event handlers are executed.

#####Recieve all scroll events

ScrollSpy.onScroll(handler) { return handler-id }:

handler: function(ScrollData, ScrollDelta)

Register a handler that receives all scroll events.

#####Handling scrolling along single axis

ScrollSpy.onYScroll(handler) { return handler-id }:
ScrollSpy.onXScroll(handler) { return handler-id }:

handler: function(pos, delta, ScrollData, ScrollDelta)

Register a handler to receive a scroll event along the Y axis or the X axis.

#####Handling vertical overscroll

ScrollSpy.onOverscrollVert(handler) { return handler-id }:
ScrollSpy.onOverscrollTop(hatndler) { return handler-id }:
ScrollSpy.onOverscrollBottom(handler) { return handler-id }:

handler: function(ScrollData, ScrollDelta)

Recieve overscroll events along the Y axis.

#####Handling horizontal overscroll

ScrollSpy.onOverscrollHorz(handler) { return handler-id }:
ScrollSpy.onOverscrollLeft(handler) { return handler-id }:
ScrollSpy.onOverscrollRight(handler) { return handler-id }:
handler: function(ScrollData, ScrollDelta)

Recieve overscroll events along the X axis.

The affix directive

Add affix to any DOM element as an attribute to affix it to an edge of the browser window.

<div affix>Affixed!</div>

The default edge is top. In the previous example the class affix will be added to the div once it hits the browser top edge.

<div affix="bottom" affix-class="affixed">Affixed to bottom!</div>

The class affixed will be added to the class once it reaches the bottom edge of the browser window.

Possible values for affix are top, bottom, left and right.

More fluent passage by adding a placeholder

In default mode the element which should be affixed is just set to position fixed. As this will pull the element out of its normal flow, the elements below will be moved up with a jolt.

If you add {placeholder: true} to the affix options the original element will be cloned and the clone gets inserted after its origin to serve as a placeholder, so that you won't see any flickering effects.

<div affix affix-options="{placeholder: true}">Affixed!</div>

The default of the option placeholder is false.

The pagemenu and pageitems directives

The module provides two directives, pageitems attribute and tag. The pageitems tag will parse the included HTML and query for items with a certain class. The menu will then be generated in the DOM where you put the tag from that list of items.

The pageitems attribute accepts two parameters, selector and topmargin. The selector specifies the class used to query the DOM for menu items. The topmargin specifies a scrolling offset that is useful if you contain a static header and don't want your items to be under that static header when you click on the menu to scroll to them.

The list is mapped to a tree using the following heuristic. A type is generated for the item based on the tag name and classes. The type is compared to the previous item's type. If they are equal this new item is a sibling of the previous item. Otherwise we traverse a stack of parents. If a matching type is found the stack is popped to that level and the new item becomes a sibling at that level. If no parent is found the stack is pushed and the new item becomes a child of the last item.

For a more visual demonstration, consider the following list of items:

<h2 id="1" class="item">Item 1</h2>
<h2 id="2" class="item">Item 2</h2>
<h3 id="3" class="item">Item 3</h3>
<h4 id="4" class="item">Item 4</h4>
<h4 id="5" class="item">Item 5</h4>
<h2 id="6" class="item">Item 6</h2>
<h2 id="7" class="item subitem">Item 7</h2>

This will be mapped to the following tree:

Item 1
Item 2
    Item 3
        Item 4
        Item 5
Item 6
    Item 7

###How do I use it? Install with bower:

bower install ngScrollSpy --save

Add a <script> to your index.html:

<script src="/bower_components/ngScrollSpy/dist/ngScrollSpy.min.js"></script>

And add ngScrollSpy as a dependency for your app:

angular.module('myApp', ['ngScrollSpy']);

###Dependencies? Only AngularJS.

###Example? The demo directory contains three demo files:

  • horz.html: A demonstration of affixing a DOM element to either the left or the right edge of the window.
  • vert.html: A demonstration of affixing a DOM element to either the top or the bottom edge of the window.
  • pagemenu.html: A demonstration of a page menu.

###Credits? Aside for the Bootstrap people for the obvious inspiration, the pagemenu code was inspired by Evil Closet Monkey's answer to a question on StackExchange.

###And you are? Magnús Örn Gylfason, a web programmer working in the banking industry in Iceland. You can contact me at

###Licence The MIT License (MIT)

Copyright (c) 2014 Magnús Örn Gylfason

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

ngscrollspy's People

Contributors

edim24 avatar k88hudson avatar leonex-cs1 avatar lookfirst avatar mchapman avatar mg avatar puttyman avatar pzurowski avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ngscrollspy's Issues

Provide a way to offset from edge of screen

I want to be able to account for the fixed header I already have, so I want my div to stop when it is offset from the top. I currently have it 'bounce back' when the div hits the top via a position tag, but that causes a couple of strange behaviors.

Error in IE9

I'm getting this little annoying error in IE9.

TypeError: Unable to get value of the property 'length': object is null or undefined<menu class="nav pagemenu"> 

It works as it should in all other browsers. The page items from the content (h2's) isn't printed i into the pagemenu list.

What to to do?

Tag 1.0.2

Would you mind tagging a new release so I can pull in the latest commit? Thanks!

Bower out of Sync

Downloading on http://mg.github.io/ngScrollSpy/ the version works perfectly fine. Doing a Bower save downloading v1.0.6 has a problem on line #219 in the ngScrollSpy.js which is missing affixOptions = Saw the issue has been updated 14 days ago but what is getting downloaded using Bower is out of sync.

ngScrollSpy with ng-route

Hi, I am using angular-route together with ngScrollSpy, but find that the hash link won't work with angular-route, I try to use this link to solve the problem, and It seems work too, but want to see if there is another better method.
Here is what I added in ngScrollSpy.js

// ln: 497
// markup += '<a href="#' + $location.path() +'/#'+ item.link + '">';
      markup += '<a href="" ng-click="scrolltoHref(' + "'" +item.link + "'" +')">';

and add a controller to the directive

    controller: function ($scope) {
      $scope.scrolltoHref = function(id){
        $location.hash(id);
        $anchorScroll();
      };
    },

Affix directive does not work for element scroll

It seems like the affix directive only works for the window scroll, not for any element.

A common scenario is to have a sidebar with its own scrollbar. It would be nice to be able to fix the position of elements relative to that elements scroll position rather than the window's scroll position.

Request: Please package for npm

Like so many developers out there, I fall into the CommonJS camp, using Browserify to bundle my js/coffee files into a single js file. Currently I use Napa to wrap non-npm'd projects for use however it would much easier to maintain if there was an npm package for this library. Thanks.

Suggestion: link to mgcrea's Angular Strap library

Hello,

I briefly used your library to perform affix type actions in my project, before I discovered some bugs and then you announced this project was abandoned (bummer!).

However, luckily I discovered that mgcrea's Angular Strap project - which is intended to be an Angular friendly drop-in replacement for the Bootstrap Javascript functions - has both a scroll spy and an affix component contained in it.

Better yet, the developer has been careful to make everything highly modularized. On the doc page, it will point to the dependencies each separate module has, so you can pick and choose the modules you need.

I for instance was able to replace this library with Angular Strap's affix functionality. Pretty lightweight, and effective.

Perhaps you can provide a link to mgcrea's library ( http://mgcrea.github.io/angular-strap/ ) on the Readme?

Thanks for your great library, and apologies that you had to abandon it.

affix not working without offset in affix-options

affix in demo's not working.

Seems that just having affix attrib without a affix-options containing an offset value doesn't set the default offset of 0.

SHA: e9aed4d

Fix that worked for me.

Line #20 of affix.js:

affixOptions = angular.extend({offset: 0}, affixOptions);

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.