最近遇到客戶的一個需求,要在網頁中添加一個Search 功能,其實對於網頁的搜索,Ctrl+F,真的是很是足夠了,可是客戶的需求,不得不作,這裏就作了個關於Jquery Search function的簡單研究。歡飲提出不一樣解決方法。javascript
使用Contains函數。css
描述: 選擇全部包含指定文本的元素。html
jQuery( ":contains(text)" )java
text: 用來查找的一個文本字符串。這是區分大小寫的。node
這裏是官方連接:http://www.jquery123.com/api/contains-selector/jquery
這裏看個簡單的demo.web
<html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script src="Script/jquery-1.11.2.min.js" type="text/javascript"></script> <script type="text/javascript"> $(function () { $("div:contains('John')").css("text-decoration", "underline"); }); </script> </head> <body> <form id="form1" runat="server"> <div>John Resig</div> <div>George Martin</div> <div>Malcom John Sinclair</div> <div>J. Ohn</div> <div>john mohan</div> </form> </body> </html>
在瀏覽器中能夠看到。sql
這是個很是簡單的例子,在div中,只要包含了John,就添加下劃線,這裏區分大小寫的。數據庫
若是咱們不想區分大小寫,這裏須要用到Jquery 擴展;express
能夠查看這個連接:https://css-tricks.com/snippets/jquery/make-jquery-contains-case-insensitive/
jQuery.expr[':'].Contains = function (a, i, m) { return jQuery(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0; };
在包含上述代碼後,再在瀏覽器中查看效果;
能夠看出,這裏已經不區分大小寫了。
若是咱們想,在搜索輸入框中,輸入關鍵字,而後文本高亮顯示,使用Contains函數,看這個demo。
這裏是連接:http://jsfiddle.net/bipen/dyfRa/
這裏是Html 代碼;
Type Something: <input id="textBoxID" /> <table id="table" border=1> <tr style="display:table-row"> <th class="Name">NAME</th> <th class="Score">SCORE</th> <th class="Email">EMAIL</th> </tr> <tr> <!--tabledata--> <td >jQuery</td> <td >39</td> <td >test@gmail.com</td> </tr> <tr> <td >Javascript</td> <td >34</td> <td >abc@gmail.com</td> </tr> </table>
再看Jquery 代碼:
$.extend($.expr[":"], { "containsIN": function(elem, i, match, array) { return (elem.textContent || elem.innerText || "").toLowerCase().indexOf((match[3] || "").toLowerCase()) >= 0; } }); $('#textBoxID').keyup(function(){ $('td').css("background-color",''); var value= $(this).val(); $('td:containsIN("'+value+'")').css("background-color",'red'); });
查看效果;
項目實踐:
在實際的應用中,通常都要求會比較高,好比優先匹配全文(full text match)。而後匹配數目多的(split word by word)。根據匹配數目的多少排序。
排序須要用到數組的Sort函數,看個簡單例子
Sort numbers in an array in ascending order:
var points = [40, 100, 1, 5, 25, 10]; points.sort(function(a, b){return a-b});
The result of points will be:
在咱們搜索後,若是想關鍵字高亮顯示,這可使用簡單的插件。查看完整代碼;
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="SearchDemo.aspx.cs" Inherits="Jquery_Programming.SearchDemo" %> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <script src="Script/jquery-1.11.2.min.js" type="text/javascript"></script> <script type="text/javascript"> $(function () { // $("div:Contains('John')").css("text-decoration", "underline"); //press enter key to trigger click button $('#txtSearch').keypress(function (event) { if (event.keyCode == 13) { $('#btnSearch').trigger('click'); event.stopPropagation(); return false; } }); $('#btnSearch').click(function () { var item = $('#txtSearch').val(); if (item.length > 0) { //清空查詢結果 $('#searchResult').html(''); var itemIndex = 0; var newHtml = ""; //Use a regular expression (\s matches spaces, tabs, new lines, etc.) var itemArr = item.split(/\s+/); var newItemArr = []; var maxCount = 0; var fullMaxCount = 100; $('.Faq > li').each(function (index) { var $this = $(this).clone(); //first time the full text match if ($this.is(":contains('" + item + "')")) { $this.highlight(item); var p = {}; p.index = index; p.keyCount = fullMaxCount; p.refThis = $this; p.refText = $this.text(); newItemArr[index] = p; return; //jump the belowing code. } //then match word by word for (var i = 0, len = itemArr.length; i < len; i++) { // if ($this.text().toLowerCase().split(/\s+/).indexOf(itemArr[i].toLowerCase()) >= 0) { if ($this.is(":contains('" + itemArr[i] + "')")) { if (newItemArr[index] && newItemArr[index] != null) { newItemArr[index].keyCount++; } else { $this.highlight(itemArr[i]); var p = {}; p.index = index; p.keyCount = 1; p.refThis = $this; p.refText = $this.text(); newItemArr[index] = p; } } } }); if (newItemArr.length > 0) { newItemArr.sort(function (a, b) { return b.keyCount - a.keyCount; }); var icount = Math.floor(maxCount / 2); $.each(newItemArr, function (i, obj) { if (obj != undefined) { obj.refThis.find('i').text(itemIndex++); newHtml += "<li> " + obj.refThis.html() + "</li>"; } }); } if (newHtml.length == 0) { newHtml = "<h1>0 results </h1>"; newHtml += "<br />Your search returned no matches."; } $('#searchResult').append(newHtml); $('.Faq').hide(); } }); }); $.expr[":"].contains = $.expr.createPseudo(function (arg) { return function (elem) { return $(elem).text().toUpperCase().indexOf(arg.toUpperCase()) >= 0; }; }); jQuery.fn.highlight = function (pat) { function innerHighlight(node, pat) { var skip = 0; if (node.nodeType == 3) { var pos = node.data.toUpperCase().indexOf(pat); if (pos >= 0) { var spannode = document.createElement('span'); spannode.className = 'highlight'; var middlebit = node.splitText(pos); var endbit = middlebit.splitText(pat.length); var middleclone = middlebit.cloneNode(true); spannode.appendChild(middleclone); middlebit.parentNode.replaceChild(spannode, middlebit); skip = 1; } } else if (node.nodeType == 1 && node.childNodes && !/(script|style)/i.test(node.tagName)) { for (var i = 0; i < node.childNodes.length; ++i) { i += innerHighlight(node.childNodes[i], pat); } } return skip; } return this.each(function () { innerHighlight(this, pat.toUpperCase()); }); }; jQuery.fn.removeHighlight = function () { function newNormalize(node) { for (var i = 0, children = node.childNodes, nodeCount = children.length; i < nodeCount; i++) { var child = children[i]; if (child.nodeType == 1) { newNormalize(child); continue; } if (child.nodeType != 3) { continue; } var next = child.nextSibling; if (next == null || next.nodeType != 3) { continue; } var combined_text = child.nodeValue + next.nodeValue; new_node = node.ownerDocument.createTextNode(combined_text); node.insertBefore(new_node, child); node.removeChild(child); node.removeChild(next); i--; nodeCount--; } } return this.find("span.highlight").each(function () { var thisParent = this.parentNode; thisParent.replaceChild(this.firstChild, this); newNormalize(thisParent); }).end(); }; </script> <style type="text/css"> li { line-height: 30px; font-family: Arial; } #txtSearch { width: 200px; } i { font-size: 14px; font-weight: bold; margin: 10px; } ul { list-style-type: none; } .highlight { background-color: #fff34d; -moz-border-radius: 5px; /* FF1+ */ -webkit-border-radius: 5px; /* Saf3-4 */ border-radius: 5px; /* Opera 10.5, IE 9, Saf5, Chrome */ -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7); /* FF3.5+ */ -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7); /* Saf3.0+, Chrome */ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.7); /* Opera 10.5+, IE 9.0 */ } .highlight { padding:1px 4px; margin:0 -4px; } </style> </head> <body> <form id="form1" runat="server"> <div> Search Here:<input id="txtSearch" placeholder="Please input key words to search" /> <input type="button" id="btnSearch" value="Search" /></div> <ul id="searchResult"> </ul> <ul class="Faq"> <li><i>1</i>Question bans do not affect other privileges, such as commenting or voting, and there is no indication to the rest of the community that a particular user has been banned.</li> <li><i>2</i>The ban will be lifted automatically by the system when it determines that your positive contributions outweigh those questions which were poorly received.</li> <li><i>3</i>The only way to end a posting block is to positively contribute to the site; automatic bans never expire or "time out".</li> <li><i>4</i>If you see a similar message when trying to post an answer, please see our guidance on what to do about answer bans.</li> <li><i>5</i>Reading your question out loud to yourself can help you understand what it sounds like to others. Here are some additional tips for writing good, useful questions:</li> </ul> </form> </body> </html>
這裏是網頁顯示截圖;
查看搜索效果:
從上圖中能夠看到,有一個搜索框,一個Search的按鈕,一些文本內容,當咱們輸入關鍵詞,能夠按enter 鍵或者點擊Search button.
當若是有搜索結果時,咱們隱藏之前的內容,只顯示搜索結果。
爲何直接在輸入框中按enter鍵能夠工做呢,看這裏代碼;
$('#txtSearch').keypress(function (event) { if (event.keyCode === 13) { $('#btnSearch').trigger('click'); event.stopPropagation(); return false; } });
若是keyCode ===13, 咱們就trigger the button's click method.
若是從數據庫查詢,這個須要用到Freetext in mssql.
而後經過DataTable 綁定到顯示控件,或者用Ajax 綁定到UI.這裏就不列例子了。
歡迎提出不一樣解決方案,期待更好的解決方案。