jQuery跨标签突出显示元素中的文本片段
jQuery highlight pieces of text in an element across tags
我想使用 jQuery 选择并返回搜索到的文本。
问题是;文本的某些部分可能位于<span>
或其他内联元素中,因此当在此文本中搜索'waffles are tasty'
时:'I'm not sure about <i>cabbages</i>, but <b>waffles</b> <span>are</span> <i>tasty</i>, indeed.'
,您不会得到任何匹配项,而文本对人们来说看起来不会中断。
让我们用这个 HTML 作为例子:
<div id="parent">
<span style="font-size: 1.2em">
I
</span>
like turtles
<span>
quite a
</span>
lot, actually.
<span>
there's loads of
</span>
tortoises over there, OMG
<div id="child">
<span style="font-size: 1.2em">
I
</span>
like turtles
<span>
quite a
</span>
lot, actually.
TURTLES!
</div>
</div>
有了这个(或类似的)JavaScript:
$('div#parent').selectText({query: ['i like', 'turtles', 'loads of tortoises'], caseinsensitive: true}).each(function () {
$(this).css('background-color', '#ffff00');
});
//The (hypothetical) SelectText function would return an array of wrapped elements to chain .each(); on them
您可能希望生成此输出:(显然没有注释)
<div id="parent">
<span style="font-size: 1.2em">
<span class="selected" style="background-color: #ffff00">
I
</span> <!--Wrap in 2 separate selection spans so the original hierarchy is disturbed less (as opposed to wrapping 'I' and 'like' in a single selection span)-->
</span>
<span class="selected" style="background-color: #ffff00">
like
</span>
<span class="selected" style="background-color: #ffff00"> <!--Simple match, because the search query is just the word 'turtles'-->
turtles
</span>
<span>
quite a
</span>
lot, actually.
<span>
there's
<span class="selected" style="background-color: #ffff00">
loads of
</span> <!--Selection span needs to be closed here because of HTML tag order-->
</span>
<span class="selected" style="background-color: #ffff00"> <!--Capture the rest of the found text with a second selection span-->
tortoises
</span>
over there, OMG
<div id="child"> <!--This element's children are not searched because it's not a span-->
<span style="font-size: 1.2em">
I
</span>
like turtles
<span>
quite a
</span>
lot, actually.
TURTLES!
</div>
</div>
(假设的)SelectText
函数会将所有选定的文本包装在<span class="selected">
标签中,而不管搜索的某些部分是否位于其他内联元素中,如<span>
、''等。它不会搜索子<div>
的内容,因为它不是内联元素。
有没有一个jQuery插件可以做这样的事情?(将搜索查询包装在 SPAN 标记中并返回它们,而忽略找到的文本的某些部分是否可能位于其他内联元素中?
如果没有,如何创建这样的函数?这个函数有点像我正在寻找的,但它不会返回所选范围的数组,并且当找到的部分文本嵌套在其他内联元素中时会中断。
任何帮助将不胜感激!
小菜一碟!看到这里。
折叠符号:
$.each(
$(...).findText(...),
function (){
...
}
);
内联表示法:
$(...).findText(...).each(function (){
...
}
);
三个选项:
- 为此,请使用浏览器的内置方法。对于这一发现,IE
TextRange
了其findText()
方法;其他浏览器(除了 Opera,上次我检查,那是很久以前的事了)有window.find()
.但是,window.find()
可能会在某个时候被杀死而不被替换,这并不理想。对于突出显示,您可以使用document.execCommand()
. - 使用我的 Rangy 库。这里有一个演示:http://rangy.googlecode.com/svn/trunk/demos/textrange.html
- 构建自己的代码以在 DOM 中搜索文本内容并设置其样式。
此答案更详细地介绍了前两个选项:
https://stackoverflow.com/a/5887719/96100
由于我现在碰巧正在做类似的事情,如果你想看看我对"选项 3"的解释的开始,我想我会分享这个,主要特点是遍历所有文本节点,而不会改变现有标签。尚未在任何不寻常的浏览器中进行测试,因此对此没有任何保证!
function DOMComb2 (oParent) {
if (oParent.hasChildNodes()) {
for (var oNode = oParent.firstChild; oNode; oNode = oNode.nextSibling) {
if (oNode.nodeType==3 && oNode.nodeValue) { // Add regexp to search the text here
var highlight = document.createElement('span');
highlight.appendChild(oNode.cloneNode(true));
highlight.className = 'selected';
oParent.replaceChild(highlight, oNode);
// Or, the shorter, uglier jQuery hybrid one-liner
// oParent.replaceChild($('<span class="selected">' + oNode.nodeValue + '</span>')[0], oNode);
}
if (oNode.tagName != 'DIV') { // Add any other element you want to avoid
DOMComb2(oNode);
}
}
}
}
然后也许使用 jQuery 有选择地搜索内容:
$('aside').each(function(){
DOMComb2($(this)[0]);
});
当然,如果你的旁白中有旁白,可能会发生奇怪的事情。
(DOMComb 函数改编自 Mozilla 开发参考网站https://developer.mozilla.org/en-US/docs/Web/API/Node)
我写了一稿作为小提琴。主要步骤:
我为jQuery做了一个插件
$.fn.selectText = function(params){
var phrases = params.query,
ignorance = params.ignorecase;
wrapper = $(this);
. . .
return(wrapper);
};
现在我可以将选择称为$(...).selectText({query:["tortoise"], ignorance: true, style: 'selection'});
我知道你想在函数调用后有迭代器,但在你的情况下这是不可能的,因为迭代器必须返回有效的jQuery选择器。例如: word <tag>word word</tag> word
不是有效的选择器。
的内容后,对于每个搜索makeRegexp()
进行个人正则表达式。
每个搜索的 html 源转到emulateSelection()
,然后wrapWords()
主要思想是包装<span class="selection">...</span>
每个短语,而不是用标签分隔,但不分析整个节点树。
注意:
它不适用于 html 中的<b><i>...
标签。您必须在正则表达式字符串中进行更正。我不保证它可以与 unicode 一起使用。但谁知道呢...
据我了解,我们谈论的是像$.each($(...).searchText("..."),function (str){...});
这样的迭代器。
看看大卫·赫伯特·劳伦斯的诗:
<div class="poem"><p class="part">I never saw a wild thing<br />
sorry for itself.<br />
A small bird will drop frozen dead from a bough<br />
without ever having felt sorry for itself.<br /></p></div>
实际上,渲染后,浏览器会这样理解它:
<div class="poem">
<p class="part">
<br>I never saw a wild thing</br>
<br>sorry for itself.</br>
<br>A small bird will drop frozen dead from a bough</br>
<br>without ever having felt sorry for itself.</br>
</p>
</div>
例如,我寻找短语:"wild thing sorry for"
.因此,我必须强调一下:
wild thing</br><br>sorry for
我不能像这样包装它<span>wild thing</br><br>sorry for</span>
,然后通过一些临时id="search-xxxx"创建jQuery选择器,并将其返回 - 这是错误的html。我可以像这样包装每段文本:
<span search="search-xxxxx">wild thing</span></br><br><span search="search-xxxxx">sorry for</span>
然后我必须调用一些函数并返回选择器的jQuery数组:
return($("[search=search-xxxxx]"));
现在我们有两个"结果":a)"野物";b) "对不起"。这真的是你想要的吗?
或
你必须像另一个插件一样编写你自己的函数each()
jQuery:
$.fn.eachSearch = function(arr, func){
...
};
其中 arr 不是选择器数组,而是选择器数组数组,例如:
arr = [
{selector as whole search},
{[{selector as first part of search]}, {[selector as second part of search]}},
...
]
- 如何使用jquery在填充自动完成的值后使文本框只读
- 使用Clipboard.js复制span文本
- 使用JS如何动态更改显示的html文件中的文本背景颜色
- 用程序搜索JQuery数据表中的文本
- jQuery匹配JSON对象的部分文本
- 如何将某些文本片段划分为父标签的子项
- 如何获取文档片段中的所有文本节点
- jQuery跨标签突出显示元素中的文本片段
- 将文本片段从外部页面获取到谷歌浏览器扩展程序
- 如何将 fadeOut jQuery 属性与 Javascript 文本片段一起使用
- 用于观察的聚合物代码示例片段不会更改文本颜色
- 将文本拆分为一些粗体和一些不在功能Javascript片段上
- 通过JavaScript正则表达式提取特定的文本片段
- 在jQuery和/或javascript中检索页面上的所有斜体文本片段
- Ace编辑器自动完成,对本地片段/文本的优先级较低
- Ace编辑器-如何包括帮助文本和片段在同一弹出
- 如何在升华文本片段中使用$char
- 画布片段的崇高或原子文本编辑器
- 获取html文本片段,而无需创建DOM
- 如何在此代码片段中定位链接图像而不是链接文本