Why would $anchorScroll do nothing?

4,362 views
Skip to first unread message

David Karr

unread,
Feb 26, 2014, 7:17:20 PM2/26/14
to ang...@googlegroups.com
I have a SPA using angular ui-bootstrap for the tabs component.  In the body of each tab I have several nested accordions, and ngTables at the "leaf" nodes.  In a few places I have code that attempts to activate a particular tab, and open up the accordion tree until a particular table is open, and then scroll to a row in the table.

All of the code that activates the tab and opens accordions works fine.  What is not working is the final call to "$anchorScroll".  For some reason this is doing nothing.

I'm using the following function:

        scrollTo:    function (elementId) {
            $location.hash("#" + elementId);
            $timeout(function() {
                $anchorScroll();
            });
        },


I tried setting a breakpoint in this function and executing the following in the Firebug console:

angular.element("#" + elementId)

This prints out something like this (I'm eliding some of the value):

The fact that it prints this out instead of "jQuery( )" means that this is a valid and existing element.

Almost every single time I've tested this, nothing happens on the call to "$anchorScroll".  Strangely enough, just a couple minutes ago, when I was stepping through this code, I saw it correctly scroll to the row in the table.  I then tested it again and got the same do-nothing behavior.  That was the only time I've ever seen this work.

The last thing I just tried a moment ago was adding a timeout value to the $timeout call, starting with "1000".  The first time I reloaded the page with this, I saw even stranger behavior.  I saw the page scroll to the correct table row, but it only stayed there for a fraction of a second, and then jumped back to the top of the page.

I'm doing most of my testing in Firefox, but it demonstrates the same behavior in Chrome.

Note that the element I'm trying to scroll to is a "td" element, not a "a" element.  I couldn't find a clear statement about whether this should work, but I found the following plunkr: http://plnkr.co/edit/NvAdFWay46A9naw7zG3X?p=preview , which shows that the scrolled-to element does not have to be a "a" element.

David Karr

unread,
Feb 26, 2014, 7:34:11 PM2/26/14
to ang...@googlegroups.com

One thing that I neglected to mention is that just before this scrolling functionality is executed, there is a ui-bootstrap modal displayed on the screen containing a table of links.  When the user clicks on a link, it dismisses the dialog and then does the "scrollTo".

Lauri Elias

unread,
Feb 27, 2014, 11:23:02 AM2/27/14
to ang...@googlegroups.com
Also having problems. Every option (3 different raw JS implementations, a directive, $anchorScroll) just take me to the top of the page on Chrome 33. 
HTML: 
<a id="{{hotel.code}}"></a>

JS:
$location.hash("#" + hotel.code);
$anchorScroll();

David Karr

unread,
Feb 27, 2014, 4:50:43 PM2/27/14
to ang...@googlegroups.com

I've managed to fix my particular problem, and I can see one obvious problem with what you're doing.

First of all, I determined that the parameter to $location.hash() is NOT a CSS selector, it's just an element id, so you should remove the "#" prefix.

For my problem, I discovered that putting $anchorScroll in the $timeout block is required, but not sufficient. When I moved the $location.hash() call into the $timeout block also, it then started working consistently.

Current and working version of my "scrollTo" function is now this:
        scrollTo:    function (elementId) {
            $timeout(function() {
                $location.hash(elementId);
                $anchorScroll();
            });
        },
 
Reply all
Reply to author
Forward
0 new messages