Maison > interface Web > Tutoriel H5 > le corps du texte

Implémentation des opérations d'annulation et de restauration de l'éditeur basées sur la nouvelle fonctionnalité HTML5 Mutation Observer_html5.

WBOY
Libérer: 2016-05-16 15:46:11
original
1872 Les gens l'ont consulté

Introduction à MutationObserver

MutationObserver offre aux développeurs la possibilité de répondre de manière appropriée lorsque l'arborescence DOM dans une certaine plage change. Cette API est conçue pour remplacer l'événement Mutation introduit dans la spécification d'événement DOM3.

Mutation Observer est une interface permettant de surveiller les modifications du DOM. Mutation Observer sera averti lorsque des modifications se produiront dans l'arborescence des objets DOM.

Mutation Observer possède les fonctionnalités suivantes :

•Il attend que toutes les tâches de script soient terminées avant de s'exécuter, c'est-à-dire de manière asynchrone
•Il encapsule les enregistrements de modifications DOM dans un tableau pour les traiter au lieu de traiter les modifications DOM une par une.
•Il peut observer tous les changements qui se produisent dans les nœuds DOM, et il peut également observer un certain type de changements

Informations MDN : MutationObserver

MutationObserver est un constructeur, donc lors de sa création, vous devez transmettre new MutationObserver ;

Lors de l'instanciation de MutationObserver, une fonction de rappel est requise. La fonction de rappel sera appelée lorsque le nœud DOM spécifié (nœud cible) change

.

Lorsqu'il est appelé, l'objet observateur sera passé à la fonction avec deux paramètres :

 1 : Le premier paramètre est un tableau contenant plusieurs objets MutationRecord

 2 : Le deuxième paramètre est l'objet observateur lui-même

.

Par exemple :

 

Copier le code
Le code est le suivant :

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

méthodes d'observateur

L'observateur d'instance a trois méthodes : 1 : observer ; 2 : déconnecter ; 3 : takeRecords ;

méthode d'observation

Méthode Observer : enregistrez le nœud cible qui doit être observé auprès de l'objet observateur actuel et recevez une notification lorsque le DOM change dans le nœud cible (vous pouvez également observer ses nœuds descendants en même temps

) ;

Cette méthode nécessite deux paramètres, le premier est le nœud cible et le deuxième paramètre est le type qui doit être surveillé pour les modifications, qui est un objet json. L'exemple est le suivant :

 


Copier le codeLe code est le suivant :
observer.observe( document. body, {
'childList' : true, //Les éléments enfants de cet élément sont ajoutés ou supprimés
'subtree' : true, //Tous les éléments enfants de cet élément sont ajoutés ou supprimés
' attributs' : true, //Écoutez les modifications d'attribut
'characterData' : true, //Écoutez les modifications de texte ou de commentaires
'attributeOldValue' : true, //Valeur originale de l'attribut
'characterDataOldValue' : vrai
});


méthode de déconnexion

La méthode de déconnexion cessera d'observer les propriétés et les changements de nœud du nœud cible jusqu'à ce que la méthode d'observation soit à nouveau appelée

 ;

takeRecords

Effacer la file d'attente d'enregistrement de l'objet observateur et renvoyer un tableau contenant l'objet événement Mutation ;

MutationObserver est parfait pour implémenter la restauration et l'annulation d'un éditeur, car toutes les modifications qui se produisent dans le nœud spécifié seront enregistrées à chaque fois. Si vous utilisez l'implémentation traditionnelle de keydown ou de keyup, il y aura certains inconvénients, tels que :

1 : Perte de défilement, entraînant une position de défilement inexacte

2 : Perte de focus ;

....

Il a fallu quelques heures pour écrire un plug-in de gestion MutationJS pour l'annulation et le rétablissement (gestion des annulations et des restaurations) implémenté via MutationObserver, qui peut être utilisé comme introduction distincte du plug-in : (

http://files.cnblogs.com/files/diligenceday/MutationJS.js
) :


Copier le code
Le code est le suivant :

