kamrify commited on
Commit
fa4fbb8
·
1 Parent(s): a2f6883

Positioning the popover by giving position

Browse files
Files changed (2) hide show
  1. assets/scripts/src/popover.js +112 -24
  2. index.html +12 -2
assets/scripts/src/popover.js CHANGED
@@ -21,20 +21,21 @@ export default class Popover extends Element {
21
  this.window = window;
22
  this.document = document;
23
 
24
- this.node = this.makeNode();
25
  this.hide();
26
  }
27
 
28
  makeNode() {
29
  let popover = this.document.getElementById(ID_POPOVER);
30
- if (popover) {
31
- return popover;
 
32
  }
33
 
34
- popover = Popover.createFromString(POPOVER_HTML);
35
- document.body.appendChild(popover);
36
-
37
- return popover;
38
  }
39
 
40
  /**
@@ -50,8 +51,11 @@ export default class Popover extends Element {
50
  return div.firstChild;
51
  }
52
 
53
- getHeight() {
54
- return Math.max(this.node.scrollHeight, this.node.offsetHeight);
 
 
 
55
  }
56
 
57
  hide() {
@@ -74,29 +78,113 @@ export default class Popover extends Element {
74
  show(position) {
75
  this.reset();
76
 
77
- const popoverTip = this.node.querySelector(`.${CLASS_POPOVER_TIP}`);
78
- const popoverTitle = this.node.querySelector(`.${CLASS_POPOVER_TITLE}`);
79
- const popoverDescription = this.node.querySelector(`.${CLASS_POPOVER_DESCRIPTION}`);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
80
 
81
- popoverTitle.innerText = this.options.title;
82
- popoverDescription.innerText = this.options.description;
 
 
 
 
 
 
 
 
 
83
 
84
- const pageHeight = this.getFullPageSize().height;
85
- const popoverMargin = this.options.padding + 10;
86
- const popoverHeight = this.getHeight();
 
 
 
 
 
 
 
 
87
 
88
- this.node.style.left = `${position.left - this.options.padding}px`;
 
 
89
 
90
- // Calculate different dimensions after attaching popover
91
- const pageHeightAfterPopOver = position.bottom + popoverHeight + popoverMargin;
92
 
93
  // If adding popover would go out of the window height, then show it to the top
94
  if (pageHeightAfterPopOver >= pageHeight) {
95
- this.node.style.top = `${position.top - popoverHeight - popoverMargin}px`;
96
- popoverTip.classList.add('bottom');
97
  } else {
98
- this.node.style.top = `${position.bottom + popoverMargin}px`;
99
- popoverTip.classList.add('top');
100
  }
101
  }
102
  }
 
21
  this.window = window;
22
  this.document = document;
23
 
24
+ this.makeNode();
25
  this.hide();
26
  }
27
 
28
  makeNode() {
29
  let popover = this.document.getElementById(ID_POPOVER);
30
+ if (!popover) {
31
+ popover = Popover.createFromString(POPOVER_HTML);
32
+ document.body.appendChild(popover);
33
  }
34
 
35
+ this.node = popover;
36
+ this.tipNode = popover.querySelector(`.${CLASS_POPOVER_TIP}`);
37
+ this.titleNode = popover.querySelector(`.${CLASS_POPOVER_TITLE}`);
38
+ this.descriptionNode = popover.querySelector(`.${CLASS_POPOVER_DESCRIPTION}`);
39
  }
40
 
41
  /**
 
51
  return div.firstChild;
52
  }
53
 
54
+ getSize() {
55
+ return {
56
+ height: Math.max(this.node.scrollHeight, this.node.offsetHeight),
57
+ width: Math.max(this.node.scrollWidth, this.node.offsetWidth),
58
+ };
59
  }
60
 
61
  hide() {
 
78
  show(position) {
79
  this.reset();
80
 
81
+ // Set the title and descriptions
82
+ this.titleNode.innerText = this.options.title;
83
+ this.descriptionNode.innerText = this.options.description;
84
+
85
+ // Position the popover around the given position
86
+ switch (this.options.position) {
87
+ case 'left':
88
+ this.positionOnLeft(position);
89
+ break;
90
+ case 'right':
91
+ this.positionOnRight(position);
92
+ break;
93
+ case 'top':
94
+ this.positionOnTop(position);
95
+ break;
96
+ case 'bottom':
97
+ this.positionOnBottom(position);
98
+ break;
99
+ case 'auto':
100
+ default:
101
+ this.autoPosition(position);
102
+ break;
103
+ }
104
+ }
105
+
106
+ /**
107
+ * Shows the popover on the left of the given position
108
+ * @param elementPosition
109
+ */
110
+ positionOnLeft(elementPosition) {
111
+ const popoverWidth = this.getSize().width;
112
+ const popoverMargin = this.options.padding + 10; // adding 10 to give it a little distance from the element
113
+
114
+ this.node.style.left = `${elementPosition.left - popoverWidth - popoverMargin}px`;
115
+ this.node.style.top = `${elementPosition.top - this.options.padding}px`;
116
+ this.node.style.right = '';
117
+ this.node.style.bottom = '';
118
+
119
+ this.tipNode.classList.add('right');
120
+ }
121
+
122
+ /**
123
+ * Shows the popover on the right of the given position
124
+ * @param elementPosition
125
+ */
126
+ positionOnRight(elementPosition) {
127
+ const popoverMargin = this.options.padding + 10; // adding 10 to give it a little distance from the element
128
+
129
+ this.node.style.left = `${elementPosition.right + popoverMargin}px`;
130
+ this.node.style.top = `${elementPosition.top - this.options.padding}px`;
131
+ this.node.style.right = '';
132
+ this.node.style.bottom = '';
133
+
134
+ this.tipNode.classList.add('left');
135
+ }
136
+
137
+ /**
138
+ * Shows the popover on the top of the given position
139
+ * @param elementPosition
140
+ */
141
+ positionOnTop(elementPosition) {
142
+ const popoverHeight = this.getSize().height;
143
+ const popoverMargin = this.options.padding + 10; // adding 10 to give it a little distance from the element
144
+
145
+ this.node.style.top = `${elementPosition.top - popoverHeight - popoverMargin}px`;
146
+ this.node.style.left = `${elementPosition.left - this.options.padding}px`;
147
+ this.node.style.right = '';
148
+ this.node.style.bottom = '';
149
+
150
+ this.tipNode.classList.add('bottom');
151
+ }
152
 
