在iOS中滚动<div>会导致div空白

Ric*_*ahl 5 html5 ios cordova

我正在尝试处理一长串的<div>s并在导航和返回后保持列表中的滚动位置.基本上,如果在列表中进行了选择,我会捕获listScrollPos,然后在我返回页面时尝试重置它(在Angular中 - 因此首先重新呈现列表).

vm.getAlbums = function() {
    albumService.getAlbums()
        .success(function (data) {
            vm.albums = data;                    
            $timeout(function () {                        
                if (albumService.listScrollPos) {
                    $("#MainView").scrollTop(albumService.listScrollPos);
                    albumService.listScrollPos = 0;
                }
            }, 50); // delay required
        })
        .error(function(err) {
            vm.error.error(err.message);
        });
};
Run Code Online (Sandbox Code Playgroud)

这个过程在我测试的所有浏览器中都能正常工作 - 除了在WebView中的iOS上(Safari工作正常).在其他浏览器中,列表显示,并在初始渲染后移动滚动位置.指针重置,一切都很好.

但是,在Safari 8或在Cordova的Web View中的iOS 8上,div变为白色并显示"空".如果我在任何地方触摸div,它会立即显示在正确的滚动位置.

IOW,DOM似乎被更新和渲染,但浏览器以某种方式优化了在程序控制下移动的滚动内容.

在以编程方式移动滚动位置后,有没有办法强制浏览器重新呈现元素?

Ric*_*ahl 3

好的,经过更多检查后,问题肯定与 iOS WebView 无关 - iOS 上的 Safari 可以正常工作,无需执行以下任何操作。但 Cordova 应用程序或固定的 iOS 应用程序会表现出这种“白色”行为。

解决方法是使用“scrollHeight 读取技巧”显式强制 DOM 重新渲染元素。

这是有效的代码:

vm.getAlbums = function() {
    albumService.getAlbums()
        .success(function (data) {
            vm.albums = data;                    
            setTimeout(function () {                        
                if (albumService.listScrollPos) {
                    var el = $("#MainView");
                    el.scrollTop(albumService.listScrollPos);
                    albumService.listScrollPos = 0;
                    $timeout(function() {
                        var t = el[0].scrollHeight;
                    }, 1);
                }
            }, 1); // delay around animation 900
        })
};
Run Code Online (Sandbox Code Playgroud)

请注意最后一个 $timeout() 块,它只是读取元素的滚动高度,这会强制重新渲染并正确显示结果。

由于轻微的渲染延迟,有一点跳跃。