想象一下包含标题的html文本(h1-h6)。在我的场景中,它也在一个html页面中作为DOM出现。因此,使用jQuery,我会像$('.text').find('h1,h2,h3,h4,h5,h6')
那样提取所有标题。
但我不想使用jQuery或任何其他重型框架。我怎么能用angularJS做到这一点? 请记住,我需要按照正确的顺序将标题显示为目录。
答案 0 :(得分:3)
所以这是我的最终解决方案。 ng-model部分用于在文本更新时更新标题。
.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();
}
}
})
用法:
<a ng-repeat="headline in headlines" ng-click="scrollTo(headline)">{{headline.label}}</a>
<div table-of-contents ng-model="html">{{html}}</div>
答案 1 :(得分:1)
看看这个库-https://www.cssscript.com/generating-a-table-of-contents-with-pure-javascript-toc/
您只需将js代码放在控制器中,它将所有标头放在ID为#toc的标签下
在您的html文件中创建
<div class="col-md-3 col-xs-12">
<aside id="toc"></aside> <!-- Content will appear here -->
</div>
<div class="col-md-9 col-xs-12 no-padding">
<div id="doc-content">
... Your content is here ...
</div>
然后在您的控制器中包含此功能。例如,您可以从onInit调用它。
loadTOC(){
// Definitions
var extendObj = function (src, target) {
for (var prop in target) {
if (target.hasOwnProperty(prop) && target[prop]) {
src[prop] = target[prop];
}
}
return src;
};
var getHeaders = function (selector, scope) {
var ret = [];
var target = document.querySelectorAll(scope);
Array.prototype.forEach.call(target, function (elem) {
var elems = elem.querySelectorAll(selector);
ret = ret.concat(Array.prototype.slice.call(elems));
});
return ret;
};
var getLevel = function (header) {
if (typeof header !== 'string') {
return 0;
}
var decs = header.match(/\d/g);
return decs ? Math.min.apply(null, decs) : 1;
};
var createList = function (wrapper, count) {
while (count--) {
wrapper = wrapper.appendChild(
document.createElement('ol')
);
if (count) {
wrapper = wrapper.appendChild(
document.createElement('li')
);
}
}
return wrapper;
};
var jumpBack = function (currentWrapper, offset) {
while (offset--) {
currentWrapper = currentWrapper.parentElement;
}
return currentWrapper;
};
var setAttrs = function (overwrite, prefix) {
return function (src, target, index) {
var content = src.textContent;
var pre = prefix + '-' + index;
target.textContent = content;
var id = overwrite ? pre : (src.id || pre);
id = encodeURIComponent(id);
src.id = id;
target.href = '#' + id;
};
};
var buildTOC = function (options) {
var selector = options.selector;
var scope = options.scope;
var ret = document.createElement('ol');
var wrapper = ret;
var lastLi = null;
var _setAttrs = setAttrs(options.overwrite, options.prefix);
getHeaders(selector, scope).reduce(function (prev, cur, index) {
var currentLevel = getLevel(cur.tagName);
var offset = currentLevel - prev;
if (offset > 0) {
wrapper = createList(lastLi, offset);
}
if (offset < 0) {
wrapper = jumpBack(wrapper, -offset * 2);
}
wrapper = wrapper || ret;
var li = document.createElement('li');
var a = document.createElement('a');
_setAttrs(cur, a, index);
wrapper.appendChild(li).appendChild(a);
lastLi = li;
return currentLevel;
}, getLevel(selector));
return ret;
};
var initTOC = function (options) {
var defaultOpts = {
selector: 'h1, h2, h3, h4, h5, h6',
scope: 'body',
overwrite: false,
prefix: 'toc'
};
options = extendObj(defaultOpts, options);
var selector = options.selector;
if (typeof selector !== 'string') {
throw new TypeError('selector must be a string');
}
if (!selector.match(/^(?:h[1-6],?\s*)+$/g)) {
throw new TypeError('selector must contains only h1-6');
}
return buildTOC(options);
};
// Generating the TOC
var container = document.querySelector('#toc');
var toc = initTOC({
selector: 'h1, h2',
scope: '#doc-content', // you can specify here a tag where to look at
overwrite: false,
prefix: 'toc'
});
container.appendChild(toc);
}
答案 2 :(得分:0)
你很幸运,应该能够使用angular.element几乎与使用jQuery完全相同的方式。
angular.element('h1')
会找到h1
元素。
答案 3 :(得分:0)
答案 4 :(得分:0)
您可以使用
找到具有“.text”类的元素angular.element(document.querySelectorAll(".text"));