popover.js 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. const { windowWidth, windowHeight } = wx.getSystemInfoSync();
  2. // 三角形箭头的高度
  3. const trangleHeight = 12;
  4. Component({
  5. relations: {
  6. './popover-item': {
  7. type: 'child'
  8. }
  9. },
  10. data: {
  11. // 当前显隐状态
  12. visible: false,
  13. // popover 宽
  14. pw: 100,
  15. // popover 高
  16. ph: 120,
  17. // popover 距左距离
  18. px: 0,
  19. // popover 距上距离
  20. py: 0,
  21. // 垂直方向 top/bottom
  22. vertical: '',
  23. // 水平方向 left/center/right
  24. align: ''
  25. },
  26. methods: {
  27. onDisplay: function(e) {
  28. let self = this;
  29. if (self.last && self.last === e.id) {
  30. self.setData({
  31. visible: !self.data.visible
  32. });
  33. } else {
  34. wx.createSelectorQuery().selectViewport().scrollOffset(view => {
  35. let { pw, ph, px, py, vertical, align } = self.data;
  36. let pOverW = (pw - e.width) / 2;
  37. let offsetL = e.left,
  38. offsetR = windowWidth - e.right,
  39. offsetB = windowHeight - e.bottom;
  40. if (offsetL >= pOverW && offsetR >= pOverW) {
  41. align = 'center';
  42. px = e.left - pOverW;
  43. } else if (offsetL > pOverW && offsetR < pOverW) {
  44. align = 'left';
  45. px = windowWidth - (offsetR + pw);
  46. // 如果向右贴边了,设置一点距离
  47. if ((windowWidth - pw) == px) px -= 5;
  48. } else if (offsetL < pOverW && offsetR > pOverW) {
  49. align = 'right';
  50. px = e.left;
  51. // 如果向左贴边了,设置一点距离
  52. if (px == 0) px += 5;
  53. }
  54. if (offsetB >= (ph + trangleHeight)) {
  55. vertical = 'bottom';
  56. py = view.scrollTop + e.bottom + trangleHeight;
  57. } else {
  58. vertical = 'top';
  59. py = view.scrollTop + e.top - ph - trangleHeight;
  60. }
  61. self.setData({
  62. visible: true,
  63. px: px,
  64. py: py,
  65. ph: self.getItemsHeight(),
  66. vertical: vertical,
  67. align: align
  68. });
  69. }).exec();
  70. }
  71. // 记录上一次点击的元素
  72. self.last = e.id;
  73. },
  74. onHide: function() {
  75. this.setData({
  76. visible: false
  77. });
  78. },
  79. // 获取所有子元素
  80. getItems: function() {
  81. return this.getRelationNodes('./popover-item');
  82. },
  83. // 获取所有子元素的总高度
  84. getItemsHeight() {
  85. return this.getItems().map(item => item.data.height).reduce((a, b) => a + b, 0);
  86. }
  87. }
  88. })