Cách thêm thông tin bổ sung vào văn bản web đã sao chép


103

Một số trang web hiện sử dụng dịch vụ JavaScript từ Tynt để gắn văn bản vào nội dung được sao chép.

Nếu bạn sao chép văn bản từ một trang web bằng cách sử dụng này và sau đó dán, bạn sẽ nhận được một liên kết đến nội dung gốc ở cuối văn bản.

Tynt cũng theo dõi điều này khi nó xảy ra. Đó là một mẹo nhỏ được thực hiện tốt

Tập lệnh của họ để thực hiện điều này rất ấn tượng - thay vì cố gắng thao tác khay nhớ tạm (chỉ những phiên bản IE cũ mới cho phép họ làm theo mặc định và luôn phải tắt) họ thao tác lựa chọn thực tế.

Vì vậy, khi bạn chọn một khối văn bản, nội dung bổ sung sẽ được thêm vào dưới dạng ẩn <div>trong lựa chọn của bạn. Khi bạn dán kiểu phụ sẽ bị bỏ qua và liên kết phụ xuất hiện.

Điều này thực sự khá dễ thực hiện với các khối văn bản đơn giản, nhưng lại là một cơn ác mộng khi bạn xem xét tất cả các lựa chọn có thể có trên HTML phức tạp trong các trình duyệt khác nhau.

Tôi đang phát triển một ứng dụng web - tôi không muốn bất kỳ ai có thể theo dõi nội dung được sao chép và tôi muốn thông tin bổ sung chứa một cái gì đó theo ngữ cảnh, thay vì chỉ là một liên kết. Dịch vụ của Tynt không thực sự thích hợp trong trường hợp này.

Có ai biết về một thư viện JavaScript mã nguồn mở (có thể là một trình cắm thêm jQuery hoặc tương tự) cung cấp chức năng tương tự nhưng không làm lộ dữ liệu ứng dụng nội bộ không?


1
Hãy xem câu trả lời của tôi tại stackoverflow.com/questions/6344588/… . Nó được thực hiện rất tương tự như bạn đề nghị
Niklas


48
Xin đừng làm điều này. XIN VUI LÒNG XIN VUI LÒNG không.
couchand

5
@couchand tại sao không? Tôi cảm thấy điều này thật khó chịu trên các trang web spam, nhưng đây là ứng dụng có thể được sử dụng để trích dẫn và nơi dữ liệu nội bộ nhạy cảm. Đó là lý do tại sao tôi không muốn sử dụng Tynt.
Keith

4
Bạn có chắc chắn muốn làm điều này? Là một người dùng, tôi ghét điều đó và tôi sẽ chuyển sự tức giận này vào sản phẩm của bạn: Đừng chạm vào khay nhớ tạm của tôi!
aloisdg chuyển sang codidact.com

Câu trả lời:


138

Cập nhật năm 2020

Giải pháp hoạt động trên tất cả các trình duyệt gần đây .

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>


[Bài đăng cũ hơn - trước bản cập nhật năm 2020]

Có hai cách chính để thêm thông tin bổ sung vào văn bản web đã sao chép.

1. Thao tác lựa chọn

Ý tưởng là theo dõi copy event, sau đó thêm một vùng chứa ẩn với thông tin bổ sung của chúng tôi vào domvà mở rộng lựa chọn cho nó.
Phương pháp này được phỏng theo bài báo này của c.bavota . Cũng kiểm tra phiên bản của jitbit để biết trường hợp phức tạp hơn.

  • Khả năng tương thích của trình duyệt : Tất cả các trình duyệt chính, IE> 8.
  • Demo : jsFiddle demo .
  • Mã Javascript :

    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. Thao tác với khay nhớ tạm

Ý tưởng là xem copy eventvà sửa đổi trực tiếp dữ liệu khay nhớ tạm. Điều này có thể sử dụng clipboardDatatài sản. Lưu ý rằng thuộc tính này có sẵn trong tất cả các trình duyệt chính trong read-only; các setDataphương pháp chỉ có sẵn trên IE.

  • Tương thích trình duyệt : IE> 4.
  • Demo : jsFiddle demo .
  • Mã Javascript :

    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
