use*_*318 5 javascript android dom webview
即时通讯使用android打开本地Web文件,然后迭代dom并应用一些更改但是当它迭代webview停止在某个随机部分呈现页面时,看看gif:
我已经做了什么
var elements = document.querySelectorAll("P");
for(var i = 0; i < elements.length;i++) {
//just iterating at the gif im chaging
//but i tried without changing, just iterating and the result still the same
}
Run Code Online (Sandbox Code Playgroud)
现在为了避免在每个dom更改时出现渲染问题,我创建了一个documentFragment并更改了它中的dom(或者只是迭代)而不是将其html返回到主文档
var x = document.getElementById('contentRoot'); //getting the element root from the DOCUMENT (not the fragment)
var frag = document.createDocumentFragment(); //creating fragment
var contentRoot = document.createElement("DIV"); // creating a new contentRoot html element
contentRoot.id = 'contentRoot';
contentRoot.innerHTML = x.innerHTML;
frag.appendChild( contentRoot );
var elements = frag.querySelectorAll("P");
for(var i = 0; i < elements.length;i++) {
//just iterating at the gif im chaging
//but i tried without changing, just iterating and the result still the same
}
document.body.innerHTML = frag.getElementById('contentRoot').innerHTML; //returning the edited html from the fragment so the webview will render/reflow just once everything not for each change
Run Code Online (Sandbox Code Playgroud)
有没有办法保持渲染正常而不"切割"?
PS:我正在使用函数迭代window.onload,所以它只是在所有dom加载到浏览器后启动,为什么它一直在切割它?并在迭代结束时再次渲染?
JavaScript 的问题在于,当 JavaScript 运行时,整个页面会被冻结并且不会呈现任何内容。如果您正在运行一个非常大的 for 循环,这可以解释您的问题。
大多数桌面计算机浏览器将在渲染页面的同时渲染滚动(我敢打赌,如果您在桌面浏览器上运行此页面,它甚至不会让您滚动)。
然而,大多数移动设备为了看起来快速而流畅,会将滚动与页面本身分开呈现。这样做的问题是,如果 JavaScript 陷入运行很长的循环,用户将能够滚动,但页面不会在他们之前渲染,最终到达这个尚未渲染任何内容的空白区域。
我敢打赌,如果您在函数运行时尝试放大页面,它看起来会非常模糊,因为没有进行渲染。
解决此问题的一种方法是使用计时器或 requestAnimationFrame API。
requestAnimationFrame几乎所有现代浏览器都支持。它的作用是将代码推迟到渲染下一帧为止,并且通常用于制作流畅的动画。
使用这个 API,我创建了以下代码...
var elements = document.querySelectorAll("P");
var i = 0;
var j = elements.length;
function iterate(){
// this acts as the body of your for loop
// do stuff with the current selected DOM element here...
// select dom element with elements[i]
i++;
if(i < j){
requestAnimationFrame(iterate);
}
}
iterate();
Run Code Online (Sandbox Code Playgroud)
现在,上面的代码在每个动画帧运行 for 循环的迭代。假设您的设备以 60 fps 运行,则每秒最多可进行 60 次迭代。
为了解决这个问题并使其更快,我们可以requestAnimationFrame(iterate)用替代代码替换window.setTimeout(iterate, 0),这实际上告诉浏览器每毫秒进行一次迭代,同时仍然能够渲染页面。然而,这种方法会降低帧速率。(但是,对于像您这样处理单独滚动的移动浏览器,帧率不应该成为问题)
编辑:
当我使用上述方法在桌面浏览器中运行一个相当简单但很长的循环时,我实现了 JavaScript 测量的 60fps,每秒大约 150 - 200 次迭代。如果您使用移动设备,结果可能会更慢。
替代建议:
如果您想使用预构建的 API 来完成此类任务,那么有一个看起来非常酷的 API。OP 找到了一个名为 Turboid 的工具,可以让您更轻松地管理这种循环。http://turboid.net/artikel/real-loops-in-javascript.php
| 归档时间: |
|
| 查看次数: |
176 次 |
| 最近记录: |