想实现的效果:当输入框的值为空时,查询按钮的颜色不改变,默认为灰色;当输入值之后,查询按钮颜色改变。
简单来说就是,想让查询按钮的背景颜色根据文本框输入的值动态变化。
想实现的效果图:
未输入时的状态:
输入完成时的效果:
- 问题描述:
今天在做快件查询界面的时候,就遇到这样一个问题:进入页面时查询按钮默认为灰色,获得输入框焦点后,开始输入字符,输入的过程中按钮颜色没有发生变化,只有当输入完内容失去焦点时按钮颜色才会改变。即按钮的颜色不能随着输入框内的值进行动态变化。
无论我怎么修改jQuery代码都不管用,尝试了各种if…else语句的书写也无法实现,一直认为是自己逻辑方面的问题,还专门思考了很久,依旧没改变。最后决定去学习交流群里向大神们请教,于是,进行了简单的问题描述,并贴了代码和图片上去。有人提出让我去搜索有关“实时监听input输入框值”的文章,我没在意,还固执的认为就是自己逻辑出问题了才无法实现效果。
/*
最初的想法:觉得刚开始输入框的值有三种情况:
(1)刚进入页面时,输入框的值肯定为空(此时未获取焦点);【灰色按钮】
(2)点击了输入框未输入内容(此时获取了焦点);【灰色按钮】
点击了输入框输入了内容(此时获取了焦点);【蓝色按钮】
(3)未输入内容之后又点击了其他元素(此时失去焦点)【灰色按钮】
输入了内容之后又点击了其他元素(此时失去焦点)【蓝色按钮】
*/12345678
- 代码实现:
最开始自己的代码如下所示:
HTML代码:
<div class="search">
<input class="input-num" type="text" placeholder="请输入要查询的单号">
<a href="javascript:;"><img class="icon-scan" src=""></a><!--输入框最右侧绝对定位的扫描icon,不用管这个标签,直接忽视-->
<input class="btn-search" value="查询" type="button">
</div>12345
jQuery代码1:
思路1:
//当输入框获取焦点时
$(".input-num").focus(function(event) {
//如果输入框的值不为空
if($(".input-num").val() !== ""){
//改变查询按钮的颜色为蓝色
$(".btn-search").css('background-color', '#30a5ff');
}else{
//为空,默认灰色显示
$(".btn-search").css('background-color', '#a4a4a4');
}
});
//当输入框失去焦点时
$(".input-num").blur(function(event) {
//如果输入框的值不为空
if($(".input-num").val() !== ""){
//改变查询按钮的颜色为蓝色
$(".btn-search").css('background-color', '#30a5ff');
}else{
//为空,默认灰色显示
$(".btn-search").css('background-color', '#a4a4a4');
}
});1234567891011121314151617181920212223
效果如下所示:
jQuery代码2:
思路2:
//先判断输入框的值是否为空 【后来补充:其实不用判断,除非人为设置,要不然肯定为空】
if($(".input-num").val() == ""){
//如果为空,获取输入框焦点(方便输入不用人为再点击一次),并重置默认的灰色
$(".input-num").focus();
$(".btn-search").css('background-color', '#a4a4a4');
}//【新注释:这里不存在else的情况,因为刚进页面输入框不可能有内容】
//再判断输入完内容失去焦点的情况
$(".input-num").blur(function(event) {
//如果仅仅只是点击了输入框未输入内容,即获取了焦点后又释放了
if($(".input-num").val() == ""){
//让它重新获得焦点。只要输入框是空值,就自动获取焦点
$(".input-num").focus();
//空值,重置默认的灰色
$(".btn-search").css('background-color', '#a4a4a4');
//如果在输入框内输入了内容
}else if($(".input-num").val() != ""){
//改变按钮颜色为蓝色
$(".btn-search").css('background-color', '#30a5ff');
}
});
});12345678910111213141516171819202122
其实效果和上面一样,只是判断条件的顺序不同而已:
jQuery代码3:
思路3:
//刚进入页面时,文本框肯定是没有获得焦点的(默认没有人为设置),此时就进行判断
if(!$(".input-num").focus())
//文本框无焦点且值为空
if($(".input-num").val() == ""){
//肯定颜色默认灰色不变
$(".btn-search").css('background-color', '#a4a4a4');
/*但要是此时,文本框内有值呢?
(那肯定不是刚进页面时输入的,这个值肯定是后来输入的内容。也就是点击了其他元素失去焦点后,又重新点击文本框获得新的焦点)*/
【新注释:这种情况不存在,真不知道之前是怎么想的。方法现在只可能顺序执行一次,是不存在执行完一次后返回来再执行的。最初的时候,可能自己认为focus方法能反复地被触发,现在我只能说:确实是想太多了!感觉自己太low了。】
}else if($(".input-num").val() != ""){
//文本框有值就直接让按钮变为蓝色
$(".btn-search").css('background-color', '#30a5ff');
//如果刚进入页面输入框就获得了焦点(除非人为设置),而且文本框的值为空 。
【新注释:这种情况不存在,之前写在下面的代码都是废话,直接跳过】
}else if($(".input-num").val() == ""){
//值为空,按钮默认灰色不变
$(".btn-search").css('background-color', '#a4a4a4');
}else{
//不为空当然就是蓝色了
$(".btn-search").css('background-color', '#30a5ff');
}
【新注释:没有判断失去焦点的情况,其实写不写blur都一样,不写什么效果都没有,写了和上面的效果一模一样。】1234567891011121314151617181920212223
小结:
到现在为止,总共测试和调整了3次代码,还是感觉是逻辑哪里没理清,然后就一直在jQuery
文档各种寻找相关的焦点事件。因为自己js
本来学的就不好,jQuery也忘得差不多了,心想:肯定是自己方法写的有问题才导致这样的结果,因此才花费了大量的时间用于寻找事件和测试方法。折腾了这么久,不但把自己弄得很烦,而且将时间都白白浪费掉了,感觉很不值得!
下面的这个方法自己最后尝试的一个了,因为在jQuery文档中又发现了两个我没用过的新方法:focusin()
和focusout()
,就准备再做一下最后的挣扎,当时感觉应该有戏了,就把希望寄托在它们身上了。结果,可想而知……
jQuery代码4:
思路4:
//当元素获得焦点时,会触发 focusin 事件。
$(".input-num").focusin(function(){
//获得焦点后立马判断值是否为空
if($(this).val() != ""){
//不为空,很好,按钮变色;为空改为灰色
$(".btn-search").css('background-color', '#30a5ff');
}else
$(".btn-search").css('background-color', '#a4a4a4');
});
//当元素失去焦点时会触发 focusout 事件。
$(".input-num").focusout(function(){
//此时只要判断失去焦点时文本框是否有值,有值的话就让按钮变色,反之就改为灰色显示。
if($(this).val() != ""){
$(".btn-search").css('background-color', '#30a5ff');
}else
$(".btn-search").css('background-color', '#a4a4a4');
});123456789101112131415161718
MMP,搞了这么久,跟刚开始的实现效果都一样。
虽然可以变色,但是共同特点都是:每次只能是在输入框失去焦点的时候变色。还是没有做到焦点还位于输入框时就同步变色的效果。从下图很明显就可以看到。
- 纯属闲聊(自行跳过即可)
上面写的所有代码全部作废,全都是无用功,浪费了这么多时间都没有得到自己想要的结果,js是应该好好学了,走马观花式的学习肯定是不行了,所以才觉得要开通CSDN博客,记录自己的学习点滴,踩过的坑,分享自己学习过程中获得的方法、技巧、经验等。其实,刚上大学时导员就让我们每个人开通一个博客,这样做会给以后找工作带来特别大的帮助,但是由于自己自制力不行,特别贪玩,打了四年LOL,花费了大量的时间在游戏上,现在回想感觉真的特别后悔。真的,多说无用,都成为历史了,说了也回不去了,现在做的只能是勉励自己,把曾经荒废的、失去的都自己弥补回来。扯远了,不提这个了,接下来,让我们继续吧。
- 迷途知返
后来在问题交流中,他告诉我:事件还能反复的触发?你加了什么定时器监听器特殊条件?我渐渐意识到可能就是这个问题,于是马上去问度娘,最终得到了答案:必须实时监听输入框值的变化。当输入框的值改变的同时,此时判断要不要做一些事情,而不是等到输入框的内容输入完成后,再等到它失去焦点的时候分开来判断。其实,这根本与失不失去焦点没有半毛钱的关系,都是在输入内容的同时进行判断的。这才恍然大悟,瞬间想起了以前学select
标签时用过的onchange
事件(现在早忘了怎么用),心想应该和这个同理。
于是,就发现了这两个事件:oninput
和onporpertychange
事件。(感觉好陌生,见都没见过)
先简单介绍一下这两个事件吧。
oninput
事件【HTML5的新事件】
当用户向<input>
和<textarea>
中尝试输入时会触发此方法。
也就是当输入框input的值发生改变时触发事件(每增加或删减字符时就会触发,是实时的)。
兼容性比较好,支持大多数浏览器,当然,除了IE(IE9以下不支持此方法)。
因此,IE特有的onpropertychange
事件将会在下面闪亮登场。
代码如下:
<input type="text" oninput="function()">1
或
$("element").on("input",function,false);1
ps:
这个事件还真的和onchange
事件很相似。
时间原因,就不详细写了。
三个事件的区别如下:
-
onchange
事件:在元素内容改变且失去焦点时触发;还可以作用于select元素。【无法做到实时监听】
但是通过js改变属性时无法触发该事件(区别于onpropertychange
事件)。 -
oninput
事件:在元素的值发生改变时立即触发,实时感应值的动态变化。通过js改变的值无法触发。
也同时监听了鼠标右键操作。【复制粘贴也有效】 -
onpropertychange
事件:【IE专属】实时触发;只要绑定元素的相关属性值(不仅仅指value值,也包括其他值)改变都会触发。除非元素被设置了 readonly属性(只读)和 disabled 属性。
最后,仅仅用了一个方法就搞定了。
方法:在元素上同时绑定 oninput 和onpropertychange事件
/*为了让输入框的内容达到规定的长度时,才允许点击按钮查询*/
$(".btn-search").on('click', function() {
//判断一下输入框的值是什么类型的
console.log( typeof( $(".input-num").val() ) );//经测试得出,不管输入什么都是string类型
//获取到输入框值的长度
console.log($(".input-num").val().length);
});
// 实时监听输入框的变化
$(".input-num").on('input propertychange',function(){
//输入框的值不为空 且 输入的数字达到13位 方可解锁按钮
if($(this).val() !== "" && $(this).val().length == "13")
$(".btn-search").css('background-color', '#30a5ff');
else
$(".btn-search").css('background-color', '#a4a4a4');
});12345678910111213141516
最终实现的效果图1 如下图所示:
if($(this).val() !== "") 1
最终实现的效果图2 如下图所示:
if($(this).val() !== "" && $(this).val().length == "13")1
总结:
四字即可,多说无益。言简意赅,知易行难!