何だこれ?#
著作権犬は退散しろ、もう私が侵害される心配はない(実際は紳士を防ぐが小人を防がず)。
知乎に似たウェブサイトでは、ウェブサイト上で 42 文字以上のテキストをコピーすると、自動的にこのような著作権声明が追加されます:
著作権は作者に帰属します。
商業利用については、作者に連絡して許可を得てください。非商業利用の場合は、出典を明記してください。
作者:DIYgod
リンク:https://www.anotherhome.net/
出典:Anotherhome
原理#
-
copy イベントを監視する
-
window.getSelection () を使用して選択されたテキストを取得する
-
clipboardData.setData を使用してクリップボードの内容を操作する
コード#
document.body.addEventListener('copy', function (e) {
if (window.getSelection().toString() && window.getSelection().toString().length > 42) {
setClipboardText(e);
alert('商業利用については、作者に連絡して許可を得てください。非商業利用の場合は、出典を明記してください。');
}
});
function setClipboardText(event) {
var clipboardData = event.clipboardData || window.clipboardData;
if (clipboardData) {
event.preventDefault();
var htmlData = ''
+ '著作権は作者に帰属します。<br>'
+ '商業利用については、作者に連絡して許可を得てください。<br>'
+ '作者:DIYgod<br>'
+ 'リンク:' + window.location.href + '<br>'
+ '出典:Anotherhome<br><br>'
+ window.getSelection().toString();
var textData = ''
+ '著作権は作者に帰属します。\n'
+ '商業利用については、作者に連絡して許可を得てください。\n'
+ '作者:DIYgod\n'
+ 'リンク:' + window.location.href + '\n'
+ '出典:Anotherhome\n\n'
+ window.getSelection().toString();
clipboardData.setData('text/html', htmlData);
clipboardData.setData('text/plain',textData);
}
}
既知の問題#
iOS Safari は clipboardData.setData () メソッドに非対応なため、iOS Safari では機能しません。
知乎オリジナル版#
以下は知乎のオリジナル版のキーコードです。原理は似ていますので、興味があればご覧ください:
var lz = function (a, b, c) {
function d(a, b) {
return ["著作権は作者に帰属します。", "商業利用については、作者に連絡して許可を得てください。", "作者:" + b, "リンク:" + a, "出典:知乎", "", ""]
}
function f(a, b, c) {
return "\x3cdiv\x3e" + d(b, c).join("\x3cbr /\x3e") + a + "\x3c/div\x3e"
}
function g(a) {
var g = z.Wq(), m = g && (0, z.ib)(g.Ed());
if (m && !(42 > m.length)) {
if ("object" === typeof a.originalEvent.clipboardData && (a.originalEvent.clipboardData.setData("text/html", f(g.Of(), b, c)), a.originalEvent.clipboardData.setData("text/plain", d(b, c).join("\n") + m), 0 < a.originalEvent.clipboardData.getData("text/plain").length)) {
a.preventDefault();
return
}
if (window.getSelection) {
a = g.Of();
var n = (0, window.$)(f(a, b, c)).css({position: "fixed", left: "-9999px"}).appendTo("body");
window.getSelection().selectAllChildren(n.get(0));
(0, window.setTimeout)(function () {
g.select();
n.remove()
}, 200)
}
}
}
a && b && c && (z.Fa(b, "http") || (b = window.location.protocol + "//" + window.location.host + b), a.on("copy", g))
};