【问题标题】:Programmatically select text in UIWebView以编程方式在 UIWebView 中选择文本
【发布时间】:2012-11-09 14:23:01
【问题描述】:

经过 2 天的研究,我提出了这个问题。我已经阅读了stackoverflow和google中的所有相关问题和答案(包括this问题,非常相似但没有答案),但仍然找不到解决方案。希望这里的人能够提供帮助。

我有一个 UIWebView,其中加载了一些文本。我想以编程方式选择部分文本,就像用户长按它一样。

我已尝试执行此 javascript 代码作为对点击的响应:

function selectEl(x,y)
{
    document.designMode = "on";
    var el = document.elementFromPoint(x, y);
    var range = document.createRange();
    range.selectNodeContents(el);
    var sel = document.getSelection();
    sel.removeAllRanges();
    sel.addRange(range);
    document.designMode = "off";
}

我已经尝试过在函数结束时将 designMode 更改为“off”,也可以不更改。 我知道这段代码“选择”了正确的元素,因为如果我执行这个命令

document.execCommand("BackColor", false, "#ffffcc");

它实际上突出显示了我单击的元素,但它不会导致选择文本。关于如何实现这一点的任何想法?

【问题讨论】:

标签: javascript iphone ios uiwebview


【解决方案1】:

这似乎是 Mobile Safari 中的一个错误。当我在 touchstart 中将 contentEditable 切换为 true 并在 touchend 中将其设置为 false 时,它​​可以工作。如果我删除这些行并刷新它仍然有效。如果我关闭 Mobile Safari,清除缓存,然后重新打开删除行的文档,它会再次停止工作。

我已经用一个工作版本更新了下面的代码(尽管为了简单起见,我删除了长按)。

<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">

(function() {
    var node,
        range,
        offset,
        clientX,
        clientY;

    document.addEventListener("DOMContentLoaded", function() {
        document.body.addEventListener("touchstart", function(event) {
            var selection = window.getSelection();
            selection.removeAllRanges();

            clientX = event.touches[0].clientX;
            clientY = event.touches[0].clientY;

            range = document.caretRangeFromPoint(clientX, clientY);
            node = range.startContainer;
            offset = range.startOffset;

            document.body.contentEditable = "true";
            event.preventDefault();
        });
        document.body.addEventListener("touchmove", function(event) {
            var selection = window.getSelection(),
                range = document.caretRangeFromPoint(event.touches[0].clientX, event.touches[0].clientY),
                newRange = document.createRange();

            if(clientY < event.touches[0].clientY) {
                newRange.setStart(node, offset);
                newRange.setEnd(range.startContainer, range.startOffset);
            }
            else {
                newRange.setStart(range.startContainer, range.startOffset);
                newRange.setEnd(node, offset);
            }

            selection.removeAllRanges();
            selection.addRange(newRange);

            event.preventDefault();
        });
        document.body.addEventListener("touchend", function(event) {
            document.body.contentEditable = "false";
            event.preventDefault();
        });
    });
})();
</script>
<body>
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam tempus volutpat mauris sed porta. Phasellus euismod malesuada eleifend. Donec mattis, orci quis scelerisque mattis, turpis sem pulvinar nisi, et sagittis nunc nisi sed nulla. Pellentesque pharetra consequat neque, ultrices mattis mauris auctor id. Aenean tincidunt turpis non odio gravida semper. Praesent feugiat, lorem at lacinia tristique, orci eros tincidunt leo, at adipiscing sapien felis at tellus. Phasellus ac est nec nibh posuere euismod vel vitae neque. Vestibulum mollis adipiscing urna ut tristique. Vivamus purus tortor, venenatis id aliquam nec, elementum et lacus. Praesent elementum purus eget sapien ornare laoreet. Vestibulum ac odio enim.
</body>
</head>
</html>

【讨论】:

  • 我将此 html 加载到 UIWebView 并且单击文本时没有任何反应。我错过了什么吗?
  • 按住(不要移动手指)然后拖动,如果您第一次在 Mobile Safari 中尝试,您可以看到标题 - 当它显示“true”时您可以开始拖动。
  • 很抱歉,它根本不起作用。我试图在“touchmove”事件监听器的末尾添加一个警报,即使显示了警报,也没有选择任何文本。
  • 警报会撤消选择,不是吗..?改用 console.log
  • 正如我所说,放大镜会把事情搞砸。我更新了答案并将preventDefault 添加到touchstart 以用于演示目的。现在就试试。真的,你不想要那个 preventDefault。您可能还想减少计时器的超时时间。
【解决方案2】:

只是一个想法:确保你没有在你的 css 中使用这样的东西:

* {
  -webkit-touch-callout: none;
   -webkit-user-select: none;
   user-select: none;
}

这会阻止任何文本选择。

【讨论】:

  • 感谢您的提示,但您可以看到我在问题中写道,该文本实际上已被选中,但我没有看到标记和它周围的蓝色突出显示。
【解决方案3】:

我遇到了这个:

hitElem.style.backgroundColor = "highlight";
hitElem.style.color = "highlighttext";

或者, THIS SITE 编写了一些可怕的脚本,但它可以帮助你:) 它适用于范围。

【讨论】:

  • 我真的很感谢没有 cmets 的投票... -_- 不是。
猜你喜欢
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-07
  • 2013-02-05
相关资源
最近更新 更多