如何阻止Chrome在复制/粘贴时将相对链接转换为绝对链接
How to stop Chrome from turning relative links to absolute links on copy/paste?
我正在用contenteditable="true"
从div
复制富文本,并将其粘贴到Medium草稿中。大多数格式都保存得很好,但出于某种原因,我不明白所有相对链接都转换为绝对链接。我不知道这是在哪一步发生的。我甚至认为Medium可能在听"粘贴"事件。这将是最糟糕的情况,因为我几乎无法控制它。但如果是这样,他们如何访问我复制内容时所在页面的URL?事实上,在与其他浏览器核实后,我得出结论,这是Chrome的错,而不是Medium的错。在Safari上它工作得很好,在Firefox上它根本不工作(但这是另一个问题的主题…)。
为了让事情变得更清楚,我试图模仿我在Wordpress博客上使用的脚注插件的行为,写一个基本上相同的bookmarklet。
这里有一个演示页面,你可以用类似wiki的语法粘贴文本,用于内联引用,并将其解析为适当的脚注:
https://rawgit.com/arielpontes/footnoter/master/index.html
在这两种使用模式中([1]复制/粘贴到演示页面或[2]使用bookmarklet),生成的html都有适当的相对链接。然而,在Chrome上粘贴回Medium后,它们变得绝对,指向rawgit.com
并破坏了功能。
然而,如果我从本地机器而不是rawgit.com
运行代码,即使在Chrome上粘贴后,链接也会保持相对形式。
可能发生了什么?有什么办法解决它吗?
TL;DR-负责粘贴内容的程序是将其放入剪贴板的程序。
每次将内容复制到剪贴板中时,执行复制的应用程序都可以在其中放置几种数据类型,因此paste
所在的程序将能够使用最适合它的数据类型。在浏览器的情况下,当您选择网页的内容并复制到剪贴板时,浏览器将创建两种类型(html/plain
和text/html
),因此,如果您将该内容粘贴到一个可以处理html的程序中,则粘贴的数据将是html,但如果不是,则数据将是纯文本。
基本上你有两个选择:
- 覆盖浏览器保存在剪贴板中的内容(这样,无论内容将粘贴到何处,它都将完全按照您想要的方式显示)
- 劫持粘贴事件,从剪贴板中获取数据,按照您想要的方式进行更改,然后自己将其放入编辑器中
$('#text').on('paste', function(e) {
if ($('input[name=paste-type]:checked').val() == 'special') {
e.preventDefault();
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
node = document.createElement("p");
text = 'Replacement text only for the paste'
node.appendChild(document.createTextNode(text))
range.insertNode(node);
}
}
}
});
$(document).on('copy', function(e) {
if ($('input[name=copy-type]:checked').val() == 'special') {
e.preventDefault();
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
range = sel.getRangeAt(0);
nodes = range.cloneContents().childNodes
content = ''
contentPlain = ''
for (var i = 0; i < nodes.length; i++) {
node = nodes[i];
contentPlain += node.textContent
if (node.nodeType == 3) {
content += node.textContent
} else if (node.nodeType == 1) {
content += node.outerHTML
}
}
}
} else {
content = '<span style="color: red; background: yellow;">Replacement text only for the copy</span>';
}
e.originalEvent.clipboardData.setData('text/html', content);
e.originalEvent.clipboardData.setData('text/plain', contentPlain);
}
});
$('#btn1').click(function() {
$('#ta1').val($('#text').html());
});
<script src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
<div id="text" contenteditable="true" style="width: 400px; height :250px; border: 1px solid black;">Paste your text here...</div><br />
<textarea id="ta1" style="width: 400px; height: 150px; border: 1px solid green;" disabled="disabled"></textarea><br />
<button id="btn1">View HTML</button><br />
<label for="reg"><input type="radio" name="paste-type" value="regular" id="reg" checked="checked" /> Regular Paste</label>
<label for="special"><input type="radio" name="paste-type" value="special" id="special" /> Force my paste</label>
<br /><br />
<label for="copy-reg"><input type="radio" name="copy-type" value="regular" id="copy-reg" checked="checked" /> Regular Copy</label>
<label for="copy-special"><input type="radio" name="copy-type" value="special" id="copy-special" /> Force my copy</label>
<br /><br />
<div style="width: 400px; height: 300px; border: 1px solid red;">
<p>Nonumes molestiae <b>scripserit mei eu. In sea singulis evertitur</b>, verear inimicus delicatissimi ad eam. Eu eros scripserit cum, nam ferri ludus saperet te, ex sea nostro prompta inciderint. Est at causae .</p>
<p>Quem feugait nam cu, sed <span style="background: red;">tantas meliore eu. Propriae efficiendi at</span> has, in usu nusquam noluisse, no nam natum verterem. Eu tation dignissim pro. Id eos wisi mollis commune</p>
<p>Ea has quando blandit <a href="#a1">intellegebat, iusto</a> fabulas eos in, per consul suscipit inciderint cu. Ea veri possim nostrud vis. Id civibi. Ut duo posse <a href="#a2">graecis voluptatibus</a>, mea eu errem possim quaestio.</p>
</div>
在上面的例子中,我给出了可以玩的选项(原始复制/粘贴和特殊复制/粘贴)
您可以看到,在特殊复制的示例中,我构建了html
字符串,以从页面中的选择中放入剪贴板(基于DOM
元素)。通过这种方式,我能够获得href
的精确值(而不将其更改为绝对路径)。
为了方便起见,jsfiddle中的代码完全相同:https://jsfiddle.net/m0ad3uaa/
问题出在客户端。浏览器复制具有绝对URL的链接,这是为了防止在将链接粘贴到不同区域时出现问题。
例如,如果我单击http://site1.com
上的一个链接,它看起来像<a href="/myresource.jpg">
,我将被引导到http://site1.com/myresource.jpg
。
现在,如果您要将相同的标记复制到http://site2.com
,那么链接现在将指向http://site2.com/myresource.jpg
,它可能存在,也可能不存在。
在大多数情况下,这是有道理的,就好像你在使用Chrome,你不太可能试图复制一个网站、资产等等。它还修复了<img>
标记指向不存在的资产的问题。
然而,尽管如此,还是有可能以编程的方式打乱所选内容
这里有一个很好的例子:http://bavotasan.com/2010/add-a-copyright-notice-to-copied-text/
从本质上讲,您只需要将document.oncopy
更改为window.getSelection()
并删除域名的所有实例,从而确保链接是相对的。
- 绝对链接/相对链接均未获胜't在菜单中工作
- 相对链接在 HTML 页面上不起作用
- 相对链接和backbone.js路由器
- 带有JS点击相对路径的网页URL链接
- jQuery或Javascript根据环境动态更改链接(相对/站点相对/绝对)
- 在javascript / php中使相对链接绝对
- jQueryMobile中的程序化(相对于基于链接的)导航
- 更改字符串中包含的相对绝对链接
- 在jQuery中使用相对路径识别链接
- 将js文件中的相对链接设置为来自文件源而不是域
- javascript为所有链接动态添加相对路径
- 用完整的url替换根相对链接
- 查看当前页面是否等于相对链接- JavaScript
- CodeIgniter追加URI段与相对链接
- 如何阻止Chrome在复制/粘贴时将相对链接转换为绝对链接
- 与 react-router 的编程相对链接
- Delphi的执行命令问题,图像的相对链接
- 如何在javascript中将所有“链接rel样式表”相对路径转换为绝对路径
- 在选择器中使用相对元素或链接查询选择器之间的区别
- JSONLoader对象链接- URL工作正常,相对路径不行