如何使用JavaScript在前节点/块中选择文本?

时间:2011-11-05 10:20:03

标签: javascript user-interface

我理解不允许JS将任意文本复制到剪贴板的安全原因,但是有一种方法可以通过单击按钮来选择预先节点中的文本,类似于select()函数在输入中的工作方式?

我不是在寻找复制到剪贴板的jQuery插件。我只想在pre block中进行文本突出显示,以便用户可以ctrl-c进行复制。

我似乎找到了蹲下。

6 个答案:

答案 0 :(得分:6)

这就是你需要的:

var clip = function(el) {
  var range = document.createRange();
  range.selectNodeContents(el);
  var sel = window.getSelection();
  sel.removeAllRanges();
  sel.addRange(range);
};

和html:

<pre onclick="clip(this);" id="copy_paste"></pre>

或者,如果您想以编程方式执行此操作:

clip(document.getElementById("copy_paste"));

或者在jquery中:

clip($("#copy_paste")[0]);

您不能将jquery元素clip()作为参数el传递。它将给出“TypeError:Range.selectNodeContents的参数1没有实现接口节点。”

答案 1 :(得分:4)

这不是太难。 IE和IE需要单独的分支。 9和所有其他浏览器。这是一个选择元素内容的函数:

现场演示:http://jsfiddle.net/yQa2w/

代码:

function selectElementContents(el) {
    if (window.getSelection && document.createRange) {
        // IE 9 and non-IE
        var range = document.createRange();
        range.selectNodeContents(el);
        var sel = window.getSelection();
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (document.body.createTextRange) {
        // IE < 9
        var textRange = document.body.createTextRange();
        textRange.moveToElementText(el);
        textRange.select();
    }
}

答案 2 :(得分:2)

当用户点击它时,您可以将pre标记更改为textarea标记:

jsFiddle:http://jsfiddle.net/WzBQf/

<button id="btnSelect">Select!</button>
<button id="btnDeselect">Deselect!</button>
<hr />
<div id="text">
    <pre id="txt1">Test</pre>
    <textarea id="txt2" readonly="readonly"></textare>
</div>

JavaScript(jQuery)代码:

$("#txt1, #btnSelect").click(function() {
    Select();
});


function Select() {
    $("#txt2").val($("#txt1").html()).show();
    $("#txt1").hide();

    $("#txt2").focus()[0].select();
}

function Deselect() {
    $("#txt1").html($("#txt2").val()).show();
    $("#txt2").hide();
}
$("#txt2").blur(function() {
    Deselect();
});

$("#btnDeselect").click(function() {
    Deselect();
});

答案 3 :(得分:1)

看看

https://developer.mozilla.org/it/DOM/window.getSelection

它与所有市长浏览器不兼容,首先是IE实现版本9

但是在较旧的IE中,document.selection中有一些替代API,看起来相当于

http://msdn.microsoft.com/en-us/library/ms535869%28v=vs.85%29.aspx

祝你好运!

答案 4 :(得分:0)

据我所知,您无法选择<input><textarea>以外的文字。顺便问一下,你为什么需要那个?

答案 5 :(得分:0)

好的 - 这就是我根据jsFiddle的建议做的事情并且它有效。唯一的问题是我没有Windows,在IE中,我确实将它复制到剪贴板,显然断行已经坏了,但这不是这个问题(我怀疑.replace()可以解决它 - 我只需要访问用IE播放的窗口):

function lineBreakCount(str){
// http://snippets.dzone.com/posts/show/5770
/* counts \n */
try {
    return((str.match(/[^\n]*\n[^\n]*/gi).length));
    } catch(e) {
    return 0;
    }
}

function nodeToCopy($node) {
// For Code Snippets - [AW]
$pre = $node.find('pre:first');
var string = $pre.text();
if (window.clipboardData && clipboardData.setData) {
    clipboardData.setData('text', string);
    } else {
    var n = 1 + lineBreakCount(string);
    $pre.attr('class','nodisplay');
    $pre.after('<textarea readonly="readonly" rows="' + n + '" class="dbg-copycode">' + string.replace(/</g,'&lt;').replace(/>/,'&gt;') + '</textarea>');
    $node.find('textarea:first').focus();
    $node.find('textarea:first').select();
    $node.find('div:last').find('button').replaceWith('<button class="dbg-copycode" type="button" title="Restore syntax highlight">Restore</button>');
    $node.find('div:last').find('button').click(function() {restorePreFromText($(this).parent().parent())});
    }
}

function restorePreFromText($node) {
// For Code Snippets - [AW]
$node.find('pre:first').removeAttr('class');
$node.find('textarea').remove();
$node.find('div:last').find('button').replaceWith('<button class="dbg-copycode" type="button" title="Select code example for copying">Select Code</button>');
$node.find('div:last').find('button').click(function() {nodeToCopy($(this).parent().parent())});
}

$(document).ready(function() {
// For Code Snippets - [AW]
var copybutton = 'Select Code';
var copytitle  = 'Select code example for copying';
if (window.clipboardData && clipboardData.setData) {
    copybutton = 'Copy Code';
    copytitle  = 'Copy code example to clipboard';
    }
$('pre[data-code]').after('<div class="dbg-rbutton"><button class="dbg-copycode" type="button" title="' + copytitle + '">' + copybutton + '</button></div>');
$('.dbg-copycode').click(function() {nodeToCopy($(this).parent().parent())});
});

我没有使用.hide()隐藏pre块的原因是因为.hide()添加了一个在服务器使用的Mozilla CSP策略下被禁止的style属性,所以我必须设置一个class属性代替。