MutationObserver監聽DOM變化示例

风雨后见彩虹發表於2024-09-13

示例程式碼:

<template>
  <div class="it-bottom-button" :style="{ right: bottomBarRight }">
    <slot></slot>
  </div>
</template>
<script>
export default {
  name: "itBottomBar",
  componentNmame: "itBottomBar",
  props: {
    el: {
      type: String,
      default: "#subview"
    },
    right: {
      type: String,
      default: "20px"
    }
  },
  data() {
    return {
      bottomBarScrollBarWidth: 0,
      bottomBarRight: "20px",
      mutationObserver: null
    };
  },
  watch: {
    right() {
      this.bottomBarRight = this.right;
    }
  },
  mounted() {
    this.getScrollWidth();
    this.initMutationObserver();
  },
  beforeDestroy() {
    // 停止監控
    this.mutationObserver.disconnect();
    this.mutationObserver = null;
  },
  methods: {
    getScrollWidth() {
      const outer = document.createElement("div");
      outer.className = "el-scrollbar__wrap";
      outer.style.visibility = "hidden";
      outer.style.width = "100px";
      outer.style.position = "absolute";
      outer.style.top = "-9999px";
      document.body.appendChild(outer);

      const widthNoScroll = outer.offsetWidth;
      outer.style.overflow = "scroll";

      const inner = document.createElement("div");
      inner.style.width = "100%";
      outer.appendChild(inner);

      const widthWithScroll = inner.offsetWidth;
      outer.parentNode.removeChild(outer);
      this.bottomBarScrollBarWidth = widthNoScroll - widthWithScroll;
    },

    // 初始化MutationObserver監聽DOM變化
    initMutationObserver() {
      const MutationObserver = window.MutationObserver || window.WebkitMutationObserver || window.MozMutationObserver;
      // 監測瀏覽器是否支援
      const observeMutationSupport = !!MutationObserver;
      if (!observeMutationSupport) return;
      const subview = document.querySelector(this.el);
      const config = {
        attributes: true,
        childList: true,
        characterData: true,
        subtree: true
      };
      this.mutationObserver = new MutationObserver(() => {
        this.bottomBarViewChange();
      });
      this.mutationObserver.observe(subview, config);
    },

    bottomBarViewChange() {
      const subview = document.querySelector(this.el);
      let subviewScrollHeight = subview.scrollHeight; // 內容高度
      let subvviewOffsetHeight = subview.offsetHeight; // 可視區域高度
      if (subviewScrollHeight > subvviewOffsetHeight) {
        this.bottomBarRight = this.bottomBarScrollBarWidth + Number(this.right.replace("px", "")) + "px";
      } else {
        this.bottomBarRight = this.right;
      }
    }
  }
};
</script>

使用示例:

<it-bottom-bar>
      <el-button @click="goBack">取 消</el-button>
      <el-button type="primary" @click="submitForm('ruleForm')">保 存</el-button>
</it-bottom-bar>

相關文章