【问题标题】:Use jQuery to auto select text inside a span tag when clicked单击时使用 jQuery 自动选择 span 标签内的文本
【发布时间】:2013-12-09 08:15:50
【问题描述】:

我有一个 div,其中包含一系列 span 标签,每个标签都包含一串文本。我想将一个 jQuery click 事件附加到所有跨度,以便当单击任何跨度内的文本时,将自动选择整行文本(dom > innerText 对象)以方便拖放或复制/粘贴文本字符串。

比如我的内容是……

<div id="mySpans">
  <span>&nbsp;This is my text&nbsp;</span>
  <span>&nbsp;This is my text&nbsp;</span>
</div>

如果光标单击跨度内的任何文本,我想选择该跨度内的文本,以便可以将其拖放(没有跨度标签,只是跨度的 innerText)作为副本。

jQuery 是否有一个简单的方法来做到这一点?

编辑:对我要完成的工作的更详细说明:

如果没有脚本的帮助,为了复制一个文本块,用户必须手动拖动选择一个选择矩形穿过文本块。然后文本被选中,表示单击和拖动事件将拾取所有选定的文本。因此,我正在尝试创建允许单击文本以自动为用户选择文本的脚本,这样他们就不必自己手动操作了。

【问题讨论】:

  • 我认为,出于安全原因,不允许操纵用户的选择。那将是非常邪恶的。这就像如果有人说“嗨”,你会让他说“我想要披萨”,接受它作为披萨的订单并让他付钱......
  • @Justin 也许是这样,但在这种情况下,我只是让用户更容易选择一个文本块。该脚本只是被用作允许点击事件(他们发起)完成选择(许多用户发现很难做到)的快捷方式。
  • @Justus,是的,但无论如何你都会在服务器端这样做,让客户端看到你搞砸了他的订单将是 '邪恶的规模(和“愚蠢”规模的高端)... =b
  • 可以简单地三次单击以自动选择一个跨度的全部内容,并且三次单击拖动会导致选择多个跨度内容;)

标签: jquery


【解决方案1】:

没错。简短的回答是:你不能

然而,这并不是很有帮助。因此,如果您准备接受一种略显老套的方法,但至少有一个警告,您可以:

给定html:

<div id="wrap">
    <span class="copyText">This is some text to copy.</span>
    <span>Can't copy <em>this</em> (automatically...)!</span>
    <span class="copyText">And this is yet more text.</span>
</div>

还有 CSS:

span.copyText {
    position: relative;
    display: block;
}
textarea {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    border: 0 none transparent;
    margin: 0;
    padding: 0;
    outline: none;
    resize: none;
    overflow: hidden;
    font-family: inherit;
    font-size: 1em;
}

您可以使用以下 jQuery:

$(document).ready(
    function() {
        $('.copyText').click(
            function() {
                if ($('#tmp').length) {
                    $('#tmp').remove();
                }
                var clickText = $(this).text();
                $('<textarea id="tmp" />')
                    .appendTo($(this))
                    .val(clickText)
                    .focus()
                    .select();
        return false;
    });
$(':not(.copyText)').click(
    function(){
        $('#tmp').remove();
    });

});

带有必要的JS Fiddle demo, at: http://jsfiddle.net/davidThomas/ZmYBh/

主要需要注意的是,您要复制的元素不能(至少使用这种方法)从一行换行到下一行(除非它也是display: block ),我怀疑这与原生 form 元素如何呈现为“实心”矩形有关,这与大多数其他 inline 元素不同,例如 html 会形成一个更...“流体”(?)矩形时包装)。

不过,可能还有其他人。

JS Fiddle demo to show that it does work with wrapping text, so long as the parent container element (span) is still display: block;.


编辑:补充说我尝试使用inputs 而不是textarea,可以预见的是,它的工作方式与textarea&lt;span contenteditable&gt; 没有任何不同/更好,它(再次,可以预见)根本没有选择文本,而是在文本的开头插入了插入符号。

叹息。我认为这个问题应该有一个更简单的答案,但我一辈子都看不到它。

【讨论】:

  • 谢谢大卫。感谢您的回答。
  • 不客气,我知道这不是你想要的,但我希望它对你有所帮助,至少...... =/
  • 来自 jquery doc ( .select() ) : This event is limited to &lt;input type="text"&gt; fields and &lt;textarea&gt; boxes
【解决方案2】:

使用 DOM 范围:http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html

var span = ...
var range = document.createRange();
range.setStartBefore(span.firstChild);
range.setEndAfter(span.lastChild);
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);

