问题1
项目中,选中文本(svg>text) 时,文本会有叠影,问题只在浏览器134版本后
如图:
元素结构
html
<style>
body{
::selection{
background-color: green;
}
}
</style>
<body>
<div style="position:releative">
<img/>
</div>
<svg style="position:absolute;">
<text fill="transparent"> </text>
</svg>
</body>
解决
html
<style>
svg>text::selection{
fill: transparent;
}
</style>
过程
- 1、找出问题可能
选中文本时,不应该出现叠影,但出现了,应该是fill="transparent"
失效了,旧浏览器版本无此问题,谷歌131,133无问题,只在134有问题
手写demo html
,当时没加body selection
样式,没复现问题,很慌,不知道咋办,只能证明这个是能解的
- 2、验证134版本的问题
谷歌浏览器找相关issue、 issues.chromium.org/issues?q=st...
但是只找到issues.chromium.org/issues/4037... ,不太像
翻阅了浏览器更新日志,developer.chrome.com/release-not... 找到可能相关的,在项目中确实发现继承了,加body selection
样式,复现问题

- 3、解决问题
谷歌搜CSS 突出显示继承
www.google.com.hk/search?q=CS...
得到详情的原理 developer.chrome.com/blog/select...
里面有这段案例:默认选中是有背景色的,现在继承的父元素 selection
没有写背景色,所以子元素也没背景色了。

由此可知,svg>text
的fill
属性,之前 selection
是跟起源元素text
,现在是跟父元素,我观察到项目里,有继承body
的selection
,body
的selection
里只写背景色,没有写fill
,那么自然也没有fill="transparent"
,要解决的话,只需要在selection
里加fill="transparent"
问题2
问题:文本无法拷贝
项目中监听了copy
事件,阻止默认行为,自己获取选中文本再模拟执行copy事件进行复制
简单的demo如下
js
<script>
function handleShortcutCopy(e){
console.log('xiao,启动');
let currentSelectedText = String(
window.getSelection()?.toString(),
);
console.log('currentSelectedText',currentSelectedText);
e.preventDefault();
e.stopPropagation();
let res = true;
const textarea = document.createElement('textarea');
try {
textarea.setAttribute('readonly', 'readonly');
textarea.setAttribute('class', 'without-copyperm-dom');
textarea.value = currentSelectedText;
document.body.appendChild(textarea);
textarea.select();
textarea.setSelectionRange(0, currentSelectedText.length);
res = document.execCommand('copy');
} catch (e) {
console.error(e);
res = false;
} finally {
document.body.removeChild(textarea);
}
console.log('res',res);
// navigator.clipboard.writeText(currentSelectedText)
}
setTimeout(()=>{
document.getElementsByClassName('sc-kNzBZN')[0].addEventListener('copy',handleShortcutCopy);
},500)
</script>
找根因
在项目里断点调试,
直接在监听事件 handleShortcutCopy
最上方return,不执行后面的,是可以复制的
在res = document.execCommand('copy');
的下一条语句打断点,此时是可以拷贝出来的,当时我认为拷贝没问题,应该是其他异步的原因导致
注意,copy
事件断点调试过久会导致拷贝失败,走进catch
里
去掉了各种didupdate、mutationObserve
,还是失败
只能去谷歌issue找灵感,在里面搜copy,ctrl+c等关键词
最终找到了 issues.chromium.org/issues/4013...
所以是谷歌浏览器的bug,再次更新版本就好了