如何获取第三方动态生成的dom元素-观察器observer()

180 阅读2分钟

在做一个地图项目的时候,有一个编辑地图经纬度坐标的需求,这里是调取的第三方的api会在地图上采集当前的经纬度信息,点击地图上的某一个位置就会弹框确认是否修改为当前的经纬度坐标,然后回调函数会获取点击的value(经纬度信息),当时需求老师要求把这个弹窗的位置和样式都修改一下,我当时以为没有什么问题,不就是一个小样式吗,1分钟够了吧,最后发现第三方的文档没有关于样式的修改内容,然后这个弹窗的dom结构还是动态生成的,我哭死。

最后,我找到openObserver这个观察器的存在,它可以监测动态生成的dom元素,刚好可以使用它来获取到动态生成的三方提示弹窗,然后在对弹窗dom进行样式修改。

1、创建一个观察器并开启它

其中包括创建观察器实例、配置观察项、观察目标节点。

// 开启观察器
    openObserver() {
      // 创建一个观察器实例并传入回调函数
      const observer = new MutationObserver(this.MutationObservercallback);
      // 配置观察选项
      const config = { childList: true, subtree: true };
      // 开始观察目标节点
      observer.observe(document.body, config);
      // 将观察器实例存储在组件实例上以便后续使用
      this.observer = observer;
    },

2、观察器的回调函数

这里需要先在浏览器的dom结构中找到动态生成的弹窗的元素中的类名,选择对应类名去监听,回调函数中可以监听动态新增的dom节点和删除的节点信息,获取dom元素后就可以操作dom了。

mutation.addedNodes的循环中可以获取到动态新增的node节点对象,可以直接修改node中的样式即可。 如有在动态删除节点动作操作时,可以在mutation.removedNodes的循环中操作。

MutationObservercallback(mutationsList, observer) {
      for (let mutation of mutationsList) {
        if (mutation.type === 'childList') {
          mutation.addedNodes.forEach((node) => {
            if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains('layui-layer')) {
              // console.log('动态新增的layui-layer的dom:', node);
                // 设置 node 的 style 属性
                node.style.position = 'fixed';
                node.style.left = `1px`;
                node.style.top = `2px`;
                //...
            }
          });
          mutation.removedNodes.forEach((node) => {
            if (node.nodeType === Node.ELEMENT_NODE && node.classList.contains('layui-layer')) {
              // console.log('removed:', node);
            }
          });
        }
      }
    }

 

备注:如果修改的dom没有更新的话,可以使用$nextTick。