xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!

MutationObserver


"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2020-03-22
 * @modified
 *
 * @description
 * @augments
 * @example
 * @link
 *
 */

const log = console.log;

class DOM_CLASS {
  public watch(node: any){
    // 观察dom数据变化
    const MutationObserver = (<any>window).MutationObserver || (<any>window).WebKitMutationObserver || (<any>window).MozMutationObserver;
    const target = document.querySelector(node);
    const observer = new MutationObserver((mo: any) =>{
        log(`mo`, mo);
    });
    const config = {
      childList: true,
      attributes: true,
      characterData: true,
      subtree:true,
      attributeOldValue:true,
      characterDataOldValue:true,
    };
    observer.observe(target, config);
  }
}



export default DOM_CLASS;

export {
  DOM_CLASS,
};



IntersectionObserver

polyfill

https://github.com/w3c/IntersectionObserver/tree/master/polyfill

$ npm i -S intersection-observer

demo

https://codepen.io/xgqfrms/pen/bGGQNrW?editors=1010

// https://c7sky.com/lazy-loading-images-using-intersection-observer.html

class LazyLoadImage {
  // constructor(props);
  // super();
  constructor(){
    this.name = "";
    this.config = {};
    this.images = "";
    this.imageCount = "";
    // this.observer = "";
    this.defaults = {
      imageLoadedClass: 'js-lazy-image--handled',
      imageSelector: '.js-lazy-image',
      // If the image gets within 50px in the Y axis, start the download.
      rootMargin: '-100px 0px',
      // rootMargin: '50px 0px',
      threshold: 0.01,
    };
  }
  // defaults = {
  //   imageLoadedClass: 'js-lazy-image--handled',
  //   imageSelector: '.js-lazy-image',
  //   // If the image gets within 50px in the Y axis, start the download.
  //   rootMargin: '50px 0px',
  //   threshold: 0.01
  // };
  fetchImage(url) {
    return new Promise((resolve, reject) => {
      const image = new Image();
      image.src = url;
      image.onload = resolve;
      image.onerror = reject;
    });
  }
  preloadImage(image) {
    const url = image.dataset.src;
    if (!url) {
      return;
    }
    return this.fetchImage(url).then(() => {
      this.applyImage(image, src);
    });
  }
  loadImagesImmediately(images) {
    // foreach() is not supported in IE
    for (let i = 0; i < images.length; i++) {
      let image = images[i];
      this.preloadImage(image);
    }
  }
  applyImage(img, src) {
    // Prevent this from being lazy loaded a second time.
    img.classList.add(config.imageLoadedClass);
    img.src = src;
  }
  disconnect() {
    if (!observer) {
      return;
    }
    this.observer.disconnect();
  }
  onIntersection(entries) {
    console.log(`entries`, entries);
    let that = this;
    // Disconnect if we've already loaded all of the images
    if (this.imageCount === 0) {
      this.disconnect();
      return;
    }
    // Loop through the entries
    for (let i = 0; i < entries.length; i++) {
      let entry = entries[i];
      // Are we in viewport?
      if (entry.intersectionRatio > 0) {
        this.imageCount--;
        // Stop watching and load the image
        console.log(`this.observer`, this.observer, that.observer);
        // this.observer && this.observer.unobserve(entry.target);
        // this.preloadImage(entry.target);
      }
    }
  }
  init(options = {}) {
    this.config = {
      ...this.defaults,
      ...options,
    };
    this.images = [...document.querySelectorAll(this.config.imageSelector)];
    this.imageCount = this.images.length;
    // If we don't have support for intersection observer, loads the images immediately
    if (!('IntersectionObserver' in window)) {
      this.loadImagesImmediately(this.images);
    } else {
      // It is supported, load the images
      this.observer = new IntersectionObserver(this.onIntersection, this.config);
      console.log(`init this.observer`, this.observer);
      // foreach() is not supported in IE
      for (let i = 0; i < this.images.length; i++) {
        let image = this.images[i];
        if (image.classList.contains(this.config.imageLoadedClass)) {
          continue;
        }
        this.observer.observe(image);
        console.log(`observer`, this.observer);
      }
    }
  }
};

let app = new LazyLoadImage();
app.init();

// export default LazyLoadImage;


原文地址:https://www.cnblogs.com/xgqfrms/p/12549181.html