153
+ /**
154
+ * Shows the popover on the bottom of the given position
155
+ * @param elementPosition
156
+ */
157
+ positionOnBottom(elementPosition) {
158
+ const popoverMargin = this.options.padding + 10; // adding 10 to give it a little distance from the element
159
+
160
+ this.node.style.top = `${elementPosition.bottom + popoverMargin}px`;
161
+ this.node.style.left = `${elementPosition.left - this.options.padding}px`;
162
+ this.node.style.right = '';
163
+ this.node.style.bottom = '';
164
 
165
+ this.tipNode.classList.add('top');
166
+ }
167
+
168
+ /**
169
+ * Automatically positions the popover around the given position
170
+ * such that the element and popover remain in view
171
+ * @param elementPosition
172
+ */
173
+ autoPosition(elementPosition) {
174
+ const pageSize = this.getFullPageSize();
175
+ const popoverSize = this.getSize();
176
 
177
+ const pageHeight = pageSize.height;
178
+ const popoverHeight = popoverSize.height;
179
+ const popoverMargin = this.options.padding + 10; // adding 10 to give it a little distance from the element
180
 
181
+ const pageHeightAfterPopOver = elementPosition.bottom + popoverHeight + popoverMargin;
 
182
 
183
  // If adding popover would go out of the window height, then show it to the top
184
  if (pageHeightAfterPopOver >= pageHeight) {
185
+ this.positionOnTop(elementPosition);
 
186
  } else {
187
+ this.positionOnBottom(elementPosition);
 
188
  }
189
  }
190
  }
index.html CHANGED
@@ -68,24 +68,34 @@
68
  element: '.section__header',
69
  popover: {
70
  title: 'Adding Introductions',
71
- description: 'You can use it to add popovers on top of the website'
 
72
  },
73
  },
74
  {
75
  element: '.section__how',
76
  popover: {
77
  title: 'Just Specify the Item',
78
- description: 'All you have to do is provide the query selector of element to highlight'
 
79
  },
80
  },
81
  {
82
  element: '.section__purpose',
 
 
 
 
83
  },
84
  {
85
  element: '.section__examples',
86
  },
87
  {
88
  element: '.section__contributing',
 
 
 
 
89
  },
90
  ]);
91
 
 
68
  element: '.section__header',
69
  popover: {
70
  title: 'Adding Introductions',
71
+ description: 'You can use it to add popovers on top of the website',
72
+ position: 'left'
73
  },
74
  },
75
  {
76
  element: '.section__how',
77
  popover: {
78
  title: 'Just Specify the Item',
79
+ description: 'All you have to do is provide the query selector of element to highlight',
80
+ position: 'right'
81
  },
82
  },
83
  {
84
  element: '.section__purpose',
85
+ popover: {
86
+ title: 'Automatically Position',
87
+ description: 'It can automatically position too if you dont provide'
88
+ }
89
  },
90
  {
91
  element: '.section__examples',
92
  },
93
  {
94
  element: '.section__contributing',
95
+ popover: {
96
+ title: 'Automatically Position',
97
+ description: 'It can automatically position too if you dont provide'
98
+ }
99
  },
100
  ]);
101