mootools
Searching within the page is a major browser functionality, but what if we could code a search box in JavaScript that would do the same thing? I set out to do that using MooTools and ended up with a pretty decent solution.
在页面内进行搜索是浏览器的主要功能,但是如果我们可以在JavaScript中编写可以实现相同功能的搜索框怎么办? 我开始使用MooTools做到这一点,最后得到了一个不错的解决方案。
MooTools JavaScript类 (The MooTools JavaScript Class)
var Highlighter = new Class({
/* implements */
Implements: [Options],
/* options */
options: {
autoUnhighlight: true,
caseSensitive: false,
elements: '*',
className: '',
onlyWords: false,
tag: 'span'
},
/* initialization */
initialize: function(options) {
/* set options */
this.setOptions(options);
this.elements = $$(this.options.elements);
this.words = [];
},
/* directs the plugin to highlight elements */
highlight: function(words,elements,className) {
/* figure out what we need to use as element(s) */
var elements = $$(elements || this.elements);
var klass = className || this.options.className;
if (words.constructor === String) { words = [words]; }
/* auto unhighlight old words? */
if(this.options.autoUnhighlight) { this.unhighlight(); }
/* set the pattern and regex */
var pattern = '(' + words.join('|') + ')';
pattern = this.options.onlyWords ? '\\b' + pattern + '\\b' : pattern;
var regex = new RegExp(pattern, this.options.caseSensitive ? '' : 'i');
/* run it for each element! */
elements.each(function(el) { this.recurse(el,regex,klass); },this);
/* make me chainable! */
return this;
},
/* unhighlights items */
unhighlight: function(words) {
//var selector = this.options.tag + (word ? '[rel=' + word + ']' : '');
if (words.constructor === String) { words = [words]; }
words.each(function(word) {
word = (this.options.caseSensitive ? word : word.toUpperCase());
if(this.words[word]) {
var elements = $$(this.words[word]);
elements.set('class','');
elements.each(function(el) {
var tn = document.createTextNode(el.get('text'));
el.getParent().replaceChild(tn,el);
});
}
},this);
return this;
},
/* recursed function */
recurse: function(node,regex,klass) {
if (node.nodeType === 3) {
var match = node.data.match(regex);
if (match) {
/* new element */
var highlight = new Element(this.options.tag);
highlight.addClass(klass);
var wordNode = node.splitText(match.index);
wordNode.splitText(match[0].length);
var wordClone = wordNode.cloneNode(true);
highlight.appendChild(wordClone);
wordNode.parentNode.replaceChild(highlight, wordNode);
highlight.set('rel',highlight.get('text'));
var comparer = highlight.get('text');
if(!this.options.caseSensitive) { comparer = highlight.get('text').toUpperCase(); }
if(!this.words[comparer]) { this.words[comparer] = []; }
this.words[comparer].push(highlight);
return 1;
}
} else if ((node.nodeType === 1 && node.childNodes) && !/(script|style)/i.test(node.tagName) && !(node.tagName === this.options.tag.toUpperCase() && node.className === klass)) {
for (var i = 0; i < node.childNodes.length; i++) {
i += this.recurse(node.childNodes[i],regex,klass);
}
}
return 0;
}
});
The class does provide a few options:
该类确实提供了一些选项:
autoUnhighlight: (defaults to true) Defines whether or not to auto-unhighlight highlighted words when searched.
autoUnhighlight :( 默认为true)定义搜索时是否自动取消突出显示突出显示的单词。
caseSensitive: (defaults to false) Defines whether the search should be case sensitive.
caseSensitive :( 默认为false)定义搜索是否区分大小写。
elements: (defaults to '*') Defines which elements are searchable.
elements :( 默认为“ *”)定义可搜索的元素。
className: (defaults to '') The class name that will represent the highlighted word class. Gets applied to a span.
className:( 默认为“”)将代表突出显示的单词class的类名称。 应用于范围。
onlyWords: (defaults to false) Defines whether the class should only find words.
onlyWords :( 默认为false)定义类是否仅应查找单词。
tag: (defaults to 'span') Defines the generated element type which will contain the highlighted text.
tag :( 默认为'span')定义生成的元素类型,其中将包含突出显示的文本。
The class has two main methods:
该类有两个主要方法:
highlight: Highlights the given text. Accepts the words, elements, and classname as parameters.
高亮:突出显示给定的文本。 接受单词,元素和类名作为参数。
unhighlight: Unhighlights the given text. Accepts words as parameters.
取消突出显示:取消突出显示给定的文本。 接受单词作为参数。
MooTools的用法 (The MooTools Usage)
/* sample usage */
window.addEvent('domready',function() {
/* instance */
var highlighter = new Highlighter({
elements: '#sample-content li',
className: 'highlight',
autoUnhighlight: false
});
/* submit listener */
document.id('submit').addEvent('click',function() { if(document.id('search').value) { highlighter.highlight(document.id('search').value); } });
document.id('submit3').addEvent('click',function() { if(document.id('search3').value) { highlighter.highlight(document.id('search3').value,'*','highlight1'); } });
document.id('submit2').addEvent('click',function() { if(document.id('search2').value) { highlighter.unhighlight(document.id('search2').value); } });
document.id('search').addEvent('keypress',function(e) { if(e.key == 'enter') { document.id('submit').fireEvent('click'); } });
document.id('search3').addEvent('keypress',function(e) { if(e.key == 'enter') { document.id('submit3').fireEvent('click'); } });
document.id('search2').addEvent('keypress',function(e) { if(e.key == 'enter') { document.id('submit2').fireEvent('click'); } });
});
What's great is that there are only two functions to use publicly for this class: highlight() and unhighlight().
很棒的是,该类仅公开使用两个函数: highlight()和unhighlight() 。
It's important for me to mention that this class is not perfect! One glaring issue is that if you search for a word, then unhighlight the word, and then look for that word with the next word ("Lorem" => "Lorem ipsum"), the searcher doesn't find the second word due to the way the nodes are in place. If you have a solution to fix that, please let me know. This class was based on http://bartaz.github.com/sandbox.js/jquery.highlight.html.
对于我来说,重要的是这门课并不完美! 一个明显的问题是,如果您搜索一个单词,然后取消突出显示该单词,然后使用下一个单词(“ Lorem” =>“ Lorem ipsum”)查找该单词,则搜索者将找不到第二个单词,原因是节点的放置方式。 如果您有解决此问题的解决方案,请告诉我。 此类基于http://bartaz.github.com/sandbox.js/jquery.highlight.html 。
Happy searching!
搜索愉快!
mootools