9

这是我想要完成的事情:当用户使用鼠标、键盘或触摸来选择“myDiv”中的文本时,我想获取三个谨慎的 HTML 块:选择之前的 HTML(在它的“左侧” )、选择内部的 HTML 以及选择之后的 HTML(在它的“右侧”)。html 应该与 myDiv.innerHTML 中出现的一样。

选择可能在标记对内开始或结束(即,孤立的选择不一定是有效的 HTML)。我不需要处理选择中的绝对定位元素等特殊情况;我关心的所有选择都将被限制在一个 div 中,该 div 将包含基本标签,如 strong、em、ul、ol、h1、image 和 table。

我最接近的是使用rangy来获取选择并调用selection.getRangeAt(0).cloneContents()以获取选择 HTML。这工作得很好,直到我做出一个单独无效的选择,并且浏览器更改文档片段的 HTML 以使其成为有效标记。

额外信息:这就是我需要这个的原因:

我正在创建一个文档反馈系统,因此我需要将选择信息保存到数据库中以供以后检索和重构。通常我会使用 DOM 路径和选定的文本保存选择,但文本可能会在保存和重构之间发生变化。例如,作者可能会移动整个段落、删除部分等。这样 DOM 路径就变得毫无用处了。

所以我的(不完美的)计划是将选择存储为[偏移量,长度,html_snippet]。这就是“立场”。我还将存储直接出现在所选文本之前和之后的 html 片段。这就是“上下文”。

使用这些数据的组合,我应该能够在大多数情况下重新定位最初选择的文本,即使它已经移动或部分更改。当失败时,用户界面将有办法解决它,但我希望这种情况尽可能少地发生。

非常感谢!

4

2 回答 2

1

我有几个问题:

1.- 当您说“选择后的 html”时 - 该 html 与选择之前的 html 有何不同,反之亦然?由于您的“脚本”或其他原因,“选择”过程本身是否会篡改 html?

2.- 你说文本选择没有发生在 textareas 中......那么你正在使用哪些元素?段落?div...?缩小范围会有所帮助。

3.-你有没有想过使用jquery?

http://api.jquery.com/select/

做类似的事情

$('#element_with_text_goes_here').select(function() {

//apply grabbing functions here, for example

//copy html 'before' selection:
     $pre_html = $('html').clone();

   // copy selection...see below:

   // copy html 'after' selection'...same as before


});

复制选择:

如此处所述:

选择元素中的文本(类似于用鼠标突出显示)

Jason 编写了以下函数:

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) { // moz, opera, webkit
        var selection = window.getSelection();            
        var range = doc.createRange();
        range.selectNodeContents(text);
        selection.removeAllRanges();
        selection.addRange(range);
    }
}

可以在这里找到现场工作演示:http: //jsfiddle.net/edelman/KcX6A/339/

这里还有一个 jquery 插件版本:http: //jsfiddle.net/edelman/KcX6A/340/

您可以使用它来获取所选文本。你只需要相应地调整它,因为他是从一个相反的角度接近它。您可以向我们提供的详细信息越多……我们可以提供的帮助就越大。

希望这有助于
G

于 2012-03-03T04:23:06.097 回答
0

此代码从用户的选择中获取 html/text,但它仅适用于 IE。该代码也适用于跨标签选择。(用于保持代码简短的全局变量。)

<script>
function selected(){
    thediv=document.getElementById('div');
    res=document.getElementById('htm');
    userSelection=document.selection;
    userRange=userSelection.createRange();
    /* For wider scale of elements */
    // rangeParent=userRange.parentElement();
    // if(rangeParent!=thediv) userRange.moveToElementText(rangeParent);
    rangeText=userRange.htmlText;   // OR: rangeText=userRange.text;
    res.innerText=rangeText;    
    return; 
}    
</script>
</head>    
<body onload="document.onselectionchange=selected;">
<div id="div">
<h1>The great testpage</h1>
<p>A paragraph with some text</p>
<p>This paragraph <b>contains</b> a child element.</p>
<p>And this is the last paragraph.</p>
<table>
<tr><td>Cell1-1</td><td>cell1-2</td></tr>
<tr><td>Cell2-1</td><td>cell2-2</td></tr>
</table>
<ol>
<li>item1</li>
<li>item2</li>
<li>item3</li>
</ol>
</div>
<br>
<span id="htm"></span>
</body>

选择前后的内容thediv你会得到这样的:prepost=thediv.innerHTML/innerText.split(rangeText);

如果页面包含除 之外的任何其他元素thediv,则必须将它们设为不可选择。

于 2012-03-03T10:18:08.590 回答