【发布时间】:2017-01-23 10:52:44
【问题描述】:
以下场景。
我用 material2 编写了一个 angular2 应用程序。
在我的 SideNav 中是一个搜索输入字段。当用户输入它时,他被重定向(通过路由)到搜索组件,而搜索到的单词作为路由参数传递。
搜索组件显示应用程序的所有页面,其中包含搜索的单词(背景中的索引)。一旦用户点击条目,他就会被重定向到这个页面,并且搜索到的词作为查询参数被附加。我现在试图突出显示页面上搜索词的所有外观,用户被重定向到。目前我正在这样做:
subscription: ISubscription;
searchTerm: string;
constructor(private router: Router, private elementRef: ElementRef) {}
ngOnInit(): void {
this.subscription = this.router.routerState.queryParams.subscribe(queryParams => {
let searchTerm = queryParams['searchTerm'];
if (searchTerm) {
this.searchTerm = searchTerm;
} else {
this.searchTerm = null;
}
});
}
ngAfterContentInit(): void {
if (this.searchTerm && isStaticDoc) {
let regExp = new RegExp(`(${this.searchTerm})`, 'i');
this.highlightWords(this.elementRef.nativeElement, regExp);
}
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
highlightWords(node, regExp: RegExp) {
if (!node || ! regExp) {
return;
}
if (node.nodeType === 3) {
let regs = regExp.exec(node.nodeValue);
if (regs) {
let match = document.createElement('span');
match.appendChild(document.createTextNode(regs[0]));
match.classList.add('search-hl');
let after = node.splitText(regs.index);
after.nodeValue = after.nodeValue.substring(regs[0].length);
node.parentNode.insertBefore(match, after);
}
} else if (node.hasChildNodes()) {
for (let i = 0; i < node.childNodes.length; i++) {
this.highlightWords(node.childNodes[i], regExp);
}
}
}
现在的问题是,我收到一个错误RangeError: Maximum call stack size exceeded,这可能是一个暗示,递归级别太深了。
我已经尝试过使用 3rd 方库,它们中的任何一个都不是真的可以从 angular2 使用,而且最重要的是,编写的代码并不难……但它不起作用。
任何想法如何按照相同或类似的方法在最大调用堆栈大小以下暂存?
tl;dr 试图在页面上突出显示 searchTerm(作为 queryParam 传递)的所有外观 -> 我的方法(参见代码)不是 由于最大调用堆栈大小而工作。
编辑:使用 rc4 atm,很快就会升级,但这应该不是问题(我猜)
【问题讨论】:
-
在将搜索结果插入 dom 之前,为什么不对搜索结果使用字符串替换功能? (将 'searchvalue' 替换为 'searchvalue')要全部替换,请参阅:stackoverflow.com/questions/1144783/…
-
首先,感谢您的回答。但问题是,通过简单地调用替换
node#innerHtml在(例如)alink#href或 id 中出现的 searchTerm 也会被span包围,这会导致突出显示但非常破碎的页面(取决于搜索词)。我也尝试只匹配不在标签中的单词,但由于链接(到其他网站)有无限的可能性,几乎不可能找到正确的正则表达式,尤其是在 js 中缺乏负面外观的情况下......跨度> -
然后你可以找到匹配前第一次出现的“”是“>”,匹配后是“
-
@user3791775 我已经根据您的建议制定了一个解决方案。非常感谢!
-
很高兴听到这个消息!
标签: javascript dom angular highlight