在项目开展过程中,业主提出页面输入框自带的历史记录功能不能贴合实际使用要求,遂考虑禁用input自带的历史记录功能(autocomplete=“off”),开发一个公用的脚本适用当前需要。
需求如下:
1、历史记录按输入的时间倒序排列;
2、input输入内容变化时,自动匹配;
3、最多展示10条;
实现思路:
1、input输入框获取到焦点后,自动从localStorage中查询相应的数据,匹配输入内容,展示最新10条;
2、input输入框焦点移出后,判断是否移出历史记录选择区域,若超出,则关闭历史记录选择区域,并将输入内容记录到localStorage中(去空、去重);
3、用户在历史记录选择区域中点击选择后,将选择内容赋值到input中,并更新localStorage;
效果如下:
代码如下:
var mouseX;
var mouseY;
$(function () {
// 获取鼠标当前位置
document.onmousemove = function (event) {
if (navigator.userAgent.indexOf('Firefox') >= 0) {
mouseX = event.clientX;//老版的火狐没有x,y
mouseY = event.clientY;//老版的火狐没有x,y
}
else {
mouseX = event.x;
mouseY = event.y;
}
}
$(".historyRecord").focus(function () {
var cookie = getCookie(this.id + "History");
if (this.oninput == null) { // input输入改变时,重新刷新匹配的历史记录
this.oninput = function () {
var cookieNew = getCookie(this.id + "History");
if (cookieNew != null) {
var array = cookieNew.split("|");
if (array.length > 0) {
var matchArray = new Array();
if ($.trim(this.value) != "") {
for (var i = 0; i < array.length; i++) {
if (array[i].indexOf($.trim(this.value)) != -1) {
matchArray.push(array[i]);
}
}
}
else {
matchArray = array;
}
// 最多显示 10 条历史记录
var maxIndex = matchArray.length > 10 ? 10 : matchArray.length;
var showDiv = document.getElementById("div_" + this.id);
if (maxIndex > 0) {
var html = "";
if (showDiv == null) {
var left = getAbsoluteLeft(this.id);
var top = getAbsoluteTop(this.id);
var height = getElementHeight(this.id);
html = "<div class='show_history' id='div_" + this.id + "' style='left: " + left + "px; top: " + (top + height) + "px; " +
"background-color: #fff; border: 1px solid #ccc; border-radius: 4px; padding-top: 6px; padding-bottom: 6px; position: absolute; width: 200px; z-index: 99;'>";
}
for (var i = 0; i < maxIndex; i++) {
html += "<div class='optionDiv' style='height: 30px; line-height: 30px; font-size: 13px; padding-left: 10px; z-index: 100;' οnmοuseοver='divOver(this)' οnmοuseοut='divOut(this)' οnclick='divClick(\"" + this.id + "\", \"" + matchArray[i] + "\")'>" + matchArray[i] + "</div>";
}
if (showDiv == null) {
html += "</div>";
$(this.parentNode).append(html);
}
else {
// 清空原先的历史信息div,添加新的div
document.getElementById("div_" + this.id).innerHTML = "";
$("#div_" + this.id).append(html);
}
}
else if (showDiv != null) { //若已展示历史记录,则删除历史记录展示Div
showDiv.remove();
}
}
}
};
}
//焦点捕获时,根据localstorage显示能够匹配的记录
if (cookie != null) {
var array = cookie.split("|");
if (array.length > 0) {
var matchArray = new Array();
if ($.trim(this.value) != "") {
for (var i = 0; i < array.length; i++) {
if (array[i].indexOf($.trim(this.value)) != -1) {
matchArray.push(array[i]);
}
}
}
else {
matchArray = array;
}
// 最多显示10条历史记录
var maxIndex = matchArray.length > 10 ? 10 : matchArray.length;
if (maxIndex > 0) {
var left = getAbsoluteLeft(this.id);
var top = getAbsoluteTop(this.id);
var height = getElementHeight(this.id);
var html = "<div class='show_history' id='div_" + this.id + "' style='left: " + left + "px; top: " + (top + height) + "px; " +
"background-color: #fff; border: 1px solid #ccc; border-radius: 4px; padding-top: 6px; padding-bottom: 6px; position: absolute; width: 200px; z-index: 99;'>";
for (var i = 0; i < maxIndex; i++) {
html += "<div class='optionDiv' style='height: 30px; line-height: 30px; font-size: 13px; padding-left: 10px; z-index: 100;' οnmοuseοver='divOver(this)' οnmοuseοut='divOut(this)' οnclick='divClick(\"" + this.id + "\", \"" + matchArray[i] + "\")'>" + matchArray[i] + "</div>";
}
html += "</div>";
$(this.parentNode).append(html);
}
}
}
});
$(".historyRecord").blur(function (event) {
var out = true;
var historyDiv = document.getElementsByClassName("show_history");
if (historyDiv.length > 0) {
//根据鼠标当前位置,判断鼠标是否移出输入框及历史记录区域
var x1 = historyDiv[0].offsetLeft;
var y1 = historyDiv[0].offsetTop;
var x2 = historyDiv[0].offsetLeft + historyDiv[0].offsetWidth;
var y2 = historyDiv[0].offsetTop + historyDiv[0].offsetHeight;
var oTop = 0; //父元素定位的Top
var oLeft = 0; //父元素定位的Left
var o = document.getElementsByClassName("show_history")[0];
while (o.offsetParent != null) {
var oParent = o.offsetParent;
oTop += oParent.offsetTop // Add parent Top position
oLeft += oParent.offsetLeft // Add parent Left position
o = oParent
}
if ((mouseX - oLeft) >= x1 && (mouseX - oLeft) <= x2 && (mouseY - oTop) >= y1 && (mouseY - oTop) <= y2) {
out = false
}
else {
$(".show_history").remove();
}
}
// 若移出,记录当前输入值到localStorage中
if (out) {
var cookie = getCookie(this.id + "History");
if (cookie != null) {
var array = cookie.split("|");
if (array != null && array.length > 0) {
if (array[0] != this.value && $.trim(this.value) != "") {
array.remove(this.value);
array.unshift(this.value);
if (array.length > 100) { //设置最多保存100条历史记录
array.pop();
}
setCookie(this.id + "History", array.join("|"));//转成字符串
}
}
else if ($.trim(this.value) != "") {
setCookie(this.id + "History", this.value);
}
}
else if ($.trim(this.value) != "") {
setCookie(this.id + "History", this.value);
}
}
});
});
function divOver(e) { //鼠标滑过,div背景变灰
e.style.backgroundColor = "#ebebeb";
}
function divOut(e) { //鼠标滑出,div背景变白
e.style.backgroundColor = "white";
}
function divClick(id, value) { //鼠标点击
document.getElementById(id).value = value; //e.innerText; //根据点击内容赋值到input中
$("#div_" + id).remove(); //移除历史记录div
$("#" + id).blur();//记录新的历史记录
}
//设置localStorage
function setCookie(name, value) {
var urlSplit = window.location.href.split('?')[0].split('/');//获取页面url, 根据url及name绑定localStorage
localStorage.setItem(urlSplit[urlSplit.length - 1] + "_" + name, value);
}
//获取localStorage
function getCookie(name) {
var urlSplit = window.location.href.split('?')[0].split('/');//获取页面url, 根据url及name绑定localStorage
return localStorage.getItem(urlSplit[urlSplit.length - 1] + "_" + name);
}
//获取控件左绝对位置
function getAbsoluteLeft(objectId) {
o = document.getElementById(objectId);
oLeft = o.offsetLeft;
//while (o.offsetParent != null) {
// oParent = o.offsetParent
// oLeft += oParent.offsetLeft
// o = oParent
//}
return oLeft
}
//获取控件上绝对位置
function getAbsoluteTop(objectId) {
o = document.getElementById(objectId);
oTop = o.offsetTop;
//while (o.offsetParent != null) {
// oParent = o.offsetParent
// oTop += oParent.offsetTop // Add parent top position
// o = oParent
//}
return oTop
}
//获取控件宽度
function getElementWidth(objectId) {
x = document.getElementById(objectId);
return x.offsetWidth;
}
//获取控件高度
function getElementHeight(objectId) {
x = document.getElementById(objectId);
return x.offsetHeight;
}
依赖文件:jquery.cookie.js
版权声明:本文为wxm2106原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。