选择元素中的文本(类似于用鼠标突出显示)

2020/09/27 16:21 · javascript ·  · 0评论

我想让用户单击一个链接,然后它在另一个元素(而不是输入)中选择HTML文本

“选择”是指您将鼠标拖到文本上方来选择文本的方式。这一直是研究的负担,因为每个人都用其他术语谈论“选择”或“突出显示”。

这可能吗?到目前为止,我的代码:

HTML:

<a href="javascript:" onclick="SelectText('xhtml-code')">Select Code</a>
<code id="xhtml-code">Some Code here </code>

JS:

function SelectText(element) {
    $("#" + element).select();
}

我是否明显遗漏了一些东西?

纯Javascript

function selectText(node) {
    node = document.getElementById(node);

    if (document.body.createTextRange) {
        const range = document.body.createTextRange();
        range.moveToElementText(node);
        range.select();
    } else if (window.getSelection) {
        const selection = window.getSelection();
        const range = document.createRange();
        range.selectNodeContents(node);
        selection.removeAllRanges();
        selection.addRange(range);
    } else {
        console.warn("Could not select text in node: Unsupported browser.");
    }
}

const clickable = document.querySelector('.click-me');
clickable.addEventListener('click', () => selectText('target'));
<div id="target"><p>Some text goes here!</p><p>Moar text!</p></div>
<p class="click-me">Click me!</p>

这是一个工作示例对于那些正在寻找jQuery插件的人,我也做了其中之一


jQuery(原始答案)

我已经在此线程中找到了解决方案我能够修改给定的信息,并将其与jQuery混合使用,以创建一个功能强大的函数来选择任何元素中的文本,而与浏览器无关:

function SelectText(element) {
    var text = document.getElementById(element);
    if ($.browser.msie) {
        var range = document.body.createTextRange();
        range.moveToElementText(text);
        range.select();
    } else if ($.browser.mozilla || $.browser.opera) {
        var selection = window.getSelection();
        var range = document.createRange();
        range.selectNodeContents(text);
        selection.removeAllRanges();
        selection.addRange(range);
    } else if ($.browser.safari) {
        var selection = window.getSelection();
        selection.setBaseAndExtent(text, 0, text, 1);
    }
}

这是一个没有浏览器嗅探并且不依赖jQuery的版本:

function selectElementText(el, win) {
    win = win || window;
    var doc = win.document, sel, range;
    if (win.getSelection && doc.createRange) {
        sel = win.getSelection();
        range = doc.createRange();
        range.selectNodeContents(el);
        sel.removeAllRanges();
        sel.addRange(range);
    } else if (doc.body.createTextRange) {
        range = doc.body.createTextRange();
        range.moveToElementText(el);
        range.select();
    }
}

selectElementText(document.getElementById("someElement"));
selectElementText(elementInIframe, iframe.contentWindow);

Jason的代码不能用于iframe中的元素(因为范围不同于窗口和文档)。我修复了该问题,并对其进行了修改,以便用作其他任何jQuery插件(可链接):

示例1:只需单击一下,即可选择<code>标记内的所有文本,并添加“ selected”类:

$(function() {
    $("code").click(function() {
        $(this).selText().addClass("selected");
    });
});

示例2:单击按钮时,在iframe中选择一个元素:

$(function() {
    $("button").click(function() {
        $("iframe").contents().find("#selectme").selText();
    });
});

注意:请记住,iframe源应位于同一域中,以防止出现安全错误。

jQuery插件:

jQuery.fn.selText = function() {
    var obj = this[0];
    if ($.browser.msie) {
        var range = obj.offsetParent.createTextRange();
        range.moveToElementText(obj);
        range.select();
    } else if ($.browser.mozilla || $.browser.opera) {
        var selection = obj.ownerDocument.defaultView.getSelection();
        var range = obj.ownerDocument.createRange();
        range.selectNodeContents(obj);
        selection.removeAllRanges();
        selection.addRange(range);
    } else if ($.browser.safari) {
        var selection = obj.ownerDocument.defaultView.getSelection();
        selection.setBaseAndExtent(obj, 0, obj, 1);
    }
    return this;
}

我在IE8,Firefox,Opera,Safari,Chrome(当前版本)中对其进行了测试。我不确定它是否可以在较旧的IE版本中使用(因为我不在乎)。

