utils.js 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import addEventListener from '../vc-util/Dom/addEventListener';
  2. import supportsPassive from '../_util/supportsPassive';
  3. export function getTargetRect(target) {
  4. return target !== window ? target.getBoundingClientRect() : {
  5. top: 0,
  6. bottom: window.innerHeight
  7. };
  8. }
  9. export function getFixedTop(placeholderRect, targetRect, offsetTop) {
  10. if (offsetTop !== undefined && targetRect.top > placeholderRect.top - offsetTop) {
  11. return `${offsetTop + targetRect.top}px`;
  12. }
  13. return undefined;
  14. }
  15. export function getFixedBottom(placeholderRect, targetRect, offsetBottom) {
  16. if (offsetBottom !== undefined && targetRect.bottom < placeholderRect.bottom + offsetBottom) {
  17. const targetBottomOffset = window.innerHeight - targetRect.bottom;
  18. return `${offsetBottom + targetBottomOffset}px`;
  19. }
  20. return undefined;
  21. }
  22. // ======================== Observer ========================
  23. const TRIGGER_EVENTS = ['resize', 'scroll', 'touchstart', 'touchmove', 'touchend', 'pageshow', 'load'];
  24. let observerEntities = [];
  25. export function getObserverEntities() {
  26. // Only used in test env. Can be removed if refactor.
  27. return observerEntities;
  28. }
  29. export function addObserveTarget(target, affix) {
  30. if (!target) return;
  31. let entity = observerEntities.find(item => item.target === target);
  32. if (entity) {
  33. entity.affixList.push(affix);
  34. } else {
  35. entity = {
  36. target,
  37. affixList: [affix],
  38. eventHandlers: {}
  39. };
  40. observerEntities.push(entity);
  41. // Add listener
  42. TRIGGER_EVENTS.forEach(eventName => {
  43. entity.eventHandlers[eventName] = addEventListener(target, eventName, () => {
  44. entity.affixList.forEach(targetAffix => {
  45. const {
  46. lazyUpdatePosition
  47. } = targetAffix.exposed;
  48. lazyUpdatePosition();
  49. }, (eventName === 'touchstart' || eventName === 'touchmove') && supportsPassive ? {
  50. passive: true
  51. } : false);
  52. });
  53. });
  54. }
  55. }
  56. export function removeObserveTarget(affix) {
  57. const observerEntity = observerEntities.find(oriObserverEntity => {
  58. const hasAffix = oriObserverEntity.affixList.some(item => item === affix);
  59. if (hasAffix) {
  60. oriObserverEntity.affixList = oriObserverEntity.affixList.filter(item => item !== affix);
  61. }
  62. return hasAffix;
  63. });
  64. if (observerEntity && observerEntity.affixList.length === 0) {
  65. observerEntities = observerEntities.filter(item => item !== observerEntity);
  66. // Remove listener
  67. TRIGGER_EVENTS.forEach(eventName => {
  68. const handler = observerEntity.eventHandlers[eventName];
  69. if (handler && handler.remove) {
  70. handler.remove();
  71. }
  72. });
  73. }
  74. }