在项目开展过程中,业主提出页面输入框自带的历史记录功能不能贴合实际使用要求,遂考虑禁用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,ymouseY = 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,添加新的divdocument.getElementById("div_" + this.id).innerHTML = "";$("#div_" + this.id).append(html);}}else if (showDiv != null) { //若已展示历史记录,则删除历史记录展示DivshowDiv.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; //父元素定位的Topvar oLeft = 0; //父元素定位的Leftvar o = document.getElementsByClassName("show_history")[0];while (o.offsetParent != null) {var oParent = o.offsetParent;oTop += oParent.offsetTop  // Add parent Top positionoLeft += oParent.offsetLeft  // Add parent Left positiono = 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绑定localStoragelocalStorage.setItem(urlSplit[urlSplit.length - 1] + "_" + name, value);
}//获取localStorage
function getCookie(name) {var urlSplit = window.location.href.split('?')[0].split('/');//获取页面url, 根据url及name绑定localStoragereturn 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

input输入框自定义历史记录相关推荐

  1. input输入框去除历史记录

    input输入框去除历史记录 input输入框的历史记录很烦人,都是一些测试用的值,但是清除cookie都去不掉 找了好久,发现社区大多数都是添加一个属性值来禁止输入框的出现,从而达到想要的效果,但是 ...

  2. HTML Input输入框自定义required的提示内容(默认值:请填写此字段)

    在input输入框中添加oninvalid和oninput属性 <input type="text" required="required" oninva ...

  3. 清空input输入框的历史记录

    添加autocomplete属性,autocomplete="off" <input class="form-control" type="te ...

  4. React:input输入框只能输入英文和特殊字符(可以自定义限制)

    React:input输入框只能输入英文和特殊字符(可以自定义限制) 直接上代码: antd3.x版本 render(){return (<Form.Item>{getFieldDecor ...

  5. Input输入框的失焦

    最近遇到一个需求:需要点击输入框后,出现下拉选项,且下拉选项的内容以树结构展示,如图 其中遇到一个棘手的问题,在输入框失去焦点时,下拉选项框需要隐藏, 这意味着当我准备点击树节点时,整个下拉选项框就被 ...

  6. 弹出框动态增加input输入框

    欢迎关注微信公众号: 程序员小圈圈 原文首发于: www.zhangruibin.com 本文出自于: RebornChang的博客 转载请标明出处^_^ 弹出框动态增加input输入框 最近项目上有 ...

  7. css3搜索框呼出键盘,移动端 input 输入框实现自带键盘“搜索“功能并修改X

    主要利用html5的,input[type=search]属性来实现,此时input和type=text外观和功能没啥区别: html代码入下: 但要实现点击键盘右下角搜索,来发送请求,js代码如下( ...

  8. js实现input输入框内容自动格式化工具-Cleave.js使用教程

    Cleave.js是一个帮助表单实现各种复杂实时格式化显示的工具库,可以说Cleave.js让表单的输入变得更加的高逼格,能实现很多复杂的表单格式化显示,简而言之就是针对 <input> ...

  9. html输入框初始输入法,【报Bug】input输入框聊天页面,如果输入法默认是全屏手写,input会被挡住,这个能解决吗?...

    ## 详细问题描述 (DCloud产品不会有明显的bug,所以你遇到的问题大都是在特定环境下才能重现的问题,请仔细描述你的环境和重现方式,否则DCloud很难排查解决你的问题) [内容] 客户是用的这 ...

  10. html 文本框赋值日期代码,如何获取到input输入框 中date的当前日期

    如何获取到input输入框 中date的当前日期 开发工具与关键技术:Visual Studio 2015 作者:徐晶旗 撰写时间:2019年6月8日 首先input是表单中的一种元素,所以接下来先给 ...

最新文章

  1. 第 7 章 项目运作
  2. 深入浅出grep与正则表达式
  3. java 圈复杂度_关于Java:降低Switch语句的循环复杂度-Sonar
  4. POE交换机供电原理及工作过程
  5. bool与string互转
  6. Java和pathion_Spring配置中的classpath:与classpath*:的区别
  7. RabbitMQ安装---rpm安装
  8. 51Nod-1050 循环数组最大段和【最大子段和+最小子段和+DP】
  9. 4.软件架构设计:大型网站技术架构与业务架构融合之道 --- 操作系统
  10. 小米球(Ngrok)实现内网穿透,让外网可以进行访问本地部署的 API
  11. android汉字转拼音
  12. 锐捷EG易网关与NBR路由器命令执行漏洞-2
  13. 彐一夕儿本铺_2019-10-16汉字宫目录
  14. 编译小程序,开发者工具打开报错Cannot read property ‘createTextNode‘ of undefined或iphone机型无法预览
  15. Spring详解一号IOC京都大火篇
  16. 面试题67. 把字符串转换成整数
  17. win7防火墙规则设置
  18. 产品说接口返回数据需要脱敏 只能安排
  19. 深入理解Image.createImage()
  20. ei加声调怎么加_ei的四个声调怎么写

热门文章

  1. 电脑正常联网,提示无法登录微信
  2. 黑色脸谱_上演三幕的脸谱剧
  3. 【速记】英语多个形容词(定语)搭配规则
  4. Python生信练习
  5. 生信分析电脑推荐_生信工程师的个人计算机配置推荐
  6. SLAM 中evo的使用(二) (evaluation of odometry) evo_traj/ape rpe/evo_ape说明与示例
  7. simulink中对powergui的使用
  8. python3 使用writerows写入csv时有多余空行的处理办法
  9. python获取实时基金数据_Python实现基金实时净值抓取
  10. 如何提高自制力?自制力差怎么办?