Javascript 如何在选择之前、内部和之后获取HTML(不在textarea中)?
以下是我试图实现的目标:当用户使用鼠标、键盘或触摸来选择“myDiv”中的文本时,我希望获得三个谨慎的HTML块:选择前的HTML(在“左侧”),选择内的HTML,以及选择后的HTML(在“右侧”)。html应该与myDiv.innerHTML一样 选择可能在标记对内开始或结束(即,独立的选择不一定是有效的HTML)。我不需要处理特殊的场景,比如选择中的绝对定位元素;我关心的所有选择都将被限制为一个div,其中包含基本标记,如strong、em、ul、ol、h1、image和table 我最近的一次尝试是使用来拦截选择并调用Javascript 如何在选择之前、内部和之后获取HTML(不在textarea中)?,javascript,html,rangy,Javascript,Html,Rangy,以下是我试图实现的目标:当用户使用鼠标、键盘或触摸来选择“myDiv”中的文本时,我希望获得三个谨慎的HTML块:选择前的HTML(在“左侧”),选择内的HTML,以及选择后的HTML(在“右侧”)。html应该与myDiv.innerHTML一样 选择可能在标记对内开始或结束(即,独立的选择不一定是有效的HTML)。我不需要处理特殊的场景,比如选择中的绝对定位元素;我关心的所有选择都将被限制为一个div,其中包含基本标记,如strong、em、ul、ol、h1、image和table 我最近的
selection.getRangeAt(0).cloneContents()
来获取选择HTML。这已经足够好了,直到我做了一个单独无效的选择,并且浏览器改变了文档片段的HTML,使其成为有效的标记
额外信息:以下是我需要此功能的原因:
我正在创建一个文档反馈系统,因此我需要将选择信息保存到数据库中,以便以后检索和重建。通常,我会使用DOM路径和所选文本保存所选内容,但文本可能会在保存和重建之间发生变化。例如,作者可能会移动整个段落,删除部分,等等。然后DOM路径变得非常无用
因此,我的(不完美的)计划是将选择存储为[offset,length,html\u snippet]。这就是“位置”。我还将存储直接出现在所选文本之前和之后的html片段。这就是“背景”
使用这些数据的组合,我应该能够在大多数时间重新定位最初选择的文本,即使它已经移动或部分更改。当这失败时,UI将有办法解决它,但我希望这种情况尽可能少地发生
非常感谢 我有几个问题: 1.-当你说“选择后的html”-该html与选择前的html或反之如何不同?“选择”过程本身是否因为您的“脚本”或其他原因而篡改html 2.-你说文本选择不是在文本区域进行的…那么你在使用什么元素?段落?分区。。。?缩小范围会有所帮助 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
});
副本选择:
如本文所述:
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);
}
}
可在此处找到现场工作演示:
这里有一个jquery插件版本:
您可以使用它来获取所选文本。你只需要相应地调整它,因为他是从相反的角度接近它的。
你能给我们的细节越多…我们就越能帮上忙
希望这有帮助
G此代码从用户的选择中获取html/文本,但它仅在IE中工作。该代码也适用于交叉标记选择。(Globals用于保持代码简短。)
所选函数(){
thediv=document.getElementById('div');
res=document.getElementById('htm');
userSelection=document.selection;
userRange=userSelection.createRange();
/*用于更大范围的元素*/
//rangeParent=userRange.parentElement();
//if(rangeParent!=thediv)userRange.moveToElementText(rangeParent);
rangeText=userRange.htmlText;//或:rangeText=userRange.text;
res.innerText=范围文本;
返回;
}
伟大的测试页面
有文字的段落
此段落包含一个子元素
这是最后一段
单元格1-1单元格1-2
单元格2-1单元格2-2
项目1
项目2
项目3
thediv
中选择前后的内容如下:prepost=thediv.innerHTML/innerText.split(rangeText)代码>
如果该页面包含除DIV之外的任何其他元素,则必须将其设置为不可选择。是的,我试图提供尽可能多的信息,但我的内容过于冗长,令人讨厌。刚才我把它削了一点。:)需要澄清的是:您需要的HTML片段是否与发送到浏览器的HTML源中显示的内容完全相同?@TimDown所有这些都发生在一个div中。对于该div,我需要发送到浏览器的确切HTML,或者使用myDiv.innerHTML获得的浏览器规范化HTML。只要不插入新标签,我可以使用任何一种。我对实现这一点不抱希望。解析HTML字符串需要糟糕的代码。你能不能在HTML中添加隐藏标记来表示选择边界?IE only对我来说不可行,但无论如何还是要感谢你的努力。:)@在你“删减”你原来的帖子之前(有人提到)。无论如何,代码中包含了某些想法,这些想法也可能被其他浏览器“翻译”。这个答案甚至不是为了完美解决你的问题。你有一个非常有趣且具有挑战性的任务,祝你好运…在我的原始帖子中,它说如果在IE中不起作用也没关系。:)我所寻求的可能甚至不可能,但我会试试口香糖。谢谢在回答你的第一个问题时:我所说的“以前”不是指“过去”,而是指“在……的左边”。想象一下,进行选择将my div的内容分为三个部分:选择左侧的html、选择内部的html和选择右侧的html。我需要为这些部分中的每一部分获取未修改的html。回答你的第二个问题:这都包含在一个div中,其中包含一些标记,如strong、em、image等……而jQuery无疑是我的首选,但不是必需的。
<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>