@dolphinweex/weex-harmony 0.1.74 → 0.1.76
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -38,6 +38,8 @@ export default {
|
|
|
38
38
|
Date.now().toString(36) + Math.random().toString(36).substring(2)
|
|
39
39
|
}`,
|
|
40
40
|
height: '0px',
|
|
41
|
+
_resizeObserver: null,
|
|
42
|
+
_heightCheckTimer: null,
|
|
41
43
|
};
|
|
42
44
|
},
|
|
43
45
|
components: {
|
|
@@ -126,20 +128,6 @@ export default {
|
|
|
126
128
|
this._rafId = null;
|
|
127
129
|
this._pendingGesture = null;
|
|
128
130
|
this._onMessage = (event) => {
|
|
129
|
-
if(event.data.type==='IFRAME_CONTENT_HEIGHT'){
|
|
130
|
-
const h = Number(event.data.height) || 0;
|
|
131
|
-
if (!h) {
|
|
132
|
-
this.height = '100%'
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
if (this._wrapperEl) {
|
|
136
|
-
this._wrapperEl.style.height = `${h}px`;
|
|
137
|
-
}
|
|
138
|
-
this.height = `${h / weex.config.env.scale}px`;
|
|
139
|
-
return
|
|
140
|
-
}else{
|
|
141
|
-
document.getElementsByTagName('iframe')[0].height = event.data.height
|
|
142
|
-
}
|
|
143
131
|
// 处理iframe手势跨窗口传递冒泡
|
|
144
132
|
if (event.data.type === 'IFRAME_GESTURE') {
|
|
145
133
|
const gestureData = event.data;
|
|
@@ -173,6 +161,135 @@ export default {
|
|
|
173
161
|
JSON.stringify(window.$midea_harmony_native),
|
|
174
162
|
"*"
|
|
175
163
|
);
|
|
164
|
+
|
|
165
|
+
// 启动 weex-root 第一个子元素的高度监听
|
|
166
|
+
this.startWeexRootHeightMonitoring();
|
|
167
|
+
}
|
|
168
|
+
},
|
|
169
|
+
|
|
170
|
+
// 监听 iframe 内 .weex-root 第一个子元素或 .weex-scroller-inner 的高度
|
|
171
|
+
startWeexRootHeightMonitoring() {
|
|
172
|
+
// 尝试多次查找元素(因为 iframe 内容可能还在加载)
|
|
173
|
+
let attempts = 0;
|
|
174
|
+
const maxAttempts = 20; // 最多尝试 20 次
|
|
175
|
+
|
|
176
|
+
this._heightCheckTimer = setInterval(() => {
|
|
177
|
+
attempts++;
|
|
178
|
+
|
|
179
|
+
const iframe = document.getElementById(this.embedId);
|
|
180
|
+
if (!iframe) {
|
|
181
|
+
if (attempts >= maxAttempts) {
|
|
182
|
+
clearInterval(this._heightCheckTimer);
|
|
183
|
+
console.warn(`未找到 iframe: ${this.embedId}`);
|
|
184
|
+
}
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
try {
|
|
189
|
+
const iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
|
|
190
|
+
let targetElement = null;
|
|
191
|
+
let elementDesc = '';
|
|
192
|
+
|
|
193
|
+
// 查找 .weex-root 的第一个子元素
|
|
194
|
+
const weexRoot = iframeDocument.querySelector('.weex-root');
|
|
195
|
+
const weexRootFirstChild = (weexRoot && weexRoot.children.length > 0) ? weexRoot.children[0] : null;
|
|
196
|
+
|
|
197
|
+
// 查找 .weex-scroller-inner
|
|
198
|
+
const weexScrollerInner = iframeDocument.querySelector('.weex-scroller-inner');
|
|
199
|
+
|
|
200
|
+
// 如果两个都找到了,比较高度,谁大用谁
|
|
201
|
+
if (weexRootFirstChild && weexScrollerInner) {
|
|
202
|
+
const rootHeight = weexRootFirstChild.offsetHeight || weexRootFirstChild.clientHeight || 0;
|
|
203
|
+
const scrollerHeight = weexScrollerInner.offsetHeight || weexScrollerInner.clientHeight || 0;
|
|
204
|
+
|
|
205
|
+
if (rootHeight >= scrollerHeight) {
|
|
206
|
+
targetElement = weexRootFirstChild;
|
|
207
|
+
elementDesc = `.weex-root 的第一个子元素 (高度: ${rootHeight}px)`;
|
|
208
|
+
} else {
|
|
209
|
+
targetElement = weexScrollerInner;
|
|
210
|
+
elementDesc = `.weex-scroller-inner (高度: ${scrollerHeight}px)`;
|
|
211
|
+
}
|
|
212
|
+
} else if (weexRootFirstChild) {
|
|
213
|
+
// 只找到 .weex-root 的第一个子元素
|
|
214
|
+
targetElement = weexRootFirstChild;
|
|
215
|
+
elementDesc = '.weex-root 的第一个子元素';
|
|
216
|
+
} else if (weexScrollerInner) {
|
|
217
|
+
// 只找到 .weex-scroller-inner
|
|
218
|
+
targetElement = weexScrollerInner;
|
|
219
|
+
elementDesc = '.weex-scroller-inner';
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// 找到目标元素,开始监听
|
|
223
|
+
if (targetElement) {
|
|
224
|
+
console.log(`找到 ${elementDesc},开始监听高度变化`, targetElement);
|
|
225
|
+
|
|
226
|
+
// 清除定时器,找到了就不再尝试
|
|
227
|
+
clearInterval(this._heightCheckTimer);
|
|
228
|
+
|
|
229
|
+
// 立即更新一次高度
|
|
230
|
+
this.updateIframeHeightFromElement(targetElement);
|
|
231
|
+
|
|
232
|
+
// 使用 ResizeObserver 监听元素高度变化
|
|
233
|
+
this._resizeObserver = new ResizeObserver(() => {
|
|
234
|
+
this.updateIframeHeightFromElement(targetElement);
|
|
235
|
+
});
|
|
236
|
+
this._resizeObserver.observe(targetElement);
|
|
237
|
+
|
|
238
|
+
} else if (attempts >= maxAttempts) {
|
|
239
|
+
clearInterval(this._heightCheckTimer);
|
|
240
|
+
console.warn('未找到 .weex-root 的第一个子元素 或 .weex-scroller-inner');
|
|
241
|
+
}
|
|
242
|
+
} catch (e) {
|
|
243
|
+
if (attempts >= maxAttempts) {
|
|
244
|
+
clearInterval(this._heightCheckTimer);
|
|
245
|
+
console.warn('无法访问 iframe 内容(可能跨域):', e.message);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}, 200); // 每 200ms 尝试一次
|
|
249
|
+
},
|
|
250
|
+
|
|
251
|
+
// 根据元素高度更新 iframe 高度
|
|
252
|
+
updateIframeHeightFromElement(element) {
|
|
253
|
+
if (!element) return;
|
|
254
|
+
|
|
255
|
+
// 获取元素的实际高度
|
|
256
|
+
const elementHeight = element.offsetHeight || element.clientHeight || element.scrollHeight;
|
|
257
|
+
|
|
258
|
+
if (elementHeight > 0) {
|
|
259
|
+
// 限制最大高度,防止死循环
|
|
260
|
+
// 策略:使用 window.innerHeight 减去 iframe 距离视口顶部的距离
|
|
261
|
+
let maxHeight = window.innerHeight;
|
|
262
|
+
|
|
263
|
+
if (this.$refs.iframe) {
|
|
264
|
+
try {
|
|
265
|
+
const rect = this.$refs.iframe.getBoundingClientRect();
|
|
266
|
+
// 如果 top > 0,说明 iframe 顶部在视口下方或视口内,减去 top 得到剩余可用高度
|
|
267
|
+
// 如果 top <= 0,说明 iframe 顶部已滚出视口上方,此时最大高度限制为 window.innerHeight (防止无限增高)
|
|
268
|
+
if (rect.top > 0) {
|
|
269
|
+
maxHeight = window.innerHeight - rect.top;
|
|
270
|
+
}
|
|
271
|
+
} catch (e) {
|
|
272
|
+
console.warn('获取 iframe 位置失败:', e);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// 确保 maxHeight 不为负数
|
|
277
|
+
maxHeight = Math.max(maxHeight, 0);
|
|
278
|
+
|
|
279
|
+
// 如果计算出的高度超过了最大限制,则使用最大限制
|
|
280
|
+
const finalHeight = elementHeight > maxHeight ? maxHeight : elementHeight;
|
|
281
|
+
|
|
282
|
+
// 更新包装器高度
|
|
283
|
+
if (this._wrapperEl) {
|
|
284
|
+
this._wrapperEl.style.height = `${finalHeight}px`;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// 更新 iframe 高度(考虑 weex scale)
|
|
288
|
+
const newHeight = `${finalHeight / weex.config.env.scale}px`;
|
|
289
|
+
if (this.height !== newHeight) {
|
|
290
|
+
this.height = newHeight;
|
|
291
|
+
console.log(`iframe 高度已更新: ${finalHeight}px -> ${newHeight} (embedId: ${this.embedId}, max: ${maxHeight}px)`);
|
|
292
|
+
}
|
|
176
293
|
}
|
|
177
294
|
},
|
|
178
295
|
handleGestureBubble(gestureData) {
|
|
@@ -220,11 +337,24 @@ export default {
|
|
|
220
337
|
},
|
|
221
338
|
},
|
|
222
339
|
beforeDestroy() {
|
|
340
|
+
// 清理 ResizeObserver
|
|
341
|
+
if (this._resizeObserver) {
|
|
342
|
+
this._resizeObserver.disconnect();
|
|
343
|
+
this._resizeObserver = null;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
// 清理定时器
|
|
347
|
+
if (this._heightCheckTimer) {
|
|
348
|
+
clearInterval(this._heightCheckTimer);
|
|
349
|
+
this._heightCheckTimer = null;
|
|
350
|
+
}
|
|
351
|
+
|
|
223
352
|
// 清理RAF避免内存泄漏
|
|
224
353
|
if (this._rafId) {
|
|
225
354
|
cancelAnimationFrame(this._rafId);
|
|
226
355
|
this._rafId = null;
|
|
227
356
|
}
|
|
357
|
+
|
|
228
358
|
// 清理消息监听
|
|
229
359
|
if (this._onMessage) {
|
|
230
360
|
window.removeEventListener("message", this._onMessage, false);
|