-
Notifications
You must be signed in to change notification settings - Fork 27.4k
ANCHOR SCROLL: WIP - feat($anchorScroll): add support for configurable scroll offset #9371
Conversation
|
||
var style = window.getComputedStyle(header); | ||
return (style.position === 'fixed') ? header.offsetHeight : 0; | ||
}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please, don't scream about this. I know :)
(It's ugly, it's not-Angular, it's hacky, it's hurting your eyes and I will remove it asap - just wanted to get some feedback on the offset approach.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or for POC you could have just done:
.config(['$anchorScrollProvider', function($anchorScrollProvider) {
$anchorScrollProvider.setScrollOffset(function () { return 100; });
});
:-)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But I guess that you wanted to see it change as the header changed size...
if (offset) { | ||
$window.scrollBy(0, -1 * offset); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be:
function scrollTo(elem) {
if (elem) {
elem.scrollIntoView();
var offset = scrollOffsetGetter();
if (offset) {
$window.scrollBy(0, -1 * offset);
}
} else {
$window.scrollTo(0, 0);
}
}
Otherwise scrolling to the top never gets to 0, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. I forgot about the .main-body-grid { margin-top: 120px;
CSS style.
I kind of like this... |
Actually the more I think about this, a finessed version of this seems like the right way to go |
I updated the Unfortunately, there seems to be an issue (for a demo see the example I added in the $anchorScroll docs). In a nutshell, when the scrolled element is not the body, then Possible solutions:
@petebacondarwin any thoughts |
I added some code to prevent elements near the bottom of the scrolled element to be scrolled further down than required. |
I made some changes here: gkalpak#1 |
@petebacondarwin , a little update: fb71268 All the functionality should be in place (still missing updated docs and tests). I tried to do a little research and I came to the conclusion that the most consistent and accurate (at least enough for our purpose) way of aquiring the element's height is using its I also added a helper to calculate the accumulated I put back the fix to avoid scrolling more than it is necessary for elements near the end of the page. I added a helper function to get an element's [computed]Style, with fallbacks for when Finally, I removed two redundant calls to I have put a couple of large inline comments , which I am not a big fan of. If you have any idea how to make them more elegant or concise... I will finish up with the docs tonight and write some tests tomorrow. In the meantime, please feel free to tell me wdyt :) |
* - **number**: A fixed number of pixels to be used as offset.<br /><br /> | ||
* - **function**: A getter function called everytime `$anchorScroll()` is executed. Must return | ||
* a number representing the offset (in pixels).<br /><br /> | ||
* - **jqLite**: A jqLite/jQuery element to be used for specifying the offset. The sum of the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@petebacondarwin
Right now we only need the "raw" DOM element (not the jqLite element), but still expect a jqLite element.
Should we modify the implementation so both raw and jqLite work (or do you think it complicates the "contract" for no real benefit) ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's leave it as a wrapped element for now, it is easier to add public API that remove it.
I'll take a look tomorrow. Thanks |
return $window.getComputedStyle ? | ||
$window.getComputedStyle(elem) : | ||
elem.currentStyle || elem.style || {}; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We are not supporting IE8 in 1.3.x so this can go away. Since this is a new feature it won't be backported to 1.2.x
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It never occurred me that 1.2.x only receives fixes (no new features). It makes sense.
No worries for IE8 then (yay) ! I'll remove the unnecessary code.
@caitp : Aha! @petebacondarwin : It probably has something to do with Firefox (and IE) doing their native scrolling after something has happened (but I haven't found out what that The only workaround I have found thus far is changing the
Ideas anyone ? |
I believe Igor has a fix for this. ..
|
Little update on the Firefox/IE issue |
Does Igor have a drawer with fixes for all sorts of stuff or something :P |
@petebacondarwin : Delaying scrolling until |
The fix I was thinking of was #9393 but it is probably not relevant to this problem. I will take a look this morning. |
00dbb36
to
8967fd7
Compare
@petebacondarwin : I pushed gkalpak@8967fd7 that fixes the issue in Firefox. (As mentioned earlier, applying a sufficient timeout works around the issue, but...) |
@petebacondarwin : Yay, tests pass !
|
cd docs
gulp build-app If you made changes to templates and need to rebuild docs you can do grunt docs Or cd docs
gulp doc-gen or to rebuld docs and generate the app cd docs
gulp You get the idea. It is good to run |
BTW, I pushed a commit with some tests regarding (Thx, @petebacondarwin , for the docs-app-building info !) |
} | ||
}); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So this function is called from within a $watch handler so it is already in a digest phase, but the readystatechange handler is not inside a $digest. So I think this should look like:
function scrollWhenReady() {
if (document.readyState === 'complete') {
$rootScope.$evalAsync(scroll);
} else if (!scrollScheduled) {
scrollScheduled = true;
document.addEventListener('readystatechange', function unbindAndScroll() {
$rootScope.$apply(function() {
if (document.readyState === 'complete') {
document.removeEventListener('readystatechange', unbindAndScroll);
scroll();
}
});
});
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For good measure it might be best to set scrollScheduled
back to false in the handler just in case in the future we want to call it again.
WARNING: Although the tests passed, when I run them locally, I come across some inconsistent behaviour with Firefox: |
I'll take a look tonight
|
abdaab7
to
30996f8
Compare
You are right :( |
50a9ab6
to
b32a767
Compare
Add support for a configurable scroll offset to $anchorScrollProvider. The offset is expressed in pixels and can be specified either as a fixed value or as a function that return the offset it pixels dynamically. (This is a POC and a WIP: no docs, no tests) Related to angular#9368 Closes angular#2070, angular#9360
…ents Finalize the implementation, fix scrolling for elements near the end of the page, make sure the values calculated for top-offset and height are accurate (and unaffected by box-sizing or offset-parents). Separately document $anchorScrollProvider, document the newly added `yOffset` property of $anchorScroll, fix minor issues in the examples and overall improve the docs. Add tests for `$anchorScroll.yOffset` and make some necessary modifications to the existing test helper functions.
d66450e
to
92e5a05
Compare
Closing this in favor of #9517. |
Add support for a configurable scroll offset to $anchorScrollProvider.
The offset is expressed in pixels and can be specified either as a fixed value or as a function that returns the offset it pixels dynamically.
(This is a POC and a WIP: no docs, no tests)
Related to #9368
Closes #2070, #9360