单击时使用 jQuery 自动选择跨度标签内的文本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4165010/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Use jQuery to auto select text inside a span tag when clicked
提问by Scott B
I have a div which contains a series of span tags, each containing a string of text. I'd like to attach a jQuery click event to all of the spans so that when the text inside any span is clicked, the entire line of text (dom > innerText object) will be auto selected to facilitate the drag/drop or copy/paste of the text string.
我有一个包含一系列 span 标签的 div,每个标签都包含一串文本。我想将 jQuery 单击事件附加到所有跨度,以便在单击任何跨度内的文本时,将自动选择整行文本(dom > innerText 对象)以方便拖放或复制/粘贴文本字符串。
For example, my content is...
例如,我的内容是...
<div id="mySpans">
<span> This is my text </span>
<span> This is my text </span>
</div>
If the cursor is clicked on any text inside a span, I want to select the text within that span, so that it can be drag/dropped (without the span tags, just the innerText of the span) as a copy.
如果光标在跨度内的任何文本上单击,我想选择该跨度内的文本,以便可以将其拖/放(没有跨度标签,只是跨度的innerText)作为副本。
Does jQuery have an easy means to do this?
jQuery 是否有一种简单的方法来做到这一点?
EDIT: A more detailed explanation of what I'm trying to accomplish:
编辑:对我要完成的工作的更详细解释:
Without aid of script, in order to copy a block of text, the user has to manually drag select a selection rectangle across the text block. The text then becomes selected signaling that a click & drag event will pick up all of the selected text. So I'm trying to create script that allows a single click on the text to automatically select the text for the user so they don't have to manually do it themselves.
在没有脚本帮助的情况下,为了复制文本块,用户必须在文本块上手动拖动选择一个选择矩形。然后文本变为选中状态,表示单击和拖动事件将选取所有选定的文本。因此,我正在尝试创建允许单击文本以自动为用户选择文本的脚本,这样他们就不必自己手动完成。
回答by David says reinstate Monica
Right. The short answer is: you can't.
对。简短的回答是:你不能。
That, however, isn't really very helpful. So, if you're prepared to accept a slightly hacky approach, with at least one caveat, you can:
然而,这并不是很有帮助。因此,如果您准备接受一种稍微有点hacky 的方法,至少有一个警告,您可以:
Given the html:
鉴于 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>
And the CSS:
和 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;
}
You can use the following jQuery:
您可以使用以下 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();
});
});
With the requisite JS Fiddle demo, at: http://jsfiddle.net/davidThomas/ZmYBh/.
使用必需的JS Fiddle 演示,请访问:http://jsfiddle.net/davidThomas/ZmYBh/。
The main caveat is that the element you want to copy cannot(with this approach at least) wrap from one line to the next (unlessit's also display: block
), I suspect it has something to do with how native form
elements are rendered as 'solid' rectangles, unlike most other inline
elements, such as html which form a more...'fluid'(?) rectangle when wrapping).
主要的警告是您要复制的元素不能(至少用这种方法)从一行到下一行(除非它也是display: block
),我怀疑这与原生form
元素如何呈现为“实心”矩形有关,与大多数其他inline
元素不同,例如 html,它们在包装时形成一个更多......'流体'(?)矩形)。
There may be others, however.
然而,可能还有其他人。
JS Fiddle 演示表明它确实适用于换行文本,只要父容器元素 ( span
) 仍然是display: block;
.
Edited:编辑:补充一点,我尝试使用
input
input
!而非textarea
textarea
其中,可以预见,没有工作的任何不同/好过textarea
textarea
,而且<span contenteditable>
<span contenteditable>
,这(再次,可以预见)没有选择的所有文字,但没有插入插入符号开头的文本。Sigh. I think there should be a far easier answer to this question, but I can't see it for the life of me.
叹。我认为这个问题应该有一个更简单的答案,但我一生都看不到它。
回答by Evan
use DOM ranges: http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html
使用 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);
回答by Phillippe Santana
Found this core-javascript solution that works well and is hack-free: http://coderzone.org/library/Select-text-in-a-DIV-SPAN-or-table-cell_1047.htm
发现这个运行良好且无黑客的核心javascript解决方案:http: //coderzone.org/library/Select-text-in-a-DIV-SPAN-or-table-cell_1047.htm
I took the liberty to change the code a bit so that it accepts the element node as argument instead of an element id.
我冒昧地稍微更改了代码,以便它接受元素节点作为参数而不是元素 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();
}
回答by Alan M.
I wanted to do something similar. My website has quotes that I wanted users to be able to easily copy. I also wanted to add the author's name to the string.
我想做类似的事情。我的网站上有我希望用户能够轻松复制的报价。我还想将作者的姓名添加到字符串中。
Normally, I have user-select set to none, so I created a class that is programmatically applied when needed...
通常,我将用户选择设置为无,所以我创建了一个在需要时以编程方式应用的类......
.editable {
user-select: text;
-webkit-user-select: text;
-moz-user-select: text;
-ms-user-select: text;
-o-user-select: text;
}
All of the quotes are in a class called "paragraph_quote". When a site visitor clicks on a quote, the follow sequence occurs:
所有引号都在一个名为“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"));
});
Look to see if the following steps have already been executed (i.e., whether the user is clicking for a second time inside the same paragraph). If it's the first time, execute steps 2 through 7. If not, just step 8.
Remove any data that might have been stored if this isn't the first time that quote was clicked.
Store the quote's HTML as data. This allow you to modify the HTML for the copy (if you would like) and then easily return it to its original state.
Add any additional text (e.g., the author's name) to the HTML. Not shown below: I also use .replace() to remove any special HTML characters like non-breaking spaces, em-dashes, etc.
Make the paragraph editable.
Add the editable class.
Set the focus to the paragraph. The editable class ensures the appearance of the focus outline.
Select the entire content of the editable paragraph. Not that this step is useful, even if the other steps have already been taken, because it causes the entire selection to be re-highlighted if the user clicks within the selection.
When the user clicks outside of the paragraph, remove the editable class and...
Restore the HTML to its previous state (if you modified as indicated in step 4, above).
查看是否已经执行了以下步骤(即,用户是否在同一段落内第二次单击)。如果是第一次,请执行第 2 步到第 7 步。如果不是,请执行第 8 步。
如果这不是第一次单击报价,则删除可能已存储的任何数据。
将报价的 HTML 存储为数据。这允许您修改副本的 HTML(如果您愿意),然后轻松地将其返回到其原始状态。
向 HTML 添加任何附加文本(例如,作者姓名)。下面未显示:我还使用 .replace() 删除任何特殊的 HTML 字符,如不间断空格、长划线等。
使段落可编辑。
添加可编辑类。
将焦点设置在段落上。可编辑类确保焦点轮廓的外观。
选择可编辑段落的全部内容。并不是说这一步是有用的,即使已经采取了其他步骤,因为如果用户在选择内单击,它会导致整个选择重新突出显示。
当用户在段落外单击时,删除可编辑类并...
将 HTML 恢复到以前的状态(如果您按照上面第 4 步中的指示进行了修改)。
回答by jxpx777
tbleckert is on the right track. The .select() event is only available for inputs though, so you'd need to have your <span>
become an input and then style it with no background, no border, and no focus ring. Then, you can do this:
tbleckert 走在正确的轨道上。.select() 事件仅适用于输入,因此您需要让您<span>
成为输入,然后设置无背景、无边框和无聚焦环的样式。然后,你可以这样做:
<input type="text" style="border:none; background:transparent; outline: none;" class="selectOnClick" />
and then your jQuery would look something like this
然后你的jQuery看起来像这样
$('input.selectOnClick').click(function(){ $(this).select(); });
This is untested code but should point you in the right direction.
这是未经测试的代码,但应该为您指明正确的方向。
回答by NimChimpsky
回答by initall
Try something like
尝试类似的东西
$('#mySpans span').hover(function() {
$(this).addClass('spanhover');
}, function() {
$(this).removeClass('spanhover');
});
where you dynamically add a class "spanhover" you defined in your CSS section like
在其中动态添加在 CSS 部分中定义的类“spanhover”,例如
#mySpans.spanhover {background-color:yellow;}