这个线程(现在已经死了)包含非常棒的东西。但是由于“安全错误”,我无法使用FF 3.5b99 + FireBug在此页面上正确执行此操作。

pe!我可以使用此代码选择整个右侧边栏,希望它对您有所帮助:

    var r = document.createRange();
    var w=document.getElementById("sidebar");  
    r.selectNodeContents(w);  
    var sel=window.getSelection(); 
    sel.removeAllRanges(); 
    sel.addRange(r); 

PS:-我无法使用jquery选择器返回的对象,例如

   var w=$("div.welovestackoverflow",$("div.sidebar"));
   
   //this throws **security exception**

   r.selectNodeContents(w);

我在寻找相同的东西,我的解决方案是这样的:

$('#el-id').focus().select();

您可以使用以下功能选择任何元素的内容:

jQuery.fn.selectText = function(){
    this.find('input').each(function() {
        if($(this).prev().length == 0 || !$(this).prev().hasClass('p_copy')) { 
            $('<p class="p_copy" style="position: absolute; z-index: -1;"></p>').insertBefore($(this));
        }
        $(this).prev().html($(this).val());
    });
    var doc = document;
    var element = this[0];
    console.log(this, element);
    if (doc.body.createTextRange) {
        var range = document.body.createTextRange();
        range.moveToElementText(element);
        range.select();
    } else if (window.getSelection) {
        var selection = window.getSelection();        
        var range = document.createRange();
        range.selectNodeContents(element);
        selection.removeAllRanges();
        selection.addRange(range);
    }
};

该函数可以如下调用:

$('#selectme').selectText();

除了以下几点,我喜欢lepe的回答:

  1. 浏览器嗅探,jQuery或否不是最佳选择
  2. 干燥
  3. 如果obj的父级不支持createTextRange,则在IE8中不起作用
  4. 应该利用Chrome使用setBaseAndExtent的功能(IMO)
  5. 将不会选择跨多个DOM元素(“ selected”元素中的元素)的文本。换句话说,如果在包含多个span元素的div上调用selText,它将不会选择每个元素的文本。YMMV对我来说真是个大难题。

这就是我想出的,点头表示lepe寻求灵感。我敢肯定我会被嘲笑,因为这也许有点笨手笨脚(实际上可能会更多,但是我离题了)。但这有效并且避免了浏览器嗅探,这就是重点

selectText:function(){

    var range,
        selection,
        obj = this[0],
        type = {
            func:'function',
            obj:'object'
        },
        // Convenience
        is = function(type, o){
            return typeof o === type;
        };

    if(is(type.obj, obj.ownerDocument)
        && is(type.obj, obj.ownerDocument.defaultView)
        && is(type.func, obj.ownerDocument.defaultView.getSelection)){

        selection = obj.ownerDocument.defaultView.getSelection();

        if(is(type.func, selection.setBaseAndExtent)){
            // Chrome, Safari - nice and easy
            selection.setBaseAndExtent(obj, 0, obj, $(obj).contents().size());
        }
        else if(is(type.func, obj.ownerDocument.createRange)){

            range = obj.ownerDocument.createRange();

            if(is(type.func, range.selectNodeContents)
                && is(type.func, selection.removeAllRanges)
                && is(type.func, selection.addRange)){
                // Mozilla
                range.selectNodeContents(obj);
                selection.removeAllRanges();
                selection.addRange(range);
            }
        }
    }
    else if(is(type.obj, document.body) && is(type.obj, document.body.createTextRange)) {

        range = document.body.createTextRange();

        if(is(type.obj, range.moveToElementText) && is(type.obj, range.select)){
            // IE most likely
            range.moveToElementText(obj);
            range.select();
        }
    }

    // Chainable
    return this;
}

而已。您看到的一些内容是为了便于阅读和/或方便。在Mac上以Opera,Safari,Chrome,Firefox和IE的最新版本进行了测试。也在IE8中测试。另外,我通常仅在代码块内需要时/在变量时声明变量,但jslint建议将它们全部声明为最高变量。好的jslint。

编辑
我忘了包括如何将其绑定到操作码:

function SelectText(element) {
    $("#" + element).selectText();
}

干杯

适用于chrome的更新版本:

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) {
        var selection = window.getSelection();
        var range = doc.createRange();
        range.selectNodeContents(text);
        selection.removeAllRanges();
        selection.addRange(range);

    }
}

$(function() {
    $('p').click(function() {
        SelectText("selectme");

    });
});

