programing

요소에서 텍스트 선택(마우스로 강조 표시)

luckcodes 2022. 11. 27. 20:00

요소에서 텍스트 선택(마우스로 강조 표시)

사용자가 링크를 클릭하면 다른 요소(입력 아님)에서 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();
}

내가 뻔히 알 수 있는 걸 놓치고 있는 건가요?

플레인 자바스크립트

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

    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(원래 답변)

는 이 스레드에서 에 대한 해결책을 찾았다.주어진 정보를 수정하고 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);

스레드(데드링크)는 매우 훌륭한 것을 포함하고 있습니다.그러나 "보안 오류"로 인해 FF 3.5b99 + FireBug를 사용하여 이 페이지에서 제대로 수행할 수 없습니다.

Yeepee!! 이 코드를 사용하여 오른쪽 사이드바 전체를 선택할 수 있었습니다.

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

PS: - 다음과 같은 jquery selector에서 반환된 객체를 사용할 수 없었습니다.

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

   r.selectNodeContents(w);

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 버전에서는 동작할 수 있을지 어떨지 잘 모르겠습니다(정말로 신경 쓰지 않습니다).

다음 기능을 사용하여 요소의 내용을 선택할 수 있습니다.

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();

저도 같은 것을 찾고 있었습니다.제 해결책은 다음과 같습니다.

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

나는 몇 가지를 제외하고는 르페의 대답이 마음에 들었다.

  1. 브라우저 스니핑, jQuery 또는 no는 최적의 상태가 아닙니다.
  2. 마른
  3. obj의 부모가 createTextRange를 지원하지 않는 경우 IE8에서 작동하지 않습니다.
  4. setBaseAndExtent를 사용하는 Chrome의 기능을 활용해야 합니다(IMO).
  5. 여러 DOM 요소("선택된" 요소 내의 요소)에 걸쳐 있는 텍스트를 선택하지 않습니다.즉, 여러 스판 요소를 포함하는 div에서 selText를 호출하면 각 요소의 텍스트는 선택되지 않습니다.그건 나한테는 거래 위반이었어, YMMV.

여기 제가 생각해낸 것이 있습니다. 영감을 얻기 위해 레페의 대답에 고개를 끄덕였습니다.나는 이것이 아마도 좀 거칠기 때문에 비웃음을 받을 것이라고 확신한다(그리고 사실은 더 그럴 수도 있지만 나는 딴 데로 돌린다.다만, 브라우저의 스니핑을 회피할 수 있기 때문에, 그것이 포인트입니다.

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;
}

바로 그겁니다.가독성이나 편리성을 목적으로 하는 것도 있습니다.Opera, Safari, Chrome, Firefox 및 IE의 최신 버전에서 Mac에서 테스트되었습니다.IE8에서도 테스트 완료.또한 나는 일반적으로 코드 블록 내에서 필요한 경우에만 변수를 선언하지만 jslint는 모든 변수를 위로 선언할 것을 제안했습니다.OK 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);
};

Selection 개체(Gecko 엔진)와 TextRange 개체(Trident 엔진)를 살펴봅니다.크로스 브라우저를 지원하는 JavaScript 프레임워크에 대해서는 알 수 없습니다만, 아직 찾아본 적이 없기 때문에 jQuery도 가지고 있을 가능성이 있습니다.

lepe - 그건 나한테 아주 잘 먹혀. 고마워!코드를 플러그인 파일에 넣고 각 문장과 함께 사용하면 여러 개의 프리태그와 여러 개의 "Select all" 링크를 한 페이지에 표시할 수 있습니다. 그러면 올바른 프리태그가 선택되어 강조 표시됩니다.

<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;               
                    });
        });
  });

Tim의 방법은 다음 문장을 대체한 후 IE와 FF 모두에 대해 div 내의 텍스트를 선택하는 등 내 경우에 완벽하게 작동합니다.

range.moveToElementText(text);

다음을 포함합니다.

range.moveToElementText(el);

div의 텍스트는 다음 jQuery 함수로 클릭하여 선택합니다.

$(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();

특히 편집 가능한 범위 요소 내에서 텍스트 범위를 선택하는 것이 사용 사례였는데, 이 항목에서는 이에 대해 설명하지 않았습니다.

주요 차이점은 유형의 노드를 통과해야 한다는 것입니다.Text에게Range오브젝트(Range 매뉴얼에 기재되어 있습니다).set Start():

startNode가 Text, Comment 또는 CDATAStection 유형의 노드인 경우 startOffset은 startNode 시작 문자 수입니다.다른 노드 유형의 경우 startOffset은 startNode 시작 사이의 자식 노드 수입니다.

Textnode는 span 요소의 첫 번째 자노드입니다.따라서 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.get Selection()

추가된jQuery.browser.webkitChrome의 "else if"로 이동합니다.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():

일치하는 각 요소의 선택 이벤트를 트리거합니다.그러면 선택한 이벤트에 바인딩된 모든 함수가 실행되고 일치하는 요소에서 브라우저의 기본 선택 액션이 호출됩니다.

왜 jQuery가 그 이유를 설명하겠습니다.select()이 경우 작동하지 않습니다.

언급URL : https://stackoverflow.com/questions/985272/selecting-text-in-an-element-akin-to-highlighting-with-your-mouse