需求背景
项目中拿过来外包的代码是用小程序跳转H5页面,H5页实现开票功能。现需要在开票处用户输入的发票抬头添加动态搜索,将可能的结果进行匹配,用户点击后将抬头和税号一并写入H5的对应input中。如图所示:
实现过程
作为一个前端cv工程师,先去google了下有没有现成的可以用的代码,于是乎搜到了一个第一次听说的标签,它可以直接配合input实现动态地将匹配结果展示出来。这不巧了么,正是我需要的。于是乎:
<input autocomplete="off" type="text" placeholder="请输入" id="textarea" list="typelist" class="inputLabel" />
<datalist id="typelist"></datalist>
然后js中利用jQuery绑定监听事件:
_view.find('#textarea').on("input", async () => {
if ($("#textarea")[0].value == '') { // 抬头清空,税号一起清空
$('.Js_DutyParagraph')[0].value = '';
return;
}
let _postData = { taxName: $("#textarea")[0].value };
//请求企业列表
let company = await Apier.getCompany(_postData); // 封装的post请求
if (company.IsSuccess == 1 && company.data) { // 确保用户输入能获取到data返回值再加载选项
let data = company.data;
_view.find('.listOption').remove(); // 删除之前的选项
for (let i = 0; i<data.length; i++) { // 添加新选项
$('#typelist').append(`<option class="listOption" value="${data[i].taxName}">${data[i].taxId}</option>`);
}
let op = $(".listOption");
for (let i = 0; i < op.length; i++) { // 自动填充税号
if (op[i].value == $("#textarea")[0].value) {
$('.Js_DutyParagraph')[0].value = op[i].outerText;
}
}
}
}
用Chrome打开小程序里跳转拼接的h5链接,调用接口,查看控制台。完美实现~正打算交差,打开开发者工具,输入随机字,等待接口返回搜索结果展示...1s...2s...3s,啥也没有。
查了一下,发现是小程序内不支持展示datalist的写法,造孽啊,白兴致冲冲的玩了半天。
第一时间是去看了下网上各种经验,如何能够兼容datalist,翻到了微信小程序论坛里也有人提问,但下面并没有一条可行的解决方法。于是乎又尝试引入Vue,使用elementui去实现。但是h5这里webpack打包的代码不能将vue的引入带入,且el组件无法展示,遂放弃。
没办法,只能自行实现,最终实现代码附在下面,因为之前已经有datalist的代码,因此纯h5 div实现比想象中简单很多。
<div class="drawBillBox re">
<div class="title">税号</div>
<input type="text" placeholder="请输入企业纳税人识别号" class="inputLabel Js_DutyParagraph" />
<div style="display: flex;justify-content:center;position:absolute;width: 100%;top: 0;">
<div id="compList" style="display: none;position:absolute;top:0;min-width:200px;background-color:rgb(255, 255, 255);padding: 0 10px;z-index: 1;box-shadow: 0px 0px 3px #646464"></div>
</div>
</div>
_view.find('#textarea').on("input", async () => {
if ($("#textarea")[0].value == '') {
$('.Js_DutyParagraph')[0].value = '';
_view.find('.listOption').remove(); // 清空并隐藏div
$('#compList').css('display','none');
return;
}
let _postData = { taxName: $("#textarea")[0].value };
//请求企业列表
let company = await Apier.getCompany(_postData);
if(company.IsSuccess == 1 && company.data){
_view.find('.listOption').remove();
let data = company.data;
for (let i = 0; i < data.length; i++) { // 用带样式的div展示数据
$('#compList').append(`<div class="listOption" style="margin: 10px 0;">
<div class="c1" style="font-size:22px;color:#646464;margin:15px 0 5px 0;">${data[i].taxName}</div>
<div class="c2" style="display:none;">税号: ${data[i].taxId}</div>
</div>`);
}
$('#compList').css('display','block'); // 拿到数据后展示
$(".listOption").click(function(){ // 这里不用箭头函数,因为需要让this只想当前的dom元素
let company = $(this).children(".c1")[0].innerText;
let code = $(this).children(".c2")[0].innerText.split(":")[1].trim(); // 拿到html文本的税号部分,然后去掉空格
$('.Js_InvoiceTitle')[0].value = company;
$('.Js_DutyParagraph')[0].value = code;
$('#compList').css('display','none'); // 选中后将pop层隐藏
});
}
}
最终实现效果展示在开头的图片。