WKWebView - 防止用户文本选择触发自动滚动

2024-01-27

当用户执行点击并按住手势来选择单词,然后将手指向屏幕的顶部或底部边缘拖动时,页面会自动滚动以适应选择。

这是一个短片演示它 https://youtu.be/Fw4cqH4gt6Y

我想防止这种行为WKWebView.

这是我到目前为止所尝试过的:

in a bridge.jswebview可以访问的文件:

var shouldAllowScrolling = true;

document.addEventListener('selectionchange', e => {
    shouldAllowScrolling = getSelectedText().length === 0;
    window.webkit.messageHandlers.selectionChangeHandler.postMessage(
        {
            shouldAllowScrolling: shouldAllowScrolling
        });
    console.log('allow scrolling = ', shouldAllowScrolling);
});

然后在一个WKScriptMessageHandler执行:

public func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
    {
        switch message.name
        {
        case "selectionChangeHandler":
            let params = paramsDictionary(fromMessageBody: message.body)
            let shouldEnableScrolling = params["shouldAllowScrolling"] as? Bool ?? true
            cell?.webView.scrollView.isScrollEnabled = shouldEnableScrolling
            cell?.webView.scrollView.isUserInteractionEnabled = shouldEnableScrolling // not together with the line above 
        default:
            fatalError("\(#function): received undefined message handler name: \(message.name)")
        }
    }

同样,我尝试致电preventDefault()直接在 javascript 文件中处理一系列事件的函数,即scroll and touchmove,像这样:

document.addEventListener('touchmove', e => {
    if (!shouldAllowScrolling) {
        e.preventDefault()
    }
}, {passive: false});

当选择某些文本时,这两种方法都可以成功防止滚动,但不会覆盖我的问题顶部描述的行为。

我可以接受 Swift 和 JavaScript 或两者混合的解决方案。


我最终通过保存最后的滚动位置并在适当的时候滚动到它来解决这个问题,如下所示:

var shouldAllowScrolling = true;
var lastSavedScrollLeft = 0;
var lastSavedScrollTop = 0;

function saveScrollPosition() {
    lastSavedScrollLeft = window.pageXOffset || document.documentElement.scrollLeft;
    lastSavedScrollTop = window.pageYOffset || document.documentElement.scrollTop;
}

document.addEventListener('touchstart', e => {
    saveScrollPosition();
});

document.addEventListener('touchend', () => {
    // enable scrolling when the user lifts their finger, to allow scrolling while text selection is still present
    shouldAllowScrolling = true;
});

document.addEventListener('scroll', e => {
    if (!shouldAllowScrolling) {
        window.scrollTo(lastSavedScrollLeft, lastSavedScrollTop);
    }
});

document.addEventListener('selectionchange', e => {
    shouldAllowScrolling = getSelectedText().length === 0;
});

如果有人可以提供更优雅的解决方案来完全阻止滚动,我很乐意接受它。

EDIT:

此解决方案可能会导致轻微晃动/抖动。

这可以通过本机禁用滚动来解决shouldAllowScrolling被设定为false,像这样:

webView.scrollView.isScrollEnabled = false
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

WKWebView - 防止用户文本选择触发自动滚动 的相关文章

随机推荐