복사 된 웹 텍스트에 추가 정보를 추가하는 방법


103

일부 웹 사이트는 이제 복사 된 콘텐츠에 텍스트를 추가 하는 Tynt 의 JavaScript 서비스를 사용합니다 .

이것을 사용하여 사이트에서 텍스트를 복사 한 다음 붙여 넣으면 텍스트 하단에 원본 콘텐츠에 대한 링크가 표시됩니다.

Tynt는 또한이를 추적합니다. 잘 된 깔끔한 트릭입니다.

이 작업을 수행하는 스크립트는 인상적입니다. 클립 보드 (이전 버전의 IE에서만 기본적으로 허용되고 항상 꺼져 있어야 함)를 조작하려고하기보다는 실제 선택을 조작합니다.

따라서 텍스트 블록을 선택하면 추가 콘텐츠가 <div>선택 항목에 포함 된 숨겨진 항목으로 추가됩니다 . 붙여 넣을 때 추가 스타일이 무시되고 추가 링크가 나타납니다.

이것은 실제로 간단한 텍스트 블록으로 수행하기 쉽지만 다른 브라우저에서 복잡한 HTML을 통해 가능한 모든 선택을 고려할 때 악몽입니다.

저는 웹 애플리케이션을 개발 중입니다. 누구도 복사 된 콘텐츠를 추적 할 수 없도록하고 추가 정보에 링크가 아닌 상황에 맞는 내용을 포함하고 싶습니다. 이 경우 Tynt의 서비스는 실제로 적절하지 않습니다.

유사한 기능을 제공하지만 내부 애플리케이션 데이터를 노출하지 않는 오픈 소스 JavaScript 라이브러리 (jQuery 플러그인 또는 유사)를 아는 사람이 있습니까?


1
stackoverflow.com/questions/6344588/… 에서 내 대답을 살펴보십시오 . 제안한 것과 매우 유사하게 수행됩니다
Niklas


48
이러지 마세요. 제발 제발 그냥하지 마십시오.
couchand

5
@couchand 왜 안돼? 스팸 사이트에서는 이것이 얼마나 성가신 일인지 알지만 이것은 인용에 사용할 수 있고 내부 데이터가 민감한 애플리케이션을위한 것입니다. 그것이 제가 Tynt를 사용하고 싶지 않은 이유입니다.
Keith

4
이 작업을 수행 하시겠습니까? 사용자로서 나는 그것을 싫어하고 나는 당신의 제품에이 분노를 포팅 할 것입니다 : 내 클립 보드를 만지지 마십시오!
aloisdg가

답변:


138

2020 업데이트

모든 최신 브라우저 에서 작동하는 솔루션입니다 .

document.addEventListener('copy', (event) => {
  const pagelink = `\n\nRead more at: ${document.location.href}`;
  event.clipboardData.setData('text', document.getSelection() + pagelink);
  event.preventDefault();
});
Lorem ipsum dolor sit amet, consectetur adipiscing elit.<br/>
<textarea name="textarea" rows="7" cols="50" placeholder="paste your copied text here"></textarea>


[이전 게시물-2020 년 업데이트 이전]

복사 된 웹 텍스트에 추가 정보를 추가하는 두 가지 주요 방법이 있습니다.

1. 선택 조작

아이디어는를 감시 copy event한 다음 추가 정보와 함께 숨겨진 컨테이너를에 추가 dom하고 선택을 확장하는 것입니다.
이 방법은 c.bavota의해이 기사 에서 채택 되었습니다 . 더 복잡한 경우 는 jitbit 의 버전 도 확인하십시오 .

  • 브라우저 호환성 : 모든 주요 브라우저, IE> 8.
  • 데모 : jsFiddle 데모 .
  • 자바 스크립트 코드 :

    function addLink() {
        //Get the selected text and append the extra info
        var selection = window.getSelection(),
            pagelink = '<br /><br /> Read more at: ' + document.location.href,
            copytext = selection + pagelink,
            newdiv = document.createElement('div');

        //hide the newly created container
        newdiv.style.position = 'absolute';
        newdiv.style.left = '-99999px';

        //insert the container, fill it with the extended text, and define the new selection
        document.body.appendChild(newdiv);
        newdiv.innerHTML = copytext;
        selection.selectAllChildren(newdiv);

        window.setTimeout(function () {
            document.body.removeChild(newdiv);
        }, 100);
    }

    document.addEventListener('copy', addLink);