/**
* @desc MutationJs, utilise le nouvel événement MutationObserve de DOM3 ; en écoutant les éléments de nœud spécifiés, écoute les changements dans les attributs dom internes ou les nœuds dom et exécute les rappels correspondants
* ;*/
window.nono = window.nono || {};
/**
* @desc
**/
nono.MutationJs = function( dom ) {
//Problèmes de compatibilité uniformes
var MutationObserver = this.MutationObserver = window.MutationObserver ||
window.WebKitMutationObserver ||
window.MozMutationObserver;
//Déterminer si le navigateur est ou S'il faut prendre en charge MutationObserver;
this.mutationObserverSupport = !!MutationObserver;
//Par défaut, écoutez les modifications dans les éléments enfants, les attributs des éléments enfants et les valeurs d'attribut;
this.options = {
'childList' : true,
'subtree' : true,
'attributes' : true,
'characterData' : true,
'attributeOldValue' : true,
'characterDataOldValue' : true
} ;
//Ceci enregistre l'instance de MutationObserve;
this.muta = {};
//La variable list enregistre les opérations de l'utilisateur;
this.list = [ ];
//L'index de restauration actuel
this.index = 0;
//S'il n'y a pas de dom, il écoutera le corps par défaut;
this.dom = dom|| document .documentElement.body || document. getElementsByTagName("body")[0];
//Démarrer la surveillance immédiatement;
this.observe( );
};
$.extend(nono. MutationJs.prototype, {
//Rappel pour les modifications de nœuds, vous devez enregistrer les opérations de rétablissement et d'annulation dans la liste ;
"callback" : function ( records , instance ) {
//Vous devez effacer le ceux derrière l'index;
this .list.splice( this.index 1 );
var _this = this;
records.map(function(record) {
var target = record.target;
console.log(record) ;
//Supprimer ou ajouter des éléments;
if( record.type === "childList" ) {
//Si vous supprimez des éléments;
if (record.removedNodes.length ! == 0) {
//Obtenir l'index relatif de l'élément ;
var index = _this.getIndexs(target.children, record.removedNodes);
_this.list .push({
"undo " : function() {
_this.disconnect();
_this.addChildren(target, record.removedNodes ,indexs );
_this.reObserve();
},
"redo " : function() {
_this.disconnect();
_this.removeChildren(target, record.removedNodes );
_this.reObserve();
}
});
//Si des éléments sont ajoutés;
};
if(record.addedNodes.length !== 0) {
//Obtenir l'index relatif de l'élément ;
var index = _this.getIndexs( target.children , record.addedNodes );
_this.list.push({
"undo" : function() {
_this.disconnect();
_this.removeChildren(target, record. addNodes );
_this.reObserve();
},
"redo" : function () {
_this.disconnect();
_this.addChildren(target, record.addedNodes, indexes);
_this.reObserve();
}
});
};
//@desc Qu'est-ce que c'est que CharacterData ;
//ref : http:// baike.baidu.com/link?url=Z3Xr2y7zIF50bjXDFpSlQ0PiaUPVZhQJO7SaMCJXWHxD6loRcf_TVx1vsG74WUSZ_0-7wq4_oq0Ci-8ghUAG8a
}else if( record.type === "characterData" ) {
var ancienneValeur = record.oldValue;
var newValue = record .target.textContent //|| record.target.innerText, n'est pas prêt à gérer la compatibilité IE789, donc innerText n'est pas nécessaire;
_this.list.push({
"annuler" : function() {
_this.disconnect();
target.textContent = oldValue;
_this.reObserve();
},
"redo" : function () {
_this.disconnect();
target.textContent = newValue;
_this.reObserve();
}
});
//Si les attributs changent , le style, l'ensemble de données et les attributs appartiennent tous aux modifications d'attributs, vous pouvez Traitement unifié ;
}else if( record.type === "attributes" ) {
var oldValue = record.oldValue;
var newValue = record.target.getAttribute( record.attributeName );
var attributeName = record.attributeName;
_this.list.push({ _this.disconnect();
target.setAttribute(attributeName, oldValue);
_this.reObserve();
},
"重做 (" : function ) {
_this.disconnect();
target.setAttribute(attributeName, newValue);
_this.reObserve();
}
});
}
}
} } );
// 重新設定索引;
this.index = this.list.length-1;
},
"removeChildren" : function ( target, Nodes ) {
for ( var i= 0, len=nodes.length; i target.removeChild(nodes[i] );
};
},
"addChildren" : 函數(目標、節點、索引) {
for(var i= 0, len=nodes.length;我 if(target.children[indexs[i]]) {
target.insertBefore(nodes[i], target.children[indexs[i]]) ;
}else{
target.appendChild(nodes[i]);
};
};
},
//快速方法,用於判斷子元素在父元素的哪個節點上;
"indexOf" : function ( target, obj ) {
return Array.prototype.indexOf.call ( target, obj)
},
"getIndexs" : function (target, objs) {
var result = [];
for(var i=0; i result.push( this.indexOf(target, objs[i]) );
};
回傳結果;
},
/**
* @desc 指定監聽的物件
**/
"observe" : function( ) {
if( this.dom.nodeType !== 1) return alert("參數不同,第一個參數應該是一個dom 節點");
this. muta = new this.MutationObserver( this.callback.bind(this) );
//立即開始監聽;
this .muta.observe( this.dom, this.options );
},
/**
* @desc 重新開始監聽;
**/
"reObserve" : function () {
this.muta.observe( this.dom, this.options );
},
/**
*@desc 不記錄dom操作, 所有在這個函數內部的操作不會記錄到undo和redo的列表中;
**/
"without" : function ( fn ) {
this.disconnect();
fn&fn ();
this.reObserve();
},
}
/**
* @desc 取消監聽;
**/
"disconnect" : function () {
return this.muta.disconnect() ;
},
/**
* @desc 儲存Mutation操作到list;
**/
},
/**
* @desc ;
**/
"save" : function ( obj ) {
if(!obj.undo)returnalert("傳進來的第一個參數必須有undo方法才行");
if(!obj.redo)returnalert( "傳進來的第一個參數必須有redo方法才行");
this.list.push(obj) ;
},
/**
* @desc 把指定index後面的操作刪除;
**/
"reset " : function () {
//清空備份;
this.list = [];
this .index = 0;
},
/**
* @desc 往回走, 取消回退
**/
"splice" : 函數(index ) {
this.list.splice(index );
},
/**
* @desc 往前走,重新操作
**/
"undo" : function () {
if( this.canUndo() ) {
this.list[this.index].undo();
this.index--;
};
},
/**
* @desc 判斷是否可以撤銷操作
**/
"重做" : function () {
if( this.canRedo ( ) ) {
this.index ;
this.list[this.index].redo();
};
},
/**
* @desc 判斷是否可以重新操作;
**/
"canUndo" : function () {
return this.index !== -1;
},
/***/
"canRedo" : function () {
返回this.list.length-1 !== this.index;
}});