【讨论】:

    【解决方案3】:

    找到了这个运行良好且无 hack 的 core-javascript 解决方案: http://coderzone.org/library/Select-text-in-a-DIV-SPAN-or-table-cell_1047.htm

    我冒昧地对代码进行了一些更改,以便它接受元素节点作为参数而不是元素 ID。

    // Selects text inside an element node.
    function selectElementText(el) {
        removeTextSelections();
        if (document.selection) {
            var range = document.body.createTextRange();
            range.moveToElementText(el);
            range.select();
        }
        else if (window.getSelection) {
            var range = document.createRange();
            range.selectNode(el);
            window.getSelection().addRange(range);
        }
    }
    
    // Deselects all text in the page.
    function removeTextSelections() {
        if (document.selection) document.selection.empty(); 
        else if (window.getSelection) window.getSelection().removeAllRanges();
    }
    

    【讨论】:

      【解决方案4】:

      tbleckert 在正确的轨道上。 .select() 事件仅可用于输入,因此您需要让您的&lt;span&gt; 成为输入,然后设置无背景、无边框和无焦点环的样式。然后,您可以这样做:

      <input type="text" style="border:none; background:transparent; outline: none;" class="selectOnClick" />
      

      然后你的 jQuery 看起来像这样

      $('input.selectOnClick').click(function(){ $(this).select(); });
      

      这是未经测试的代码,但应该为您指明正确的方向。

      【讨论】:

      • 由于此代码驻留在 WordPress 编辑器中的插件中,并包含在父表单标签中,因此在保存或发布帖子时,输入元素的外观是否会改变帖子事件?在这种情况下,我不想在提交中添加噪音。
      • 外观无关紧要,该字段仍应可编辑等等。
      • 我不希望这些字段是可编辑的。它们是只读的,仅用于复制/粘贴或拖放到内容中。 jQuery 是否有在元素的 innerText 上进行文本选择的方法?这就是我在这里寻找的。​​span>
      • 我不相信 jQuery 有这种方法。但是,您可以禁用输入或将它们设为只读(取决于您的需要)并实现相同的目标。
      • 话虽如此,这里的this post 也是为了解决问题。不过我还没有测试过。
      【解决方案5】:

      我想做类似的事情。我的网站上有一些我希望用户能够轻松复制的引用。我还想将作者的名字添加到字符串中。

      通常,我将用户选择设置为无,因此我创建了一个在需要时以编程方式应用的类...

      .editable {
          user-select: text;
          -webkit-user-select: text;
          -moz-user-select: text;
          -ms-user-select: text;
          -o-user-select: text;
      }
      

      所有的引号都在一个名为“paragraph_quote”的类中。当网站访问者点击报价时,会发生以下顺序:

      $(".paragraph_quote").on("click", function() {
          var addendum = " [by Author]";
      
          if (! $(this).attr("contenteditable") || $(this).html().indexOf(addendum) === -1) {     
                  $(this).removeData("quote")
                  .data("quote", $(this).html())
                  .html($(this).html() + addendum)
                  .attr("contenteditable", true)
                  .addClass("editable")
                  .focus()
              ;
          }
          document.execCommand('selectAll', false, null);
      }).on("blur", function() {
          $(this).removeClass("editable").html($(this).data("quote"));
      });
      
      1. 查看是否已执行以下步骤(即,用户是否在同一段落内再次单击)。如果是第一次,请执行步骤 2 到 7。如果不是,请执行步骤 8。

      2. 如果不是第一次点击该引用,则删除可能已存储的所有数据。

      3. 将引用的 HTML 存储为数据。这允许您修改副本的 HTML(如果您愿意),然后轻松将其恢复到原始状态。

      4. 向 HTML 添加任何其他文本(例如作者姓名)。未在下面显示:我还使用 .replace() 删除任何特殊的 HTML 字符,如不间断空格、破折号等。

      5. 使段落可编辑。

      6. 添加可编辑类。

      7. 将焦点设置到段落。可编辑类确保焦点轮廓的外观。

      8. 选择可编辑段落的全部内容。这并不是说这一步很有用,即使已经采取了其他步骤,因为如果用户在选择中单击,它会导致整个选择重新突出显示。

      9. 当用户在段落外点击时,移除可编辑类并...

      10. 将 HTML 恢复到之前的状态(如果您按照上面的第 4 步进行了修改)。

      【讨论】:

        【解决方案6】:

        检查select() 事件:)

        【讨论】:

        • 好吧,那时我刚来这里,就像两年前一样……让我休息一下:P 我完全同意你的看法
        【解决方案7】:
        $("span").click(function(){
        var mytext  = $(this).text()
        })
        

        会将文本放入 javascript 变量中...但查看 jQuery Ui 可能会更快,特别是 draggable

        【讨论】:

        • 我认为他只是希望突出显示文本,以便可以通过上下文菜单复制文本。我不确定他是否希望将其分配给 JavaScript 变量。
        • @David:是的,通过上下文菜单复制或拖放到内容中。如果选择了文本,它通常会自动拖动。由于目标是 WordPress 内容编辑器,因此拖放区已经为拖放做好了准备。
        • @David:我认为你最了解我想要做什么。有什么建议吗?
        • @Scott B,我理解这个问题,我只是找不到任何通过 jQuery/JavaScript 自动选择(非input/textarea)文本的方法。
        • @Scott B,请参阅我的答案(在页面的其他位置)以获得我能想到的最佳答案。
        【解决方案8】:

        试试类似的东西

        $('#mySpans span').hover(function() {
            $(this).addClass('spanhover');
        }, function() {
            $(this).removeClass('spanhover');
        });
        

        在其中动态添加您在 CSS 部分中定义的类“spanhover”,例如

        #mySpans.spanhover {background-color:yellow;}
        

        【讨论】:

        • 我认为他希望它可以作为上下文菜单(或其他任何内容)的文本选择用于复制到剪贴板;我不认为他在尝试设计风格。
        • @David:但他写道“......文本将......突出显示......”。正如@NimChimpsky 指出的那样,问题的隐藏的第二部分可以使用“可拖动”的 ui 代码来完成。
        • 大卫是正确的。就我而言,用词不当。在这种情况下,我的意思是选择,而不是样式。
        猜你喜欢
        • 2016-07-13
        • 2019-02-06
        • 1970-01-01
        • 1970-01-01
        • 2015-10-18
        • 2014-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多