以下是我要完成的任务:当用户使用鼠标,键盘或触摸选择“myDiv”中的文本时,我想获取三个谨慎的HTML块:选择之前的HTML(到“左边”) “它的”,选择中的HTML,以及选择后的HTML(到它的“右边”)。 html应该与myDiv.innerHTML一样。
选择可能在标记对内开始或结束(即,隔离的选择不一定是有效的HTML)。我不需要处理选择中绝对定位元素之类的特殊场景;我所关注的所有选择都将被限制为一个包含基本标签的div,例如strong,em,ul,ol,h1,image和table。
我最接近的是使用rangy来阻止选择并调用selection.getRangeAt(0).cloneContents()
来获取选择HTML。这种方法效果很好,直到我选择隔离无效,浏览器改变文档片段的HTML以使其成为有效标记。
额外信息:以下是我需要的原因:
我正在创建一个文档反馈系统,因此我需要将选择信息保存到数据库中以便以后检索和重构。通常我会使用DOM路径和所选文本保存选择,但文本可能会在保存和重建之间发生变化。例如,作者可能会移动整个段落,删除部分等。然后,DOM路径变得毫无用处。
所以我的(不完美)计划是将选择存储为[offset,length,html_snippet]。那就是“位置”。我还将存储直接在所选文本之前和之后出现的html片段。这是“背景”。
使用这些数据的组合,我应该能够在大多数时间重新定位最初选择的文本,即使它已移动或部分更改。当失败时,UI将有办法解决它,但我希望尽可能少发生。
Superthanks!
答案 0 :(得分:1)
我有几个问题:
1.-当你说'选择后的html'时 - 那个html与选择之前的html有什么不同,反之亦然?由于你的“脚本”或其他什么,“选择”过程本身是否篡改了html?
2.-你说文字选择不是在textareas中发生的......那你使用的是什么元素?段落? div的...?缩小范围会有所帮助。
3.-你有没有想过使用jquery?
做类似
的事情$('#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
});
复制选择:
如上所述:
Selecting text in an element (akin to highlighting with your mouse)
杰森写了以下函数:
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/
您可以使用它来获取所选文本。你只需要相应地调整它,因为他从一个反向角度接近它。 您可以提供给我们的详细信息......我们可以提供更好的帮助。
希望这会有所帮助
ģ
答案 1 :(得分:0)
此代码从用户的选择中获取html / text,但它仅适用于IE。该代码也适用于交叉标记选择。 (Globals用于保持代码简短。)
<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
之外的任何其他元素,则必须使其无法选择。