观察 Vue 中的异步外部 DOM 变化

Posted

技术标签:

【中文标题】观察 Vue 中的异步外部 DOM 变化【英文标题】:Watch for async external DOM changes in Vue 【发布时间】:2021-04-22 22:21:11 【问题描述】:

我正在使用这个组件从 Revive Adserver 注入广告:

<template>
 <div class="ins-box">
  <ins ref="insEl" :data-revive-zoneid="zoneId" data-revive-id="hash"></ins>
 </div>
</template>

<script>
export default 
  props: 
    zoneId:  type: String, default: '' 
  ,

Revive Adserver 的外部 api 将加载区域的广告图片(在示例区域 1234 中),转换 &lt;ins&gt; 元素:

<ins zone-id="1234" />

它创建的&lt;img&gt; 标签看起来像这样:

<ins data-v-fdd5803a="" data-revive-zoneid="7859">
 <a href="http://servedby.revive-adserver.net/ck.php?params" target="_blank">
  <img src="https://www.source.com/image-555.jpg"    title="" border="0">
 </a>
</ins>

我想在将创建的&lt;img&gt; 元素添加到 DOM 时对其进行编辑。我需要删除宽度和高度值。

在 jQuery 中我可以做类似$('ins img').load(function() )

Vue 的方法是什么? 该元素不是由我的 Vue 代码创建的,我也没有引用它。最重要的是,现在和他们可能会出现一个新的&lt;img&gt; 元素。

【问题讨论】:

【参考方案1】:

您可以使用纯 CSS 来解决这个问题,例如使用属性选择器。将图像的高度和宽度设置为auto 应该相当于删除 html 属性。

下面是一个示例,它将为 &lt;a&gt; 标记内的所有图像设置样式,其中 href 带有广告服务器域。

a[href*="revive-adserver.net"] img
  height: auto;
  width: auto;


如果您坚持使用 javascript 执行此操作,请在元素的父级上使用 mutationObserver 来检测对其子级的外部 DOM 更改。给父母一个参考:

<div ref="ins-box" class="ins-box">

创建变异观察者:

mounted() 
  const observer = new MutationObserver((mutationsList, observer) => 
    const img = this.$refs['ins-box'].querySelector('img');
    img.onload = () => 
      // Now do something with `img`
    
  );
  observer.observe(this.$refs['ins-box'],  childList: true );

观察父元素而不是元素本身的变化的原因是元素可能被外部服务完全替换。

【讨论】:

谢谢。这解决了我的问题(忽略高度和宽度)。我已经确定了 css 的范围,但这不适用于 img 标签,但删除范围有帮助。但是,如果我必须对 img 标签的 javascript 做一些事情。你会把它放在哪里?我会为此更新我的问题。 您可以通过提及 Vue 的作用域样式不适用于外部脚本添加的 DOM 元素来改进问题的 css 部分。这些信息本来可以帮助我更早解决我的问题。 我不介意添加它,但考虑到深度选择器可能工作得很好,我不确定这总是准确的,我还没有测试过。请记住,范围样式出现在许多 Vue + css 问题上,并且网站上有专门针对该主题的答案。它至少会使每个答案的大小增加一倍以完全覆盖范围内的 css,这可能会减损答案的核心。也许我可以在链接中加入括号“(注意范围样式)”类型的编辑。

以上是关于观察 Vue 中的异步外部 DOM 变化的主要内容,如果未能解决你的问题,请参考以下文章

vue之理解异步更新 --- nextTick

vue使用this.$nextTick()函数

Vue中的nextTick

Vue $nextTick

vue 中的computed 和 watch 监听

观察整个 HTML DOM 中的文本变化 - 如何做到这一点?