Skip to content

Commit 59fae13

Browse files
author
gmsoft
committed
🍭
1 parent 61f781d commit 59fae13

File tree

2 files changed

+204
-0
lines changed

2 files changed

+204
-0
lines changed

component.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"version": "0.33.0",
3+
"description": "搜索页面关键字高亮显示",
4+
"name": "jquery-search-highlight",
5+
"main": "jquery.searchHighlight.js",
6+
"dependencies": [
7+
8+
],
9+
"shim": {
10+
"jquery.searchHighlight.js": {
11+
"deps": ["jquery"]
12+
}
13+
}
14+
}

jquery.searchHighlight.js

Lines changed: 190 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,190 @@
1+
/**
2+
* SearchHighlight plugin for jQuery
3+
*
4+
* Thanks to Scott Yang <http://scott.yang.id.au/>
5+
* for the original idea and some code
6+
*
7+
* @author Renato Formato <[email protected]>
8+
*
9+
* @version 0.33
10+
*
11+
* Options
12+
* - exact (string, default:"exact")
13+
* "exact" : find and highlight the exact words.
14+
* "whole" : find partial matches but highlight whole words
15+
* "partial": find and highlight partial matches
16+
*
17+
* - style_name (string, default:'hilite')
18+
* The class given to the span wrapping the matched words.
19+
*
20+
* - style_name_suffix (boolean, default:true)
21+
* If true a different number is added to style_name for every different matched word.
22+
*
23+
* - debug_referrer (string, default:null)
24+
* Set a referrer for debugging purpose.
25+
*
26+
* - engines (array of regex, default:null)
27+
* Add a new search engine regex to highlight searches coming from new search engines.
28+
* The first element is the regex to match the domain.
29+
* The second element is the regex to match the query string.
30+
* Ex: [/^http:\/\/my\.site\.net/i,/search=([^&]+)/i]
31+
*
32+
* - highlight (string, default:null)
33+
* A jQuery selector or object to set the elements enabled for highlight.
34+
* If null or no elements are found, all the document is enabled for highlight.
35+
*
36+
* - nohighlight (string, default:null)
37+
* A jQuery selector or object to set the elements not enabled for highlight.
38+
* This option has priority on highlight.
39+
*
40+
* - keys (string, default:null)
41+
* Disable the analisys of the referrer and search for the words given as argument
42+
*
43+
*/
44+
45+
(function($){
46+
jQuery.fn.SearchHighlight = function(options) {
47+
var ref = options.debug_referrer || document.referrer;
48+
if(!ref && options.keys==undefined) return this;
49+
50+
SearchHighlight.options = $.extend({exact:"exact",style_name:'hilite',style_name_suffix:true},options);
51+
52+
if(options.engines) SearchHighlight.engines.unshift(options.engines);
53+
var q = options.keys!=undefined?options.keys.toLowerCase().split(/[\s,\+\.]+/):SearchHighlight.decodeURL(ref,SearchHighlight.engines);
54+
if(q && q.join("")) {
55+
SearchHighlight.buildReplaceTools(q);
56+
return this.each(function(){
57+
var el = this;
58+
if(el==document) el = $("body")[0];
59+
SearchHighlight.hiliteElement(el, q);
60+
})
61+
} else return this;
62+
}
63+
64+
var SearchHighlight = {
65+
options: {},
66+
regex: [],
67+
engines: [
68+
[/^http:\/\/(www\.)?google\./i, /q=([^&]+)/i], // Google
69+
[/^http:\/\/(www\.)?search\.yahoo\./i, /p=([^&]+)/i], // Yahoo
70+
[/^http:\/\/(www\.)?search\.msn\./i, /q=([^&]+)/i], // MSN
71+
[/^http:\/\/(www\.)?search\.live\./i, /query=([^&]+)/i], // MSN Live
72+
[/^http:\/\/(www\.)?search\.aol\./i, /userQuery=([^&]+)/i], // AOL
73+
[/^http:\/\/(www\.)?ask\.com/i, /q=([^&]+)/i], // Ask.com
74+
[/^http:\/\/(www\.)?altavista\./i, /q=([^&]+)/i], // AltaVista
75+
[/^http:\/\/(www\.)?feedster\./i, /q=([^&]+)/i], // Feedster
76+
[/^http:\/\/(www\.)?search\.lycos\./i, /q=([^&]+)/i], // Lycos
77+
[/^http:\/\/(www\.)?alltheweb\./i, /q=([^&]+)/i], // AllTheWeb
78+
[/^http:\/\/(www\.)?technorati\.com/i, /([^\?\/]+)(?:\?.*)$/i], // Technorati
79+
],
80+
subs: {},
81+
decodeURL: function(URL,reg) {
82+
URL = decodeURIComponent(URL);
83+
var query = null;
84+
$.each(reg,function(i,n){
85+
if(n[0].test(URL)) {
86+
var match = URL.match(n[1]);
87+
if(match) {
88+
query = match[1].toLowerCase();
89+
return false;
90+
}
91+
}
92+
})
93+
94+
if (query) {
95+
query = query.replace(/(\'|")/, '\$1');
96+
query = query.split(/[\s,\+\.]+/);
97+
}
98+
99+
return query;
100+
},
101+
regexAccent : [
102+
[/[\xC0-\xC5\u0100-\u0105]/ig,'a'],
103+
[/[\xC7\u0106-\u010D]/ig,'c'],
104+
[/[\xC8-\xCB]/ig,'e'],
105+
[/[\xCC-\xCF]/ig,'i'],
106+
[/\xD1/ig,'n'],
107+
[/[\xD2-\xD6\xD8]/ig,'o'],
108+
[/[\u015A-\u0161]/ig,'s'],
109+
[/[\u0162-\u0167]/ig,'t'],
110+
[/[\xD9-\xDC]/ig,'u'],
111+
[/\xFF/ig,'y'],
112+
[/[\x91\x92\u2018\u2019]/ig,'\'']
113+
],
114+
matchAccent : /[\x91\x92\xC0-\xC5\xC7-\xCF\xD1-\xD6\xD8-\xDC\xFF\u0100-\u010D\u015A-\u0167\u2018\u2019]/ig,
115+
replaceAccent: function(q) {
116+
SearchHighlight.matchAccent.lastIndex = 0;
117+
if(SearchHighlight.matchAccent.test(q)) {
118+
for(var i=0,l=SearchHighlight.regexAccent.length;i<l;i++)
119+
q = q.replace(SearchHighlight.regexAccent[i][0],SearchHighlight.regexAccent[i][1]);
120+
}
121+
return q;
122+
},
123+
escapeRegEx : /((?:\\{2})*)([[\]{}*?|])/g, //the special chars . and + are already gone at this point because they are considered split chars
124+
buildReplaceTools : function(query) {
125+
var re = [], regex;
126+
$.each(query,function(i,n){
127+
if(n = SearchHighlight.replaceAccent(n).replace(SearchHighlight.escapeRegEx,"$1\\$2"))
128+
re.push(n);
129+
});
130+
131+
regex = re.join("|");
132+
switch(SearchHighlight.options.exact) {
133+
case "exact":
134+
regex = '\\b(?:'+regex+')\\b';
135+
break;
136+
case "whole":
137+
regex = '\\b\\w*('+regex+')\\w*\\b';
138+
break;
139+
}
140+
SearchHighlight.regex = new RegExp(regex, "gi");
141+
142+
$.each(re,function(i,n){
143+
SearchHighlight.subs[n] = SearchHighlight.options.style_name+
144+
(SearchHighlight.options.style_name_suffix?i+1:'');
145+
});
146+
},
147+
nosearch: /s(?:cript|tyle)|textarea/i,
148+
hiliteElement: function(el, query) {
149+
var opt = SearchHighlight.options, elHighlight, noHighlight;
150+
elHighlight = opt.highlight?$(opt.highlight):$("body");
151+
if(!elHighlight.length) elHighlight = $("body");
152+
noHighlight = opt.nohighlight?$(opt.nohighlight):$([]);
153+
154+
elHighlight.each(function(){
155+
SearchHighlight.hiliteTree(this,query,noHighlight);
156+
});
157+
},
158+
hiliteTree : function(el,query,noHighlight) {
159+
if(noHighlight.index(el)!=-1) return;
160+
var matchIndex = SearchHighlight.options.exact=="whole"?1:0;
161+
for(var startIndex=0,endIndex=el.childNodes.length;startIndex<endIndex;startIndex++) {
162+
var item = el.childNodes[startIndex];
163+
if ( item.nodeType != 8 ) {//comment node
164+
//text node
165+
if(item.nodeType==3) {
166+
var text = item.data, textNoAcc = SearchHighlight.replaceAccent(text);
167+
var newtext="",match,index=0;
168+
SearchHighlight.regex.lastIndex = 0;
169+
while(match = SearchHighlight.regex.exec(textNoAcc)) {
170+
newtext += text.substr(index,match.index-index)+'<span class="'+
171+
SearchHighlight.subs[match[matchIndex].toLowerCase()]+'">'+text.substr(match.index,match[0].length)+"</span>";
172+
index = match.index+match[0].length;
173+
}
174+
if(newtext) {
175+
//add the last part of the text
176+
newtext += text.substring(index);
177+
var repl = $.merge([],$("<span>"+newtext+"</span>")[0].childNodes);
178+
endIndex += repl.length-1;
179+
startIndex += repl.length-1;
180+
$(item).before(repl).remove();
181+
}
182+
} else {
183+
if(item.nodeType==1 && item.nodeName.search(SearchHighlight.nosearch)==-1)
184+
SearchHighlight.hiliteTree(item,query,noHighlight);
185+
}
186+
}
187+
}
188+
}
189+
};
190+
})(jQuery)

0 commit comments

Comments
 (0)