Chúc mừng! Thật không may, chúng tôi cần nó hoạt động trong IE, nhưng đó không phải là một khởi đầu tồi.
Keith

2
Nên có một cách giải quyết cho "<pre>" thẻ, một phiên bản mượt mà của kịch bản này là ở đây
Alex

15
Lưu ý rằng "Thao tác với khay nhớ tạm" hoạt động hoàn toàn trong FireFox, Chrome và Safari nếu bạn chuyển window.clipboardDatasang event.clipboardData. IE (v11 nữa) không hỗ trợ event.clipboardData jsfiddle.net/m56af0je/8
mems

3
Nếu bạn đang sử dụng Google Analytics, v.v., bạn thậm chí có thể kích hoạt một sự kiện để ghi lại những gì người dùng đang sao chép từ trang web của bạn. Thú vị
geedubb

2
Tùy chọn đầu tiên bỏ qua các ký tự dòng mới của văn bản được sao chép.
soham

7

Đây là giải pháp javascript vani từ giải pháp đã sửa đổi ở trên nhưng hỗ trợ nhiều trình duyệt hơn (phương pháp trình duyệt chéo)

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

Phiên bản ngắn nhất cho jQuery mà tôi đã thử nghiệm và đang hoạt động là:

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

đâu là đoạn mã thực sự sao chép kết quả vào khay nhớ tạm?
vsync

@vsync Tôi tin rằng điều này chỉ bổ sung chức năng ngay trước khi quá trình sao chép diễn ra (được hệ thống thực hiện khi người dùng bắt đầu nó).
TerranRich

@vsync - như TerraRich đã nói, tôi đã cố gắng trả lời cho câu hỏi, đó là về việc thêm thông tin bổ sung vào văn bản được sao chép, vì vậy giải pháp chỉ bao gồm phần này.
user2276146

3

Đây là một plugin trong jquery để làm điều đó https://github.com/niklasvh/jquery.plugin.clipboard Từ readme của dự án "Tập lệnh này sửa đổi nội dung của một lựa chọn trước khi sự kiện sao chép được gọi, dẫn đến lựa chọn được sao chép khác với những gì người dùng đã chọn.

Điều này cho phép bạn thêm / thêm nội dung vào lựa chọn, chẳng hạn như thông tin bản quyền hoặc nội dung khác.

Được phát hành theo Giấy phép MIT "


1
Điều đó trông rất hứa hẹn. Nó sử dụng các kiểu nội tuyến mà chúng tôi không cho phép với CSP của mình, nhưng nó có thể được điều chỉnh. Chúc mừng!
Keith

3

Cải thiện câu trả lời, khôi phục lựa chọn sau khi thay đổi để ngăn lựa chọn ngẫu nhiên sau khi sao chép.

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

@TsukimotoMitsumasa Nên cóvar range = selection.getRangeAt(0);
Vokiel

Khôi phục lựa chọn văn bản là một ý tưởng hay, nếu không, nó sẽ phá vỡ hành vi mặc định của trình duyệt.
Sergey

2

Cải tiến cho năm 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
Khi sao chép-dán, bạn sẽ mất định dạng ( <a> , <img> , <b> và các thẻ khác). Tốt hơn là lấy mã HTML của văn bản đã chọn. Sử dụng hàm getSelectionHtml () từ câu trả lời này: [ stackoverflow.com/a/4177234/4177020] Và bây giờ bạn có thể thay thế chuỗi này var selection = window.getSelection();bằng cách này:var selection = getSelectionHtml();
Dmitry Kulahin

0

Cũng có một giải pháp ngắn hơn một chút:

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

Đó là tổng hợp 2 câu trả lời ở trên + khả năng tương thích với Microsoft Edge.

Tôi cũng đã thêm khôi phục lựa chọn ban đầu vào cuối, vì nó được mong đợi theo mặc định trong bất kỳ trình duyệt nào.

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);
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.