简书链接:threejs代码创建div设置样式不生效的问题原因探讨
文章字数:452,阅读全文大约需要1分钟
环境是vue环境,发现添加后打开开发者工具发现这个div并没有被设置上样式,按理来说用html js的基础常识来说这样的代码定然是没问题的,但是vue中不一样了,
vue有样式作用域的概念

1
2
3
4
5
6
7
8
9
10
11
12
13
function create3DSprite(name): CSS3DSprite {
// 创建div元素(作为标签)
let div = document.createElement('div');
div.innerHTML = name;
div.className="tag"
// div.classList.add('tag');

//div元素包装为CSS2模型对象CSS2DObject
let label = new CSS3DSprite(div);
div.style.pointerEvents = 'none';//避免HTML标签遮挡三维场景的鼠标事件
label.scale.set(0.05, 0.05, 0.05); //缩放CSS3DObject模型对象
return label;//返回CSS2模型标签
}

这样的代码如果换在html环境肯定正常的,在vue中,涉及到作用域问题,

解决方法1 去掉作用域

就是去掉当前vue中的作用域 也就是上面的class定义了tag的作用域
<style scoped></style>改为<style></style
但是这样等于当前文件所有样式其他文件都能访问到,不太好

方法2直接在当前代码设置样式

直接在当前代码设置样式
,这方法是逃避解决 ,不妥

方法3用deep

此方法大概意思是让这个类变成公共的,不妥

1
2
3
4
.tag ::v-deep .your-deep-selector {
/* 这里定义通用的深度选择器样式 */
color: red;
}
```可能会影响性能,因为它允许样式穿透整个组件树。因此,应谨慎使用,确保在需要的情况下才使用深度选择器来避免潜在的性能问题。
1
2
3
4
5
,本方法具体使用

## 方法4治根治本
根据代码是threejs,使用3dsprite或者3dlabel可能是render导致的,
发现代码为

CSS3LabelRenderer.domElement.style.pointerEvents = ‘none’;
document.body.appendChild(CSS3LabelRenderer.domElement);

把body.appendChild改为当前vue的根 appendChild
## 方法5把这个div的样式直接放到全局样式表