jQuery选择文本并在段落中添加span

6
我有一个函数可以获取选择的文本,这个文本是通过鼠标选择的,并将其添加到一个变量中。我想在所选文本中添加 `` 标签 - 在该段落中。
$("p").live("mouseup",function() {
    selection = getSelectedText();
    if(selection.length >= 3) {
        var $spn = $("<span></span>").html(selection).addClass("selected");
        $("p").wrap($spn);
    }
});

//Grab selected text
function getSelectedText(){
    if(window.getSelection){
        return window.getSelection().toString();
    }
    else if(document.getSelection){
        return document.getSelection();
    }
    else if(document.selection){
        return document.selection.createRange().text;
    }
}

我可以获取文本选择变量,但是我的函数没有将<span></span>放在段落<p>中选定的文本周围,而是将其包装在外部。
我该如何将其替换在段落中呢? 谢谢。

3
您所要求的内容通常很难实现。您确定段落下面没有嵌套标签吗?如果有,那么在不破坏当前结构的情况下可能会非常困难。 - glmxndr
段落下面不应该有除新创建的span之外的任何其他标签。 - Mircea
5个回答

5
这就是问题所在:
var $spn = $("<span></span>").html(selection).addClass("selected");
$("p").wrap($spn);

这意味着您将span标签包裹在段落周围。 我认为您想做的是这样的:
var spn = '<span class="selected">' + selection + '</span>';
$(this).html($(this).html().replace(selection, spn));

1
$spn是jQuery,不是字符串。 - tvanfosson
我的文本被替换为[object Object],没有<span>。我的变量有问题吗? - Mircea
现在运行得更好了,我得到了: <span class="selected">selected</span>这个 span 没有正确解析,我得到的是 > 而不是 <>。 - Mircea
我正在尝试编码这个字符串,但是它不起作用: $(this).text($(this).html().replace(selection, spn).replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>')); - Mircea
2
明白了! $(this).html($(this).html().replace(selection, spn));我已将文本更改为HTML。感谢大家的支持! - Mircea
3
这段代码也存在一个错误。如果您有多个相同单词的出现,该代码将始终包装单词的第一次出现,而不是实际选择的文本。 - rebellion

1
尝试修剪选择并替换HTML内部换行符。这会有很大帮助:
$('#tweet_contents').live("mouseup",function() {
    selection = getSelectedText().replace(/^\s+|\s+$/g,"");

    if(selection.length >= 4) {
        var spn = '<span id=\"selected\" class=\"polarite\"  selcount=\"'+selcounter+'\" >'+selection+'<span id=\"superscript\">'+selcounter+'<\/span>'+'<\/span>';

    $(this).html( $(this).html().replace(/(\r\n|\n|\r)/gm," ").replace(selection, spn ) ); 
    }
});

1
使用 .wrapInner() 替代 .wrap()

0

未经测试,但应该可以工作:

$("p").live("mouseup",function() {
selection = getSelectedText();
if(selection.length >= 3) {
var $spn = $("<span></span>").html(selection).addClass("selected");
$(this).html($(this).html().replace(selection, $spn);
}
});

$spn是jQuery,不是字符串。 - tvanfosson
我使用以下代码: $(document).ready(function(){$("p").live("mouseup",function() { selection = getSelectedText(); if(selection.length >= 3) { var $spn = $("<span></span>").html(selection).addClass("selected"); $(this).html($(this).html().replace(selection, $spn)); } });似乎我丢失了变量,段落中的选择工作正常,但被替换为[object Object]文本 - 没有 span。 - Mircea
哦,我的错...我刚刚查看了替换部件,我以为其余的已经工作了。 - Daan

0

我认为你需要替换段落中的文本,而不是使用wrap。

$("p").live("mouseup",function() {
   selection = getSelectedText();
   if(selection.length >= 3) {
      var spn = "<span class='selected'>" + selection + "</span>");
      var html = $(this).html().replace(selection,spn);
      $(this).html(html);
    }
});

请注意,只有当段落仅包含文本而没有标记时,此方法才能可靠地工作。

如果我选择跨越多个标签的文本,这种方法就行不通了。如果p标签是这样的:<p>Some <i>text</i></p>,而我选择的是“ome tex”,那么您的方法将无法替换任何内容。 - glmxndr
@subtenante - 我知道 -- 我在答案的结尾已经注意到了,虽然如果选择算法被修改为查找匹配的DOM部分并选择整个HTML(而不是文本),它可能会起作用。对于仅包含文本的简单段落,它将起作用(一次)。 - tvanfosson
是的,我刚刚明确了为什么它不起作用的原因。 :) - glmxndr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接