【问题标题】:UI is not updating while scrolling the UI滚动 UI 时 UI 不更新
【发布时间】:2018-06-01 19:05:17
【问题描述】:

我正在开发 Cordova 应用程序。我在哪里连接到实时传感器并从传感器读取一些数据。问题是当我滚动视图时数据被打乱了。这适用于 android,但不适用于 iOS。

这是我的代码 sn-p。

<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。

【问题讨论】:

  • 您能否提供一些细节,例如,哪个版本的 iOS 不工作?您是否在较低版本的 iOS 中进行了测试?您是否使用任何分页?
  • 我可以在从 iOS 9 到 iOS 11 的所有 iOS 设备中看到这个问题。没有使用分页。 UI 会随着数据的增长而增长。
  • 你可以看看这是否有帮助。 patrickmuff.ch/blog/2014/10/01/…
  • 我已经提到了这个链接。我的问题是滚动时 dataReceivedCallback 没有调用。
  • 是否可以为原生ui代码创建一个新线程,并在UIWebView上添加一个事件监听器?如果在滚动时未调用回调,则假定滚动阻止您的本机代码执行,新线程可以解决这个问题。我会考虑将这一切都与事件挂钩,因为随着本机代码同时运行,设置是异步的,并且发出事件将有助于解耦系统的这两个部分,并让 webview 决定何时更新视图的 JS 代码被调用...

标签: javascript ios cordova uiwebview phonegap


【解决方案1】:

iOS 在滚动期间暂停 JS 执行以提供流畅的滚动体验。 Apple 建议使用被动事件侦听器进行滚动。即使基于尝试去抖动执行的其他答案,也无法解决您的问题。您可以尝试将被动设置为 true:

something.addEventListener("scroll", callback, { passive: true })

虽然它可以改善您的情况,但很可能无法解决您在 iOS 上遇到的问题。

尝试将您的代码封装在 requestIdleCallbackrequestAnimationFrame 中。

请确保您遵循不要多次访问 DOM 树的建议。

【讨论】:

    【解决方案2】:

    我不是 100% 完全理解你的情况,但我认为你应该这样做:

    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 毫秒触发一次,这应该为处理滚动事件留出足够的空间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-04
      • 1970-01-01
      • 1970-01-01
      • 2013-07-25
      • 1970-01-01
      • 2018-12-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多