Angular JS文本高亮指令

Angular JS text highlighter directive

本文关键字:指令 高亮 文本 JS Angular      更新时间:2023-09-26

我想要一个指令,根据搜索字符串在元素中突出显示文本。

大多数可用的解决方案使用过滤器而不是指令,使用方式如下:

<div ng-html-bind-unsafe="This is the contents for this div | highlight:highlightText"></div>

下面是一个例子

我宁愿使用指令而不是过滤器,因为我不喜欢把元素的内容放在ng-html-bind属性中。我觉得元素的内容应该在里面。

无论如何,我写了这个指令,但想知道是否有更好的方法来写它。我觉得这不是最有效的方法。这是小提琴。注意,<code>元素中的文本没有突出显示。这是因为.contents()只返回元素的直接子节点和文本节点。这种行为没有问题,除非有一种非常简单的方法递归遍历每个子元素的内容。

对于遍历每个子元素的内容,可以使用递归。将添加高光笔和删除高光笔的代码放入一个函数中,并为每个子元素调用这些函数。

.contents()返回一个Jquery对象。如果node.nodeType === 1,将其转换为一个角元素并再次对其调用contents()。

        /*Function to add Highlighters*/
        scope.addHighlight = function (elm, value) {
            angular.forEach(elm.contents(), function (node) {
                if (node.nodeType === 3 && scope.needle.test(node.nodeValue)) {
                    node = angular.element(node);
                    node.after(node[0].nodeValue.replace(scope.needle, '<span class="highlight">$1</span>')).remove();
                } else if (node.nodeType === 1) {
                    node = angular.element(node);
                    if (node.contents().length > 0) scope.addHighlight(node, value);
                }
            });
        }
        /*Function to remove current Highlighters*/
        scope.removeHighlight = function (elm, value) {
            angular.forEach(elm.contents(), function (node) {
                nodetype = node.nodeType;
                node = angular.element(node);
                if (node[0].nodeName === 'SPAN' && node.hasClass('highlight')) {
                    node.after(node.html()).remove();
                    elm[0].normalize();
                }
                if (node.children().length > 0 && nodetype === 1) scope.removeHighlight(node, value);
            });
        }