Directiva de AngularJS para generar una tabla de contenidos.
-
21-12-2019 - |
Pregunta
Imagina un texto HTML que contiene titulares (H1-H6).En mi situation también está presente como DOM en una página HTML.Así que usando jQuery haría algo como $('.text').find('h1,h2,h3,h4,h5,h6')
para extraer todos los titulares.
Pero no quiero usar jquery o cualquier otro marco pesado.¿Cómo puedo hacer esto con angularjs? Recuerde que necesito los titulares en el orden correcto para mostrarlo como una tabla de contenido.
Solución
Así que aquí está mi solución final.La parte modelo NG se usa para actualizar los titulares cuando se actualiza el texto.
.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();
}
}
})
Uso:
<a ng-repeat="headline in headlines" ng-click="scrollTo(headline)">{{headline.label}}</a>
<div table-of-contents ng-model="html">{{html}}</div>
Otros consejos
Estás en suerte, y debería poder usarla angular.element Casi exactamente de la misma manera que usaría jquery.
Puedes encontrar los elementos que tienen la clase ".Text" usando
angular.element(document.querySelectorAll(".text"));