자바 스크립트 : 돌연변이 옵저버 API

원 글 : https://wangdoc.com/javascript/index.html

돌연변이 옵저버 API

개요

돌연변이 관찰자 API는 DOM의 변화를 모니터링하는 데 사용. 이러한 노드의 변화, 변화의 속성 변경 텍스트 내용 등의 변경의 DOM이 API는 알림을받을 수 있습니다.

DOM 돌연변이 옵저버 이벤트를 트리거로 변경 개념적으로 매우 가까운 경우에, 이는 이해할 수있다. 그러나, 다른 이벤트가 본질적 :; DOM의 변경 사항이 즉시 실행되지 않습니다, 돌연변이 관찰자가 비동기 적으로 실행됩니다 만, 현재까지 기다려야 이벤트가 트리거 동기화됩니다,라고하는 것입니다, DOM의 변경 사항은 즉시 해당 이벤트를 트리거합니다 모든 DOM 작업 트리거가 끝나기 전에.

이것은 DOM 기능의 잦은 변화에 대응하도록 설계되었습니다. 문서 (1000 개)에 연속 삽입되는 경우, 예를 들어, <p>1000 년, 돌연변이 옵저버 완전히 상이하고, 소자 (1000)의 연속 삽입 이벤트 브라우저 Caton을 일으킬 각 이벤트를위한 콜백 함수를 트리거 단락 끝이 트리거 후 삽입 트리거 한 번만된다.

돌연변이 관찰자는 다음과 같은 특징이 있습니다.

  • 이 작업이 실행됩니다 완료된 후 모든 스크립트 (즉, 비동기 트리거 모드)을 기다립니다.
  • 그것은 개별 섹션은 DOM 변화보다는 배열 DOM 변화 기록 처리 패키지.
  • 그것은이 DOM의 변화의 모든 유형에서 관찰 할 수있다, 당신은 단지 특정 유형의 변경을 관찰 지정할 수 있습니다.

MutationObserver 생성자

사용에서의 사용 MutationObserver생성자, 뷰어의 새로운 인스턴스는,이 예 동안 콜백 함수를 지정합니다.

var observer = new MutationObserver(callback);

위의 코드 콜백 함수는 DOM에서 변경할 때마다 호출됩니다. 콜백 함수는 제 배열의 변화이며, 두 인수를 받아, 두번째 인스턴스는 관찰, 다음은 예이다.

var observer = new MutationObserver(function (mutations, observer) {
  mutations.forEach(function(mutation) {
    console.log(mutation);
  });
});

방법 으로서는 MutationObserver

() 관찰

observe리스너를 시작하는 데 사용되는 방법은 두 개의 인수를 사용합니다.

  • DOM 노드 관찰한다 : 첫 번째 파라미터
  • 두번째 파라미터 : 구성 목적은 관찰하는 특정한 변형을 지정할
var article = document.querySelector('article');

var  options = {
  'childList': true,
  'attributes':true
} ;

observer.observe(article, options);

상기 코드는 상기 observe방법은 제 DOM 요소가 관찰 될, 두 개의 매개 변수 article변경의 제 2 유형이 관찰 될 (속성 변경 및 자식 노드로 변경).

DOM 변화 형 옵저버 (즉 코드 이상 관찰 할 수있는 options개체), 여러 가지가있다.

  • childList : 자식 노드의 변경 (추가, 삭제 또는 변경 참조).
  • 속성 : 속성의 변화를.
  • CharacterData를 : 내용이나 노드 노드 텍스트의 변화.

어떤 당신이 관찰하고자하는 변화의 종류 option는 개체의 지정된 값 true. 같은 시간을 지정해야합니다 childList, attributes그리고 characterData모든 오류를 지정하지 않을 경우 중 하나 이상에.

유형의 변화뿐만 아니라 options객체 당신은 또한 다음과 같은 속성을 설정할 수 있습니다 :

  • subtree: 시청자가 노드의 모든 자손 노드에 적용할지 여부를 나타내는 부울 값입니다.
  • attributeOldValue: 관찰 나타내는 부울 값 attributes변경은 변경 전의 속성 값 여부를 기록해야 할 때.
  • characterDataOldValue: 관찰 나타내는 부울 값 characterData변경은 변경 전의 값을 기록해야 할 때.
  • attributeFilter: (예 : 관찰의 필요성 배열 나타내는 특정 속성 ['class','src']).
// 开始监听文档根节点(即<html>标签)的变动
mutationObserver.observe(document.documentElement, {
  attributes: true,
  characterData: true,
  childList: true,
  subtree: true,
  attributeOldValue: true,
  characterDataOldValue: true
});

처럼, 노드 관찰자를 추가하려면 addEventListener반복과 같은 방식으로 같은 관찰이 유효 추가, 콜백 함수는 여전히 한 번만 트리거됩니다. 다른 지정하면 options그 주제에 객체를 나중에 유사한 범위를 추가했다.

다음 예제는 자식 노드의 새로운 관측이다.

var insertedNodes = [];
var observer = new MutationObserver(function(mutations) {
  mutations.forEach(function(mutation) {
    for (var i = 0; i < mutation.addedNodes.length; i++) {
      insertedNodes.push(mutation.addedNodes[i]);
    }
  });
  console.log(insertedNodes);
});
observer.observe(document, { childList: true, subtree: true });

