You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Content scripts execute in a special environment called an isolated world. They have access to the DOM of the page they are injected into, but not to any JavaScript variables or functions created by the page.
所以我一直认为,内容脚本与网页脚本之间是共享 DOM 树的,而且我的代码也一直是这样写的,没有出过问题,直到今天……
现在细想一下,内容脚本中的 DOM 跟网页脚本中的 DOM 更像是「双向驱动」,而不是「完全相等」。
每当 DOM 上那些标准属性(例如上面例子里的 textContent)发生变化时,这个变化就会被同步到另一个环境,但如果是添加了一个不属于 DOM 的非标准属性,Chrome 可能就没有检测到——这个行为有点类似于 Vue 的做法:如果你想要检测某个属性的变化,你就一定要把这个属性注册在 data 里,否则 Vue 无法检测到属性发生了变化。
constscript=document.createElement('script')script.textContent=` var div = document.getElementById('app') console.log(div.__myProp)`document.head.appendChild(script)
今天在开发一个扩展程序的时候发现了一个很有意思的现象。
官方文档里是这样描述内容脚本的执行环境的:
所以我一直认为,内容脚本与网页脚本之间是共享 DOM 树的,而且我的代码也一直是这样写的,没有出过问题,直到今天……
有一个网页给一个元素添加了一个私有属性,就像这样:
然后我在内容脚本里执行了下面这段代码:
现在细想一下,内容脚本中的 DOM 跟网页脚本中的 DOM 更像是「双向驱动」,而不是「完全相等」。
每当 DOM 上那些标准属性(例如上面例子里的
textContent
)发生变化时,这个变化就会被同步到另一个环境,但如果是添加了一个不属于 DOM 的非标准属性,Chrome 可能就没有检测到——这个行为有点类似于 Vue 的做法:如果你想要检测某个属性的变化,你就一定要把这个属性注册在 data 里,否则 Vue 无法检测到属性发生了变化。不过也并非没有办法取的网页脚本中的非标准属性,只要从内容脚本里插入一段代码到网页脚本里执行就可以了:
<script>
元素的脚本会在网页脚本环境里执行,所以可以拿到在内容脚本里拿不到的东西,例如网页脚本的全局变量。另外,在网页脚本中执行的代码也可以同内容脚本通信:Communication with the embedding page如果代码量很大,也可以直接嵌一个扩展程序中的脚本文件进去:
写到最后似乎偏题了,就这样吧。
The text was updated successfully, but these errors were encountered: