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

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


답변

범위가 창 및 문서와 다르기 때문에 iframe 내부의 요소에는 Jason의 코드를 사용할 수 없습니다. 그 문제를 해결하고 다른 jQuery 플러그인 (체인 가능)으로 사용하기 위해 수정했습니다.

예제 1 : 클릭 한 번으로 <code> 태그 내의 모든 텍스트 선택 및 “선택”클래스 추가 :

$(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를 사용하여이 페이지에서 바로 수행 할 수 없습니다.

이피 !! 이 코드로 전체 오른쪽 사이드 바를 선택할 수있었습니다.

    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.welovestackoverflow",$("div.sidebar"));

   //this throws **security exception**

   r.selectNodeContents(w);


답변

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

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


답변

나는 몇 가지를 제외하고 lepe의 대답을 좋아했습니다.

  1. 브라우저 스니핑, jQuery 또는 최적이 아님
  2. 마른
  3. obj의 부모가 createTextRange를 지원하지 않으면 IE8에서 작동하지 않습니다.
  4. setBaseAndExtent 를 사용하는 Chrome의 기능을 활용해야합니다 (IMO)
  5. 여러 DOM 요소 ( “selected”요소 내의 요소)에서 텍스트를 선택하지 않습니다. 즉 , 여러 범위 요소를 포함하는 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;
}

그게 다야. 당신이 보는 것 중 일부는 가독성 및 / 또는 편의를위한 것입니다. 최신 버전의 Opera, Safari, Chrome, Firefox 및 IE에서 Mac에서 테스트되었습니다. IE8에서도 테스트되었습니다. 또한 일반적으로 내부 / 코드 블록이 필요할 때만 변수를 선언하지만 jslint는 변수가 모두 최상위로 선언되도록 제안했습니다. 좋아 jslint.

편집
이것을 op의 코드에 묶는 방법을 포함시키는 것을 잊었습니다.

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

건배