[Javascript] 요소에서 텍스트 선택 (마우스로 강조 표시와 유사)


Answers

다음은 브라우저 스니핑이없고 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);
Question

사용자가 링크를 클릭하게하고 다른 요소 (입력이 아닌) 의 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();
}

나는 뻔뻔스럽게 명백한 것을 놓치고 있습니까?




나는 몇 가지 점을 제외하고는 lepe의 대답을 좋아했다 :

  1. 브라우저 스니핑, jQuery 또는 no가 최적이 아닙니다.
  2. 마른
  3. obj의 부모가 createTextRange를 지원하지 않으면 IE8에서 작동하지 않습니다.
  4. setBaseAndExtent 를 사용하는 Chrome의 기능을 활용해야합니다 (IMO).
  5. 여러 DOM 요소 ( '선택한'요소 내의 요소)에 걸친 텍스트는 선택하지 않습니다. 즉, 여러 span 요소가 포함 된 div에서 selText 를 호출하면 각 요소의 텍스트가 선택 되지 않습니다 . 그것은 나를위한 딜 브레이커였습니다, YMMV.

여기에 영감을 얻으려는 lepe의 답변에 대한 고개와 함께 나는 생각해 냈습니다. 나는 이것이 아마 약간 무거운 것 (그리고 실제로 moreso 일 수 있었지만 나는 빗나간 다.)으로서 나는 내가 조롱받을 것이다라고 확신한다. 그러나 그것은 작동하고 브라우저 스니핑을 피할 수 있습니다.

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.

편집 이 코드를 op 코드에 묶는 방법을 포함하는 것을 잊어 버렸습니다.

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

건배




다음은 문자열의 형태로 선택한 텍스트를 가져 오는 또 다른 간단한 솔루션입니다.이 문자열을 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();



Selection 객체 (Gecko 엔진)와 TextRange 객체 (Trident 엔진)를 살펴보십시오.이 구현을 위해 크로스 브라우저를 지원하는 JavaScript 프레임 워크에 대해서는 잘 모릅니다. 그러나이 중 하나도 찾지 않았습니다. jQuery에서도 가능합니다.




thread 는 정말 멋진 것들을 포함하고 있습니다. 하지만 "보안 오류"로 인해 FF 3.5b99 + FireBug를 사용하여이 페이지에서 바로 수행 할 수 없습니다.

Yipee !! 이 코드로 전체 오른쪽 사이드 바를 선택할 수 있었기 때문에 도움이 되길 바랍니다.

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

추신 : - jquery 선택기에 의해 반환 된 개체를 사용할 수 없습니다.

   var w=$("div.welove",$("div.sidebar"));

   //this throws **security exception**

   r.selectNodeContents(w);



Chrome 용 "else if"에 jQuery.browser.webkit 을 추가 jQuery.browser.webkit . Chrome에서이 작업을 수행하지 못했습니다. 23.

이 스크립트는 class="code" 태그가있는 <pre> 태그에서 내용을 선택하기위한 것입니다.

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



필자가 볼 수있는 한, 편집 가능한 스팬 요소 내부의 텍스트 범위를 선택하는 경우를 예로 들었습니다.

주요 차이점은 Range.setStart () 문서에 설명 대로 Range 객체에 Text 유형의 노드를 전달해야한다는 것입니다.

startNode가 Text, Comment 또는 CDATASection 유형의 노드이면 startOffset은 startNode의 시작부터의 문자 수입니다. 다른 노드 유형의 경우 startOffset은 startNode의 시작 사이에있는 자식 노드의 수입니다.

Text 노드는 span 요소의 첫 번째 자식 노드이므로 get을 얻으려면 span 요소의 childNodes[0] 에 액세스하십시오. 나머지는 대부분의 다른 답변과 같습니다.

다음은 코드 예제입니다.

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

기타 관련 문서 :
Range
Selection
Document.createRange()
Window.getSelection()




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




Links