2. 클립 보드 조작

아이디어는 copy event클립 보드 데이터 를보고 직접 수정하는 것입니다. 이것은 clipboardData속성을 사용하여 가능 합니다. 이 속성은의 모든 주요 브라우저에서 사용할 수 있습니다 read-only. 이 setData방법은 IE에서만 사용할 수 있습니다.

  • 브라우저 호환성 : IE> 4.
  • 데모 : jsFiddle 데모 .
  • 자바 스크립트 코드 :

    function addLink(event) {
        event.preventDefault();

        var pagelink = '\n\n Read more at: ' + document.location.href,
            copytext =  window.getSelection() + pagelink;

        if (window.clipboardData) {
            window.clipboardData.setData('Text', copytext);
        }
    }

    document.addEventListener('copy', addLink);

1
건배! 불행히도 IE에서 작동해야하지만 나쁜 시작은 아닙니다.
Keith

2
"<pre>"태그에 대한 해결 방법이 있어야합니다.이 스크립트의보다 원활한 버전은 여기에 있습니다
Alex

15
으로 변경하면 "클립 보드 조작"이 FireFox, Chrome 및 Safari에서 전적으로 작동 window.clipboardData합니다 event.clipboardData. IE (v11도)는 event.clipboardData jsfiddle.net/m56af0je/8을
mems

3
Google Analytics 등을 사용하는 경우 이벤트를 시작하여 사용자가 사이트에서 복사하는 내용을 기록 할 수도 있습니다. 재미있는
geedubb

2
첫 번째 옵션은 복사 된 텍스트의 새 줄 문자를 무시합니다.
soham

7

이것은 위의 수정 된 솔루션의 바닐라 자바 ​​스크립트 솔루션이지만 더 많은 브라우저를 지원합니다 (크로스 브라우저 방법).

function addLink(e) {
    e.preventDefault();
    var pagelink = '\nRead more: ' + document.location.href,
    copytext =  window.getSelection() + pagelink;
    clipdata = e.clipboardData || window.clipboardData;
    if (clipdata) {
        clipdata.setData('Text', copytext);
    }
}
document.addEventListener('copy', addLink);

3

내가 테스트하고 작동하는 jQuery의 가장 짧은 버전은 다음과 같습니다.

jQuery(document).on('copy', function(e)
{
  var sel = window.getSelection();
  var copyFooter = 
        "<br /><br /> Source: <a href='" + document.location.href + "'>" + document.location.href + "</a><br />© YourSite";
  var copyHolder = $('<div>', {html: sel+copyFooter, style: {position: 'absolute', left: '-99999px'}});
  $('body').append(copyHolder);
  sel.selectAllChildren( copyHolder[0] );
  window.setTimeout(function() {
      copyHolder.remove();
  },0);
});

실제로 결과를 클립 보드에 복사하는 코드는 어디에 있습니까?
vsync

@vsync 나는 이것이 복사가 일어나기 직전에 기능을 추가한다고 생각합니다 (사용자가 시작할 때 시스템에서 수행됨).
TerranRich

@vsync-TerraRich가 말했듯이 복사 된 텍스트에 추가 정보를 추가하는 질문에 응답하려고 했으므로 솔루션은이 부분 만 다룹니다.
user2276146

3

다음은 jquery의 플러그인입니다. https://github.com/niklasvh/jquery.plugin.clipboard 프로젝트 readme에서 "이 스크립트는 복사 이벤트가 호출되기 전에 선택 항목의 내용을 수정하여 복사 된 선택을 생성합니다. 사용자가 선택한 것과 다릅니다.

이를 통해 저작권 정보 또는 기타 콘텐츠와 같은 콘텐츠를 선택 항목에 추가 / 앞에 추가 할 수 있습니다.

MIT 라이센스에 따라 출시 "


1
매우 유망 해 보입니다. CSP에서 허용하지 않는 인라인 스타일을 사용하지만 잠재적으로 조정할 수 있습니다. 건배!
Keith

3

답을 개선하고 변경 후 선택을 복원하여 복사 후 무작위 선택을 방지합니다.