http://jsfiddle.net/KcX6A/326/

对于任何标签,都可以通过此简短代码选择该标签内的所有文本。它将用黄色突出显示整个标签区域,并单击一下即可选择其中的文本。

document.onclick = function(event) {
    var range, selection;
event.target.style.backgroundColor = 'yellow';
        selection = window.getSelection();
        range = document.createRange();
        range.selectNodeContents(event.target);
        selection.removeAllRanges();
        selection.addRange(range);
};

lepe-很好,谢谢!我将您的代码放在插件文件中,然后将其与每个语句结合使用,这样您就可以在一个页面上具有多个前置标记和多个“全选”链接,并且可以选择正确的前置突出显示:

<script type="text/javascript" src="../js/jquery.selecttext.js"></script>
<script type="text/javascript">
  $(document).ready(function() { 
        $(".selectText").each(function(indx) {
                $(this).click(function() {                 
                    $('pre').eq(indx).selText().addClass("selected");
                        return false;               
                    });
        });
  });

看一下Selection对象(Gecko引擎)和TextRange对象(Trident引擎)。我不知道有实现此功能的跨浏览器支持的JavaScript框架,但是我也从没有寻找过,所以甚至jQuery都有可能。

Tim的方法非常适合我的情况-在替换以下语句后,为IE和FF选择div中的文本:

range.moveToElementText(text);

具有以下内容:

range.moveToElementText(el);

通过使用以下jQuery函数单击以选择div中的文本:

$(function () {
    $("#divFoo").click(function () {
        selectElementText(document.getElementById("divFoo"));
    })
});

这是另一个以字符串形式获取所选文本的简单解决方案,您可以轻松地使用此字符串将div元素子代添加到代码中:

var text = '';

if (window.getSelection) {
    text = window.getSelection();

} else if (document.getSelection) {
    text = document.getSelection();

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

text = text.toString();

我的特殊用例是在一个可编辑的span元素内选择一个文本范围,据我所知,此处的任何答案都未描述。

主要区别在于您必须将类型的节点传递TextRange对象,如Range.setStart()的文档中所述

如果startNode是Text,Comment或CDATASection类型的Node ,则startOffset是从startNode开始的字符数。对于其他节点类型,startOffset是startNode起始之间的子节点数。

Text节点是span元素的第一个子节点,因此要获取它,需要访问childNodes[0]span元素。其余与大多数其他答案相同。

这里是一个代码示例:

var startIndex = 1;
var endIndex = 5;
var element = document.getElementById("spanId");
var textNode = element.childNodes[0];

var range = document.createRange();
range.setStart(textNode, startIndex);
range.setEnd(textNode, endIndex);

var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);

其他相关文档:
范围
选择
Document.createRange()
Window.getSelection()

已添加jQuery.browser.webkit到Chrome的“否则”。无法在Chrome 23中正常运行。

在下面制作此脚本,以选择带有的<pre>标记中的内容class="code"

jQuery( document ).ready(function() {
    jQuery('pre.code').attr('title', 'Click to select all');
    jQuery( '#divFoo' ).click( function() {
        var refNode = jQuery( this )[0];
        if ( jQuery.browser.msie ) {
            var range = document.body.createTextRange();
            range.moveToElementText( refNode );
            range.select();
        } else if ( jQuery.browser.mozilla || jQuery.browser.opera  || jQuery.browser.webkit ) {
            var selection = refNode.ownerDocument.defaultView.getSelection();
            console.log(selection);
            var range = refNode.ownerDocument.createRange();
            range.selectNodeContents( refNode );
            selection.removeAllRanges();
            selection.addRange( range );
        } else if ( jQuery.browser.safari ) {
            var selection = refNode.ownerDocument.defaultView.getSelection();
            selection.setBaseAndExtent( refNode, 0, refNode, 1 );
        }
    } );
} );

根据jQuery文档select()

触发每个匹配元素的选择事件。这将导致已绑定到该select事件的所有功能都被执行,并在匹配的元素上调用浏览器的默认select动作。

有您的解释为什么jQuery select()在这种情况下不起作用。

本文地址:http://javascript.askforanswer.com/xuanzeyuansuzhongdewenbenleisiyuyongshubiaotuchuxianshi.html
文章标签: ,  
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!

文件下载

老薛主机终身7折优惠码boke112

上一篇:
下一篇:

评论已关闭!