MutationJS 如何使用


那這個MutationJS怎麼用呢?

複製程式碼
程式碼如下:

//Il s'agit d'instancier un objet MutationJS. Si aucun paramètre n'est transmis, il surveillera les modifications dans l'élément body par défaut
mu = new nono.MutationJs();
// Vous pouvez transmettre un élément spécifié. Par exemple :
mu = new nono.MutationJS( document.getElementById("div0") );
//Ensuite, toutes les modifications d'élément sous cet élément seront enregistrées par le plug-in.

L'instance de mutation mu a plusieurs méthodes :

1 : restauration de l'opération mu.undo()

2 : mu.redo() Annuler la restauration

3 : Que mu.canUndo() puisse fonctionner en retour, la valeur de retour est vraie ou fausse

 ;

4 : Que mu.canRedo() puisse annuler la restauration, la valeur de retour est vraie ou fausse

 ;

5 : mu.reset() efface toutes les listes d'annulation et libère de l'espace

6 : mu.without() passe un paramètre de fonction, et toutes les opérations DOM à l'intérieur de la fonction ne seront pas enregistrées par mu

;

MutationJS implémente un simple undoManager pour référence, qui fonctionne parfaitement sur Firefox, Chrome, Google Chrome et IE11 :


Copier le code
Le code est le suivant :












MutationObserver est destiné au remplacement Supprimez la série originale d'événements de mutation et le navigateur surveillera l'ajout, la suppression, le remplacement, etc. de tous les éléments sous l'élément spécifié ;



;
;

;



<script><br> window.onload = function () {<br> window.mu = new nono.MutationJs();<br> //Annuler la surveillance<br> mu.disconnect();<br> //Redémarrer la surveillance<br> mu .reObserve(); <br> document.getElementById("b0").addEventListener("click", function ( ev ) {<br> div = document.createElement("div");<br> div.innerHTML = document .getElementById("value ").value;<br> document.getElementById("div").appendChild( div);<br> });<br> document.getElementById("prev").addEventListener("click" , function ( ev ) {<br> mu.undo();<br> });<br> document.getElementById("next").addEventListener("click", function ( ev ) {<br> mu.redo ();<br> });<br> };<br></script>


Capture d'écran de DEMO sous IE :

Compatibilité navigateur de MutatoinObserver :

Fonctionnalité Chrome Firefox (Gecko) Internet Explorer Opéra Safari
Support de base
18

webkit

26

14(14) 11 15 6.0WebKit

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal