【问题标题】:create URL with anchor to text selection创建带有锚点到文本选择的 URL
【发布时间】:2015-03-13 23:41:25
【问题描述】:

我想创建一个指向我编写的 Web 服务的 URL,http://mycoolthing.com,以及一个引用该页面上文本选择的#-anchor。

是否可以在 HTML/JS 中创建引用选择或 RangeObject 的锚点?

【问题讨论】:

  • 不太清楚您所说的文本选择是什么意思。您是指在一大段文本中间的一个词或句子吗?
  • 如果是一些特定的文本,你可以将它包装在span 中并为其分配一个id,然后浏览器会将页面滚动到具有# 中指定的id 的元素(尽管它不会选择任何内容,但您可以使用stackoverflow.com/questions/985272/… 的解决方案来选择文本)

标签: javascript html text anchor selection


【解决方案1】:

看看 https://developer.mozilla.org/en-US/docs/Web/API/document.execCommand

创建链接

仅在存在选择时从选择中创建锚链接。这需要将 HREF URI 字符串作为 价值论据。 URI 必须至少包含一个字符, 这可能是一个空白。 (Internet Explorer 将创建一个链接 一个空 URI 值。)

喜欢

document.execCommand('createLink', false, 'http://google.com');

【讨论】:

  • 引自网站:“当 HTML 文档切换到设计模式时,[...]”。这不是我想要的。
【解决方案2】:

根据这个网站,您可以使用 javascript 来查找页面中的一些文本。

http://www.javascripter.net/faq/searchin.htm

也许您可以创建一个指向该站点的链接并使用 GET 或 POST 包含文本选择,以便在加载其他页面时,您可以使用 javascript 和上一页的信息转到文本选择。

第一页是这样的:

window.location.href="url?text=textToFind"

在另一个页面中:

$(function () {
window.find(window.location.search)
});

【讨论】:

  • 我要标记的文本可能会在页面上出现多次,所以我怀疑实际搜索是否真的是我想要的。
  • 文本有什么特定的特征吗?也许您可以结合搜索并验证所在的dom元素。根据这个问题是可以的:stackoverflow.com/questions/1335252/…
【解决方案3】:

您可以使用

获取选定(突出显示)的文本
var txt = window.getSelection().toString();

然后使用该值构建锚

href="abc.html#' + txt;

【讨论】:

    【解决方案4】:

    正如我在评论中提到的,这是一个使用 JavaScript 和 url 上的哈希 (#) 来选择文本的选项。

    分为两部分:

    1. 调用页面将有一个指向目标页面的链接(它们可以相同),并带有一个 # 表示您要选择的文本(或者如果您知道,则为元素的 ID):

      <a href="myPage.html#Lorem">Link to my page with Lorem select</a>

    2. 目标页面将包含一些 JavaScript 代码,这些代码将选择 # 中指示的文本(如果哈希是有效的元素 ID,它将选择该元素中的文本而不是文本)。

    *请注意,对于这个解决方案,我使用了来自 Selecting text in an element (akin to highlighting with your mouse) 的一些代码(Kimtho6 的解决方案)

    /**
     * SelectText: function from https://stackoverflow.com/questions/985272/selecting-text-in-an-element-akin-to-highlighting-with-your-mouse (Kimtho6 solution)
     * 
     * element: string that contains an element id (without the #)
     */
    function SelectText(element) {
        var doc = document;
        var text = doc.getElementById(element);    
        if (doc.body.createTextRange) { // ms
            var range = doc.body.createTextRange();
            range.moveToElementText(text);
            range.select();
        } else if (window.getSelection) {
            var selection = window.getSelection();
            var range = doc.createRange();
            range.selectNodeContents(text);
            selection.removeAllRanges();
            selection.addRange(range);
    
        }
    }
    
    /**
     * selectHashText: function that selects the first appearance of a text (or an element with the id) indicated in the location hash
     */
    function selectHashText() {
    
        // check if there's an element with that ID
        if ($(document.location.hash).length == 0) {
    
            // select some text in the page
            var textToSelect = document.location.hash.substring(1);
    
            // if it's not an empty hash
            if (textToSelect != "") {
    
                // iterate the different elements in the body
                $("body *").each(function() {
    
                    // if one contains the desired text
                    if ($(this).text().indexOf(textToSelect) >= 0) {
    
                        // wrap the text in a span with a specific ID
                        $(this).html(
                            $(this).html().replace(textToSelect, "<span id='mySelect'>" + textToSelect + "</span>")
                        );
    
                        // select the text in the specific ID and stop iteration
                        SelectText("mySelect");
                    }
                });
            }
    
        } else {
            // select the content of the id in the page
            SelectText(document.location.hash.substring(1));
        }
    }
    
    // execute the text selection on page load and every time the hash changes
    $(window).on("hashchange", selectHashText);
    $(document).ready(function() { selectHashText(); });
    

    我创建了这个jsfiddle,但它不带#,所以它没有多大帮助。你也可以see it on this web page。请注意,这与 jsfiddle(及更高版本)中的代码相同,只是在一页上。


    更新:(从下面的 cmets 详细阐述)

    不使用哈希,您可以在 GET 或 POST 中将要选择的文本作为参数传递(为简单起见,我将使用 GET):

    <a href="myPage?select=Lorem">Select Lorem</a>
    

    然后使用您的后端语言(我使用 PHP,您可以使用任何其他甚至 JavaScript 解析位置 href),将文本保存到我之前使用的 textToSelect 变量中。最后一步,将.text() 替换为我使用的.html()(因此标签也包含在搜索中)

    /**
     * gup: function from https://stackoverflow.com/questions/979975/how-to-get-the-value-from-the-url-parameter (Haim Evgi's solution)
     * 
     * name: string that contains the name of the parameter to return
     */
    function gup( name ) {
        name = name.replace(/[\[]/,"\\\[").replace(/[\]]/,"\\\]");
        var regexS = "[\\?&]"+name+"=([^&#]*)";
        var regex = new RegExp( regexS );
        var results = regex.exec( window.location.href );
        return results == null ? null : results[1];
    }
    
    /**
     * selectHashText: function that selects the first appearance of a text (or an element with the id) indicated in the "select" parameter
     */
    function selectTextAcross() {
    
        // get the "select" parameter from the URL
        var textToSelect = decodeURIComponent(gup("select"));
    
        // if it's not an empty hash
        if (textToSelect != "") {
    
            // iterate the different elements in the body
            $("body *").each(function() {
    
                // if one contains the desired text
                if ($(this).html().indexOf(textToSelect) >= 0) {
    
                    // wrap the text in a span with a specific ID
                    $(this).html(
                        $(this).html().replace(textToSelect, "<span id='mySelect'>" + textToSelect + "</span>")
                    );
    
                    // select the text in the specific ID and stop iteration
                    SelectText("mySelect");
                }
            });
        } 
    }
    
    $(document).ready(function() { selectTextAcross(); });
    

    你可以see it working on this web page

    关于这个解决方案:

    • 它有效(嘿!总比没有好!:P)
    • 你可以包含h​​tml标签(你不能用#一)
    • 您需要知道文档的来源
    • 生成的代码可能无效,然后结果可能不是预期的(我测试的所有浏览器,它们在第一个“交叉”标记后停止选择)

    【讨论】:

    • 干得好,谢谢!您是否认为可以通过在锚点中不包含文字文本,但您在上面创建的范围/选择对象来使选择在整个页面中唯一?
    • 只是想确保我理解您想要的:在 ID 中指定一个范围?例如,如果我有&lt;div id='myId'&gt;This is a test&lt;/div&gt;,并且您只想选择“测试”,那么您将传递 10,4 类型的范围(文本的开头和大小)。那是对的吗?像#myId&amp;range=10,4 这样的东西?还是只是范围?
    • 不幸的是,我不得不假设选择跨越多个divs,例如abc &lt;div id='myId'&gt;This is a test&lt;/div&gt; 123,我想要选择abc This。起初我认为 JS SelectionObject 是我想要的,直到我注意到它明确包含所选文本,这使得该对象通常不适合包含在 URL 中(因为 URL 只能是 1024 个字符长)。
    • hmmm... 我可以更改解决方案,使其忽略标签。问题是它可以很好地用于嵌套标签 (&lt;div&gt;....Text &lt;div&gt;you want&lt;/div&gt; to select....&lt;/div&gt;),但它可能会在标签之间产生问题 (&lt;div&gt;....Text you want&lt;/div&gt;&lt;div&gt;to select....&lt;/div&gt;)。例如,在您提到的代码中,生成的代码可能包含无效 HTML 的“交叉嵌套”(&lt;div&gt;&lt;span&gt;&lt;/div&gt;&lt;div&gt;&lt;/span&gt;&lt;/div&gt;,我不知道英文名称)标签,并且行为将取决于浏览器解释
    • 我添加了一个允许遍历 HTML 标签的解决方案,但请注意它在遍历 HTML 标签时如何中断,生成无效的 HTML(可能可以通过不同的方式解析文档)
    【解决方案5】:

    【讨论】:

    • +1 用于此用例的文本片段 URL。 Google 为原生不支持此 API 的浏览器提供了polyfill。您可以在article 中阅读有关此功能的更多详细信息。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-06
    • 2014-01-12
    • 1970-01-01
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多