Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/html/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在选择之前、内部和之后获取HTML(不在textarea中)?_Javascript_Html_Rangy - Fatal编程技术网

Javascript 如何在选择之前、内部和之后获取HTML(不在textarea中)?

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 我最近的

以下是我试图实现的目标:当用户使用鼠标、键盘或触摸来选择“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>