function addLink() {
    //Get the selected text and append the extra info
    var selection = window.getSelection(),
        pagelink = '<br /><br /> Read more at: ' + document.location.href,
        copytext = selection + pagelink,
        newdiv = document.createElement('div');
    var range = selection.getRangeAt(0); // edited according to @Vokiel's comment

    //hide the newly created container
    newdiv.style.position = 'absolute';
    newdiv.style.left = '-99999px';

    //insert the container, fill it with the extended text, and define the new selection
    document.body.appendChild(newdiv);
    newdiv.innerHTML = copytext;
    selection.selectAllChildren(newdiv);

    window.setTimeout(function () {
        document.body.removeChild(newdiv);
        selection.removeAllRanges();
        selection.addRange(range);
    }, 100);
}

document.addEventListener('copy', addLink);

가 있어야한다 @TsukimotoMitsumasavar range = selection.getRangeAt(0);
Vokiel

텍스트 선택을 복원하는 것은 좋은 생각입니다. 그렇지 않으면 기본 브라우저 동작이 중단됩니다.
Sergey

2

2018 년 개선

document.addEventListener('copy', function (e) {
    var selection = window.getSelection();
    e.clipboardData.setData('text/plain', $('<div/>').html(selection + "").text() + "\n\n" + 'Source: ' + document.location.href);
    e.clipboardData.setData('text/html', selection + '<br /><br />Source: <a href="' + document.location.href + '">' + document.title + '</a>');
    e.preventDefault();
});

1
복사-붙여 넣기를하면 서식 ( <a> , <img> , <b> 및 기타 태그) 이 손실됩니다 . 선택한 텍스트의 HTML 코드를 얻는 것이 좋습니다. 이 답변에서 getSelectionHtml () 함수를 사용하십시오 . [ stackoverflow.com/a/4177234/4177020] 이제이 문자열 var selection = window.getSelection();을 다음 문자열 로 바꿀 수 있습니다 .var selection = getSelectionHtml();
Dmitry Kulahin

0

또한 조금 더 짧은 솔루션 :

jQuery( document ).ready( function( $ )
    {
    function addLink()
    {
    var sel = window.getSelection();
    var pagelink = "<br /><br /> Source: <a href='" + document.location.href + "'>" + document.location.href + "</a><br />© text is here";
    var div = $( '<div>', {style: {position: 'absolute', left: '-99999px'}, html: sel + pagelink} );
    $( 'body' ).append( div );
    sel.selectAllChildren( div[0] );
    div.remove();
    }



document.oncopy = addLink;
} );

0

위의 2 가지 답변 + Microsoft Edge와의 호환성을 편집 한 것입니다.

또한 모든 브라우저에서 기본적으로 예상되는대로 마지막에 원래 선택의 복원을 추가했습니다.

function addCopyrightInfo() {
    //Get the selected text and append the extra info
    var selection, selectedNode, html;
    if (window.getSelection) {
        var selection = window.getSelection();
        if (selection.rangeCount) {
            selectedNode = selection.getRangeAt(0).startContainer.parentNode;
            var container = document.createElement("div");
            container.appendChild(selection.getRangeAt(0).cloneContents());
            html = container.innerHTML;
        }
    }
    else {
        console.debug("The text [selection] not found.")
        return;
    }

    // Save current selection to resore it back later.
    var range = selection.getRangeAt(0);

    if (!html)
        html = '' + selection;

    html += "<br/><br/><small><span>Source: </span><a target='_blank' title='" + document.title + "' href='" + document.location.href + "'>" + document.title + "</a></small><br/>";
    var newdiv = document.createElement('div');

    //hide the newly created container
    newdiv.style.position = 'absolute';
    newdiv.style.left = '-99999px';

    // Insert the container, fill it with the extended text, and define the new selection.
    selectedNode.appendChild(newdiv); // *For the Microsoft Edge browser so that the page wouldn't scroll to the bottom.

    newdiv.innerHTML = html;
    selection.selectAllChildren(newdiv);

    window.setTimeout(function () {
        selectedNode.removeChild(newdiv);
        selection.removeAllRanges();
        selection.addRange(range); // Restore original selection.
    }, 5); // Timeout is reduced to 10 msc for Microsoft Edge's sake so that it does not blink very noticeably.  
}

document.addEventListener('copy', addCopyrightInfo);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.