해제 (), takeRecords ()

disconnect방법은 시청을 중지하는 데 사용됩니다. 이 메서드를 호출 한 후, DOM의 변화가 다시 발생,이 뷰어를 트리거하지 않습니다.

observer.disconnect();

takeRecords기록에있어서, 즉, 치료 과정의 변화가 취소 바꾼다. 이 방법은 기록의 변화의 배열을 반환합니다.

observer.takeRecords();

다음은 예이다.

// 保存所有没有被观察器处理的变动
var changes = mutationObserver.takeRecords();

// 停止观察
mutationObserver.disconnect();

MutationRecord 객체

DOM은 변경 기록이 생성 될 때마다 (MutationRecord 인스턴스)를 변경한다. 이 예는 변화에 관련된 모든 정보가 들어 있습니다. 돌연변이 옵저버 프로세스의 하나 MutationRecord의 예 이루어지는 어레이.

MutationRecordDOM 객체에는 다음과 같은 속성의 정보가 포함되어 있습니다 :

  • type다음 유형의 변화 관찰 attributes( characterData또는 childList).
  • target: DOM 노드 변동한다.
  • addedNodes: 새로운 DOM 노드입니다.
  • removedNodes: 삭제 DOM 노드입니다.
  • previousSibling: 이전 형제 노드, 더 수익이없는 경우 null.
  • nextSibling: 다음 형제 노드는 돌아올 수없는 경우 null.
  • attributeName: 부동산의 변경이 발생합니다. 설정하면 attributeFilter, 만 반환 사전에 지정된 속성.
  • oldValue: 변경 전의 값. 이 속성은 attributecharacterData발생하는 경우, 변경 사항이 적용 childList변화가 반환됩니다 null.

애플리케이션 예제

자식 요소의 변화

다음 예제 프로그램은 어떻게 변경 기록을 읽을 수 있습니다.

var callback = function (records){
  records.map(function(record){
    console.log('Mutation type: ' + record.type);
    console.log('Mutation target: ' + record.target);
  });
};

var mo = new MutationObserver(callback);

var option = {
  'childList': true,
  'subtree': true
};

mo.observe(document.body, option);

위의 코드 뷰어 관찰하기 위해 <body>모든 하위 노드 ( childList대표 관찰 자식 노드 subtree관측 된 변화는 자손 노드를 나타냅니다). 콜백 함수는 콘솔에서 모든 유형 및 대상 노드의 변경을 표시합니다.

속성 변경

다음 예제 프로그램에서는 특성의 변화를 추적 할 수 있습니다.

var callback = function (records) {
  records.map(function (record) {
    console.log('Previous attribute value: ' + record.oldValue);
  });
};

var mo = new MutationObserver(callback);

var element = document.getElementById('#my_element');

var options = {
  'attributes': true,
  'attributeOldValue': true
}

mo.observe(element, options);

상기 특성 변경 추적 코드는 이전에 (설정 'attributes': true)를 다음 기록 전에 설정 값을 변경한다. 실제 변경이 발생하는 경우, 변경 전의 값 콘솔 상에 표시 될 것이다.

DOMContentLoaded 이벤트를 교체

페이지가로드, DOM 노드가 너무 오래 DOM에서 관측 된 변화로, 변경 기록을 생성합니다 생성 할 때, 처음으로 관련 이벤트를 트리거 할 수 있습니다를 사용 할 필요가 없습니다 DOMContentLoaded이벤트.

var observer = new MutationObserver(callback);
observer.observe(document.documentElement, {
  childList: true,
  subtree: true
});

위의 코드, 수신기 document.documentElement(즉, 페이지가 <html>변경 HTML 노드)를 자 노드의 subtree속성은 노드를 기울인다 더 포함 자손을 지정한다. 따라서, 생성하면 웹 페이지의 모든 요소는 즉시들을 수 있습니다.

다음 코드는 사용 MutationObserver목적은 생성 된 DOM 함수 수신기를 캡슐화한다.

(function(win){
  'use strict';

  var listeners = [];
  var doc = win.document;
  var MutationObserver = win.MutationObserver || win.WebKitMutationObserver;
  var observer;

  function ready(selector, fn){
    // 储存选择器和回调函数
    listeners.push({
      selector: selector,
      fn: fn
    });
    if(!observer){
      // 监听document变化
      observer = new MutationObserver(check);
      observer.observe(doc.documentElement, {
        childList: true,
        subtree: true
      });
    }
    // 检查该节点是否已经在DOM中
    check();
  }

  function check(){
  // 检查是否匹配已储存的节点
    for(var i = 0; i < listeners.length; i++){
      var listener = listeners[i];
      // 检查指定节点是否有匹配
      var elements = doc.querySelectorAll(listener.selector);
      for(var j = 0; j < elements.length; j++){
        var element = elements[j];
        // 确保回调函数只会对该元素调用一次
        if(!element.ready){
          element.ready = true;
          // 对该节点调用回调函数
          listener.fn.call(element, element);
        }
      }
    }
  }

  // 对外暴露ready
  win.ready = ready;

})(this);

// 使用方法
ready('.foo', function(element){
  // ...
});

참조 링크

추천

출처www.cnblogs.com/wbyixx/p/12499266.html