【问题标题】:Cross-browser javascript to get and replace exact HTML from a user's selection?跨浏览器 javascript 从用户的选择中获取和替换确切的 HTML?
【发布时间】:2012-04-10 20:41:24
【问题描述】:

我正在寻找一种使用 javascript 或 JQuery 从用户选择的范围中获取、修改和替换 HTML 的方法。基本上,假设用户在一些 HTML 标记中选择了一个范围(| 描绘了选择):

<p>This is an <b>example |of</b> some text| to be selected</p>

我将如何获得:

of</b> some text

然后,在运行一些代码来修改该文本之后:

of some</b> altered text

如何将其重新插入,以便最终版本显示为:

<p>This is an <b>example of some</b> altered text to be selected</p>

我无法解决这两个问题,找到范围的确切 html,或将特定修改后的 HTML 写入范围。

【问题讨论】:

  • 您是否正在尝试将更改后的文本重新插入到原来的文档中?
  • 是的,没错。更改后的文本将返回到同一个文档中,替换选定的文本。
  • 修改后的文本从哪里来替换选中的文本?
  • 我只是修改代码中的文本,例如:function () { var html = getSelectionHTML(); html = 转换HTML(html);替换HTML(html);我需要弄清楚 getSelectionHTML() 和 replaceHTML() 函数是如何工作的。
  • 计划在 HTML 上执行什么样的转换?

标签: javascript jquery selection range


【解决方案1】:

这是我的开始:

jsFiddle

它将选择的文本替换为输入的值。

但它没有考虑到 html。

对此有什么想法吗?

$('#content').on('mouseup',function() {

    var t = false;

    if (window.getSelection) {
        t = window.getSelection();
    } else if (document.getSelection) {
        t = document.getSelection();
    } else if (document.selection) {
        t = document.selection.createRange().text;
    }

    if (t && (t+'').length > 0) {

       $('#content').html($('#content').html().replace(t,$('input').val()))

        alert("You replaced:\n" + t + "\nwith:\n" + $('input').val());
    }

});​

【讨论】:

    【解决方案2】:

    我偏离了您的文本选择想法,并做了一个基于鼠标悬停和突出显示的解决方案。不是您的确切要求,但它实现了您的基本目标。有很大的改进空间。

    示例:jsFiddle

    JS

    var $txtArea = $('textarea'); 
    
    function Rebind(){
        $('#editable *').off('mouseover.editor').on('mouseover.editor',function() {
            $(this).addClass('highlight');
            return false; 
        }).off('mouseout.editor').on('mouseout.editor',function() {
            $(this).removeClass('highlight');
            return false; 
        }).off('click.editor').on('click.editor',function() {
            var $sel = $('.highlight'); 
            $txtArea.val($sel.html()).data('selected', $sel);
        });
    }
    Rebind();
    $('input').click(function(){
        $txtArea.data('selected').html($txtArea.val()); 
        Rebind();
    }); 
    ​
    

    注意:无论出于何种原因,jQuery's on 没有选择新元素,所以我需要在编辑后重新绑定它们。

    HTML

    <div id='editable'>
        <div>
            This is <br /> some <b>content</b>
            <div>testing</div>
            <div> 
                some <i>more content</i>
                <div>eidt me</div>
            </div>
        </div>
    </div>
    
    <textarea ></textarea>
    <input type="button" value="save" /> ​
    

    CSS

    textarea{
     height:150px;
     width:100%;    
    }
    
    .highlight
    {
        border:1px solid blue !important;
    }
    

    【讨论】:

      【解决方案3】:

      我认为实现这一目标的一种方法是:

      1. 获取包含整个DOM的最高元素 选择
      2. 解析其 innerHTML 以供选择(请不要使用正则表达式)
      3. 显示匹配并记住它的位置和用于插入编辑版本的元素

      虽然我的第 3 步可能无法实际更改布局。希望应该有更简单的解决方案。

      【讨论】:

      • 是的,我也在想同样的事情,只要记住它的位置并将其插入回去
      • 这适用于大多数情况,除非选择的文本在父 DOM 元素中出现多次。在这种情况下,我如何判断需要替换哪个实例?
      • @BrandonBoone 我听说 RegEx 很糟糕,我讨厌自己去碰它。不幸的是,到目前为止,我所读到的只是人们在讨论为什么不使用它,但没有关于如何在 JS 中正确使用它的实际教程。 (我承认我也没有积极搜索过,幸运的是我很少需要这些东西)。欢迎提出建议:-)
      • @Armatus 我也同意,我听说不要使用它,但从未听说过任何替代品
      【解决方案4】:

      这是我的看法,就像 iambriansreed 的版本一样,它不考虑 HTML,正如您将在示例中看到的那样:

      jsFiddle

      这是重要的代码:

      var s = window.getSelection();
      var ss = s.toString();
      var node = $(s.getRangeAt(0).startContainer).parent();
      var contents = node.text();
      var idx = contents.indexOf( ss );
      node.html( contents.substr( 0, idx ) + 
          "HELLO" + 
          contents.substr( idx+ss.length ) );
      

      【讨论】:

      • 这个跨浏览器友好吗?
      • 这只是一个概念验证和正确方向的开始。我确定它不是跨浏览器友好的。
      猜你喜欢
      • 1970-01-01
      • 2010-10-19
      • 2010-09-18
      • 1970-01-01
      • 2013-01-13
      • 1970-01-01
      • 1970-01-01
      • 2013-09-14
      • 1970-01-01
      相关资源
      最近更新 更多