Directive AngularJS pour générer une table des matières
-
21-12-2019 - |
Question
Imaginez un texte HTML contenant des titres (h1-h6).Dans ma situation, il est également présent sous forme de DOM dans une page HTML.Donc, en utilisant jQuery, je ferais quelque chose comme $('.text').find('h1,h2,h3,h4,h5,h6')
pour extraire tous les titres.
Mais je ne veux pas utiliser jQuery ou tout autre framework lourd.Comment puis-je faire cela avec angulaireJS ?N'oubliez pas que j'ai besoin des titres dans le bon ordre pour les afficher sous forme de table des matières.
La solution
Voici ma solution finale.La partie modèle NG est utilisée pour mettre à jour les titres lorsque le texte est mis à jour.
.directive('tableOfContents', function(){
return {
restrict:'A',
require:'?ngModel',
link : function(scope, elm, attrs,ngModel) {
function updateHeadlines() {
scope.headlines=[];
angular.forEach(elm[0].querySelectorAll('h1,h2,h3,h4,h5,h6'), function(e){
scope.headlines.push({
level: e.tagName[1],
label: angular.element(e).text(),
element: e
});
});
}
// avoid memoryleaks from dom references
scope.$on('$destroy',function(){
scope.headlines=[];
});
// scroll to one of the headlines
scope.scrollTo=function(headline){
headline.element.scrollIntoView();
}
// when the html updates whe update the headlines
ngModel.$render = updateHeadlines;
updateHeadlines();
}
}
})
Utilisation:
<a ng-repeat="headline in headlines" ng-click="scrollTo(headline)">{{headline.label}}</a>
<div table-of-contents ng-model="html">{{html}}</div>
Autres conseils
Vous avez de la chance et devriez pouvoir utiliser élément angulaire presque exactement de la même manière que vous utiliseriez jQuery.
angular.element('h1')
trouvera h1
éléments.
Vous pouvez trouver les éléments ayant la classe ".text" en utilisant
angular.element(document.querySelectorAll(".text"));