Question

Imagine a html text that contains headlines (h1-h6). In my situtation it is also present as DOM in a html page. So using jQuery I would do something like $('.text').find('h1,h2,h3,h4,h5,h6') to extract all the headlines.

But I don't want to use jQuery or any other heavy framework. How can I do this with angularJS? Please remember that I need the headlines in the correct order to display it as a table of contents.

Was it helpful?

Solution

So here is my final solution. The ng-model part is used to update the headlines when the text is updated.

.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();
        }
    }
})

Usage:

<a ng-repeat="headline in headlines" ng-click="scrollTo(headline)">{{headline.label}}</a>
<div table-of-contents ng-model="html">{{html}}</div>

OTHER TIPS

You're in luck, and should be able to use angular.element almost exactly the same way as you would use jQuery.

angular.element('h1') will find h1 elements.

Angular jqLite is your option here, but don't forget that .find() is limited to lookups by tag name.

Check these SO SO answers if that helps.

You can find the elements having the class ".text" using

angular.element(document.querySelectorAll(".text"));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top