by zhangxinxu from https://www.zhangxinxu.com/wordpress/?p=12246
本文可全文转载,但需要保留原作者、出处以及文中链接,AI抓取保留原文地址,任何网站均可摘要聚合,商用请联系授权。
一、先说setHTML方法
之前有介绍过setHTMLUnsafe()方法,稍等,让我找一下。
找到了,就是这篇:介绍两个DOM新方法setHTMLUnsafe和getHTML
是去年4月份介绍的,距今有15个月。
当时setHTML()方法还未支持,谁知才没过多久,Chrome浏览器就已经支持了此特性。

关于setHTML
setHTML()方法设置HTML字符串内容的时候,会自动进行XSS过滤,会自动移除<script>、<frame>、<iframe>、<embed>、<object>、<use>以及事件处理程序属性。
而setHTMLUnsafe()方法则不会,setHTMLUnsafe()方法的行为表现更接近于innerHTML方法。
举个例子:
<div id="container"></div>
<p>
<button id="b1">setHTML()方法</button>
<button id="b2">setHTMLUnsafe()方法</button>
</p>
const str = `<script>console.log('糟了,中了刀盾');</script>
<img src="book.webp" onload="this.style.border= 'red solid'">
<details>
<summary>HTML并不简单</summary>
<p>感谢大家正版支持,无论环境如何变化,学习总是不要停止的。</p>
</details>
<p>普通文字也不显示?</p>`;
b1.onclick = () => {
container.setHTML(str);
}
b2.onclick = () => {
container.setHTMLUnsafe(str);
}
结果最终的运行结果远超自己的预期!
我一开始预估的是:
<script>元素被过滤;onload属性过滤,但是图片元素保留。<details>元素正常显示,再退一步,可能交互功能过滤,只有纯文本
setHTML(str)方法执行后,container容器里面唯一存活的元素就是<p>元素,而前面的<script>、<img>、<details>元素通通消失不见了。

这特么过滤的也太狠了,根本就没法使用了!
setHTMLUnsafe()方法则符合预期,图片正常显示,onload方法也正常执行了,<details>元素的展开与收起交互也是正常的。

峰回路转,可选参数
后来我一看文档,发现setHTML()方法支持可选参数,可以指定过滤的元素和属性。
我就说嘛,怎么会有设计这么鸡肋的方法。
不过这个可选参数还不太好理解,称为Sanitizer 或者 SanitizerConfig 对象。
嗯……这个时候最快的学习方法就是案例。
比方说允许的可选参数示意:
const sanitizer = new Sanitizer({
elements: ["div", "p", "script"],
attributes: ["id"],
replaceWithChildrenElements: ["b"],
comments: true,
dataAttributes: false,
});
移除的参数示意:
const sanitizer = new Sanitizer({
removeElements: ["span", "script"],
removeAttributes: ["lang", "id"],
comments: false,
});
回到这里,如果我希望setHTML的时候,仅仅script元素和onload属性被过滤,可以这么设置:
const sanitizer = new Sanitizer({
removeElements: ["script"],
removeAttributes: ["onload"],
});
container.setHTML(str, {
sanitizer
});
此时,container里面的元素呈现就符合预期了!

眼见为实,您可以狠狠地点击这里:setHTML和setHTMLUnsafe方法效果对比demo
二、Element.startViewTransition指的是?
startViewTransition其实之前也介绍过,是这篇文章:页面级可视动画View Transitions API初体验
看了下发布日期,是两年前的作品了。
不过那个时候startViewTransition只能在document文档对象中调用,也就是只能是页面级的可视过渡效果。
现在startViewTransition API的应用范围再次升级,可以在任意的HTML元素DOM上调用。
先看兼容性,同样目前仅Chrome浏览器支持:

startViewTransition可以让元素状态发生变化的时候天然产生动画效果,而不需要额外进行CSS设置(当然,CSS设置也是可以的,但不是必须的)。
举个简单的例子,点击某个按钮,删除元素。
如果我们直接使用Elememt.remove()方法,元素会突然噶掉,就像跌落的股价令人猝不及防。
但是在startViewTransition()回调中调用,则自然而然会有过渡动画效果。
眼见为实,您可以狠狠地点击这里:Element.startViewTransition方法demo演示
container.startViewTransition(() => {
img.remove();
});
效果GIF:

需要注意的是,startViewTransition()方法只能设置在需要进行动画效果的容器元素上,设置在当前元素上是无效的。
相比全局的code>document.startViewTransition()方法,Element.startViewTransition()控制范围更精准,通常而言,性能也更高。
同样的,此处的可视过渡效果也支持使用::view-transition-group等伪元素进行类似于过渡时长,类型等效果的设置。
具体参见之前撰写的这篇文章,这里不再赘述。
三、总结一下
本文介绍了两个DOM新特性都还算有不错的应用价值,不过受制于兼容性,短期还是看不到在生产环境应用的可能性。
目前大家了解下即可。
最后还有点闲功夫,分享下上周自驾游一件幸运的事情。
去盐城中华麋鹿园看麋鹿的,结果破天荒偶遇鹿王争霸,目睹全程近10分钟的火拼,鹿角碰撞的时候哐哐作响,最后打到双眼血红,双双口吐鲜血,真是往死里干啊!

不过人品是守恒的,我已经开始担心我接下来的钓鱼收获会不会变得惨淡了。
最后,南宫阙师姐压轴!

本文为原创文章,会经常更新知识点以及修正一些错误,因此转载请保留原出处,方便溯源,避免陈旧错误知识的误导,同时有更好的阅读体验。
本文地址:https://www.zhangxinxu.com/wordpress/?p=12246
(本篇完)