jQuery实现页面查找以索引题库

安全教育考试题库子页面嵌入博客后,就想着通过前端脚本准确快速地查找和定位,这里有个很好的案例,就是12306的车站订票起售时间查找的页面效果。

所以我要做的功能就是:在搜索框输入题目关键字段后,点击Enter按钮或按Enter键,可以迅速将页面滚动定位到第一个匹配的位置,将关键字高亮,并可以继续匹配下去,同时保持搜索框和按钮在页面顶部,方便继续查找。

关键代码

HTML

主要呈现一个搜索区域#searchBox,包含一个输入框,用来输入要查找的关键字段,以及一个Enter按钮,然后就是前言、使用说明和题库#content

<div id="searchBox">
<input class="textbox" id="searchStr" type="text" size="30" name="searchStr" placeholder="请输入关键字段" /> 
<input class="searchbtn" id="searchBtn" type="button" value="Enter" />
</div>

<div id="content">
<h2>前言</h2>
<hr />
<p>
...
</p>

<h2>使用说明</h2>
<hr />
<p>
...
</p>

<h2>题库</h2>
<hr />

<p>
...
</p>

...

</div>

CSS

简单对页面内容进行了CSS设置,其中.highlight用来设置查找结果高亮显示的样式效果。

p {
line-height: 33px;
}
.highlight {
background: #fff;
color: red;
}
#searchBox {
background: #fff;
opacity: .8;
text-align: right;
}
#searchStr {
width: 300px;
height: 30px;
}
#searchBtn {
background: #0f79be;
margin-top: 6px;
border-radius: 2px;
border: 0;
width: 100px;
line-height: 30px;
color: #fff;
}

jQuery

首先,实现一个固定搜索框和按钮的效果,当页面往下拉滚动时,输入框和按钮始终保持在页面的顶部。

(function($) {
$.fn.fixDiv = function(options) {
var defaultVal = {
top: 10
};

var obj = $.extend(defaultVal, options);
$this = this;
var _top = $this.offset().top;
var _left = $this.offset().left;

$(window).scroll(function() {
var _currentTop = $this.offset().top;
var _scrollTop = $(document).scrollTop();

if (_scrollTop > _top) {
$this.offset({
top: _scrollTop + obj.top,
left: _left
});
} else {
$this.offset({
top: _top,
left: _left
});
}
});

return $this;
};
})(jQuery);

然后,调用fixDiv()

$(function() {
$("#searchBox").fixDiv({
top: 0
});
});

接着,当输入关键字段后,点击Enter按钮或按Enter键,调用函数highlight()

$(function() {
$('#searchBtn').click(highlight);

$('#searchStr').keydown(function(e) {
var key = e.which;
if (key == 13) highlight();
});
});

函数highlight()定义:

function highlight() {
clearSelection(); // 清空上次高亮显示的内容

var flag = 0;
var bStart = true;

var searchText = $('#searchStr').val();
var _searchTop = $('#searchStr').offset().top + 30;
var _searchLeft = $('#searchStr').offset().left;

if ($.trim(searchText) === "") {
showTips("请粘贴文本后再查找", _searchTop, 3, _searchLeft); // 提示信息
return;
}

// 查找匹配
var regExp = new RegExp(searchText, 'g');
var content = $("#content").text();

if (!regExp.test(content)) {
showTips("呀,这道题没有啊,在底部吐槽一下吧", _searchTop, 3, _searchLeft); // 提示信息
return;
} else {
if (sCurText != searchText) {
i = 0;
sCurText = searchText;
}
}

// 高亮显示
$('p').each(function() {
var html = $(this).html();
var newHtml = html.replace(regExp, '<span class="highlight">' + searchText + '</span>');

$(this).html(newHtml);
flag = 1;
});

// 定位
if (flag == 1) {
if ($(".highlight").size() > 1) {
var _top = $(".highlight").eq(i).offset().top + $(".highlight").eq(i).height();
$("#searchBtn").val("查找下一个");
} else {
var _top = $(".highlight").offset().top + $(".highlight").height();
}

$("html, body").animate({ scrollTop: _top - 50 });
i++;

if (i > $(".highlight").size() - 1) {
i = 0;
}
}
}

上述代码中的函数clearSelection()定义如下:

function clearSelection() {
$('p').each(function() {
$(this).find('.highlight').each(function() {
$(this).replaceWith($(this).html());
});
});
}

还有函数showTips()

var tipsDiv = '<div class="tipsClass"></div>';
$('body').append(tipsDiv);

function showTips(tips, height, time, left) {
var windowWidth = document.documentElement.clientWidth;
$('.tipsClass').text(tips);

$( 'div.tipsClass' ).css({
'top': height + 'px',
'left': left + 'px',
'position': 'absolute',
'padding': '8px 6px',
'background': '#000',
'font-size': '14px',
'font-weight': '900',
'margin': '0 auto',
'text-align': 'center',
'width': 'auto',
'color': '#fff',
'border-radius': '2px',
'opacity': '.8',
'box-shadow': '0 0 10px #000'
}).show();

setTimeout(function() {
$('div.tipsClass').fadeOut();
}, (time * 1000));
}

到这里就基本完成了。

jQuery引用报错

编译、部署后,Chrome浏览器调试报错:

(index):7695 Uncaught TypeError: $(...).fixDiv is not a function
(anonymous function) @ (index):7695

我百思不得其解,因为在这之前我已引入了jQuery。后来在Stack Overflow找到了问题所在:

@sholsinger: Check that you’re not loading jQuery into the page twice. Some plugins or plugin libraries like to include jQuery. So it can overwrite your existing jQuery instance and override the $ and jQuery variables with a new – fresh – instance causing existing plugins to be undefined. Plugins are added to the prototype of jQuery when they are defined. So if you destroy the only instance of that object, then the prototype is reset to its original form. And therefore those plugins are no longer part of that prototype.

简单来说就是在上述代码后又加载了一遍jQuery,我一看,果然是,后一个是Hexo编译时引入的,即

<script type="text/javascript" src="/vendors/jquery/index.js?v=2.1.3"></script>

只需要将其注释掉即可。