我正在开发Cordova应用程序。我在哪里连接到实时传感器并从传感器读取一些数据。问题是当我滚动视图时数据被加扰。这适用于Android,但不适用于iOS。
这是我的代码段。
<div id="right_col">
<button onclick="clearReceivedData()">Clear Received Data</button>
<br>
<div id="receivedData"></div>
</div>
function dataReceivedCallback(data) {
document.getElementById("receivedData").innerHTML += data.value1 + ": ";
document.getElementById("receivedData").innerHTML += data.value2 + ":";
document.getElementById("receivedData").innerHTML += data.value3 + "<br>";
}
对于从传感器接收的每个数据,将调用 dataReceivedCallback
。此回调也会阻塞,直到滚动完成。如何在滚动UI时更新UI。
答案 0 :(得分:1)
iOS在滚动过程中暂停JS执行,以提供流畅的滚动体验。苹果公司建议使用被动事件监听器进行滚动。即使基于试图消除执行力的其他答案,也无法解决您的问题。您可以尝试将被动设置为true:
something.addEventListener("scroll", callback, { passive: true })
尽管它可以改善您的状况,但很可能无法解决您在iOS上遇到的问题。
尝试将代码包装在requestIdleCallback
或requestAnimationFrame
中。
请确保您遵循的建议是不要多次访问DOM树。
答案 1 :(得分:0)
我不太了解您的情况,但我认为您应该这样做:
1-尽可能少地访问innerHTML
,每次读取或写入元素属性时都强制重新渲染文档,下面提供一种更好的方法。
function dataReceivedCallback(data) {
var newHTML = '';
newHTML += data.value1 + ": ";
newHTML += data.value2 + ":";
newHTML += data.value3 + "<br>";
document.getElementById("receivedData").innerHTML += newHTML;
}
如您所见,我们只访问一次innerHTML
而不是3
2-您需要为浏览器留出一些空间来处理滚动事件,因此需要使用异步功能更新ui,同样可以利用超时功能来做到这一点:
var timeoutHandller;
function dataReceivedCallback(data) {
clearTimeout(timeoutHandller);
timeoutHandller = setTimeout(function() {
var newHTML = '';
newHTML += data.value1 + ": ";
newHTML += data.value2 + ":";
newHTML += data.value3 + "<br>";
document.getElementById("receivedData").innerHTML += newHTML;
}, 150);
}
现在,UI更新每150毫秒触发一次,这将为处理滚动事件留出足够的空间。