InfiniteScroll.js 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. /*
  2. * Copyright (C) 2014 - present Instructure, Inc.
  3. *
  4. * This file is part of Canvas.
  5. *
  6. * Canvas is free software: you can redistribute it and/or modify it under
  7. * the terms of the GNU Affero General Public License as published by the Free
  8. * Software Foundation, version 3 of the License.
  9. *
  10. * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY
  11. * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
  13. * details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License along
  16. * with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. import _ from 'underscore'
  19. import ReactDOM from 'react-dom'
  20. var InfiniteScroll = {
  21. topPosition(el) {
  22. if (!el) {
  23. return 0;
  24. }
  25. return el.offsetTop + this.topPosition(el.offsetParent);
  26. },
  27. loadMoreIfNeeded: _.throttle(function() {
  28. var atBottom = false;
  29. if (this.scrollElement) {
  30. atBottom = this.scrollElement.scrollTop + this.scrollElement.clientHeight + 100 >= this.scrollElement.scrollHeight;
  31. } else {
  32. var el = ReactDOM.findDOMNode(this)
  33. var scrollTop = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
  34. atBottom = this.topPosition(el) + el.offsetHeight - scrollTop - window.innerHeight < 100;
  35. }
  36. if (atBottom) {
  37. this.loadMore();
  38. }
  39. }, 100),
  40. attachScroll() {
  41. if (this.refs.scrollElement) {
  42. this.scrollElement = this.refs.scrollElement
  43. }
  44. (this.scrollElement || window).addEventListener('scroll', this.loadMoreIfNeeded);
  45. (this.scrollElement || window).addEventListener('resize', this.loadMoreIfNeeded);
  46. this.loadMoreIfNeeded();
  47. },
  48. detachScroll() {
  49. (this.scrollElement || window).removeEventListener('scroll', this.loadMoreIfNeeded);
  50. (this.scrollElement || window).removeEventListener('resize', this.loadMoreIfNeeded);
  51. this.scrollElement = null;
  52. },
  53. componentDidMount() {
  54. this.attachScroll();
  55. },
  56. componentDidUpdate() {
  57. this.attachScroll();
  58. },
  59. componentWillUnmount() {
  60. this.detachScroll();
  61. },
  62. };
  63. export default InfiniteScroll