index.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import util from "./util.js";
  2. function scrollIntoView(elem, container, config) {
  3. config = config || {}; // document 归一化到 window
  4. if (container.nodeType === 9) {
  5. container = util.getWindow(container);
  6. }
  7. var allowHorizontalScroll = config.allowHorizontalScroll;
  8. var onlyScrollIfNeeded = config.onlyScrollIfNeeded;
  9. var alignWithTop = config.alignWithTop;
  10. var alignWithLeft = config.alignWithLeft;
  11. var offsetTop = config.offsetTop || 0;
  12. var offsetLeft = config.offsetLeft || 0;
  13. var offsetBottom = config.offsetBottom || 0;
  14. var offsetRight = config.offsetRight || 0;
  15. allowHorizontalScroll = allowHorizontalScroll === undefined ? true : allowHorizontalScroll;
  16. var isWin = util.isWindow(container);
  17. var elemOffset = util.offset(elem);
  18. var eh = util.outerHeight(elem);
  19. var ew = util.outerWidth(elem);
  20. var containerOffset;
  21. var ch;
  22. var cw;
  23. var containerScroll;
  24. var diffTop;
  25. var diffBottom;
  26. var win;
  27. var winScroll;
  28. var ww;
  29. var wh;
  30. if (isWin) {
  31. win = container;
  32. wh = util.height(win);
  33. ww = util.width(win);
  34. winScroll = {
  35. left: util.scrollLeft(win),
  36. top: util.scrollTop(win)
  37. }; // elem 相对 container 可视视窗的距离
  38. diffTop = {
  39. left: elemOffset.left - winScroll.left - offsetLeft,
  40. top: elemOffset.top - winScroll.top - offsetTop
  41. };
  42. diffBottom = {
  43. left: elemOffset.left + ew - (winScroll.left + ww) + offsetRight,
  44. top: elemOffset.top + eh - (winScroll.top + wh) + offsetBottom
  45. };
  46. containerScroll = winScroll;
  47. } else {
  48. containerOffset = util.offset(container);
  49. ch = container.clientHeight;
  50. cw = container.clientWidth;
  51. containerScroll = {
  52. left: container.scrollLeft,
  53. top: container.scrollTop
  54. }; // elem 相对 container 可视视窗的距离
  55. // 注意边框, offset 是边框到根节点
  56. diffTop = {
  57. left: elemOffset.left - (containerOffset.left + (parseFloat(util.css(container, 'borderLeftWidth')) || 0)) - offsetLeft,
  58. top: elemOffset.top - (containerOffset.top + (parseFloat(util.css(container, 'borderTopWidth')) || 0)) - offsetTop
  59. };
  60. diffBottom = {
  61. left: elemOffset.left + ew - (containerOffset.left + cw + (parseFloat(util.css(container, 'borderRightWidth')) || 0)) + offsetRight,
  62. top: elemOffset.top + eh - (containerOffset.top + ch + (parseFloat(util.css(container, 'borderBottomWidth')) || 0)) + offsetBottom
  63. };
  64. }
  65. if (diffTop.top < 0 || diffBottom.top > 0) {
  66. // 强制向上
  67. if (alignWithTop === true) {
  68. util.scrollTop(container, containerScroll.top + diffTop.top);
  69. } else if (alignWithTop === false) {
  70. util.scrollTop(container, containerScroll.top + diffBottom.top);
  71. } else {
  72. // 自动调整
  73. if (diffTop.top < 0) {
  74. util.scrollTop(container, containerScroll.top + diffTop.top);
  75. } else {
  76. util.scrollTop(container, containerScroll.top + diffBottom.top);
  77. }
  78. }
  79. } else {
  80. if (!onlyScrollIfNeeded) {
  81. alignWithTop = alignWithTop === undefined ? true : !!alignWithTop;
  82. if (alignWithTop) {
  83. util.scrollTop(container, containerScroll.top + diffTop.top);
  84. } else {
  85. util.scrollTop(container, containerScroll.top + diffBottom.top);
  86. }
  87. }
  88. }
  89. if (allowHorizontalScroll) {
  90. if (diffTop.left < 0 || diffBottom.left > 0) {
  91. // 强制向上
  92. if (alignWithLeft === true) {
  93. util.scrollLeft(container, containerScroll.left + diffTop.left);
  94. } else if (alignWithLeft === false) {
  95. util.scrollLeft(container, containerScroll.left + diffBottom.left);
  96. } else {
  97. // 自动调整
  98. if (diffTop.left < 0) {
  99. util.scrollLeft(container, containerScroll.left + diffTop.left);
  100. } else {
  101. util.scrollLeft(container, containerScroll.left + diffBottom.left);
  102. }
  103. }
  104. } else {
  105. if (!onlyScrollIfNeeded) {
  106. alignWithLeft = alignWithLeft === undefined ? true : !!alignWithLeft;
  107. if (alignWithLeft) {
  108. util.scrollLeft(container, containerScroll.left + diffTop.left);
  109. } else {
  110. util.scrollLeft(container, containerScroll.left + diffBottom.left);
  111. }
  112. }
  113. }
  114. }
  115. }
  116. export default scrollIntoView;