我正在尝试开发一个全屏搜索字段,并且希望橙色“搜索”按钮仅在所有输入都有效时才关闭叠加层。
每个输入的数字限制为 2 位,仅限数字且介于 1 到 20 之间。 一切正常,除了当最后一个输入有效时“搜索”按钮会关闭覆盖,即使前两个输入留空(错误)....
有冲突或者脚本错误吗?
$(function() {
$('a[href="#search"]').on("click", function(event) {
event.preventDefault();
$("#search").addClass("open");
$('#search > form > input[type="search"]').focus();
});
$("#search, #search button.close").on("click keyup", function(event) {
if (
event.target == this ||
event.target.className == "close" ||
event.keyCode == 27
) {
$(this).removeClass("open");
}
});
$(".send_btn").submit(function(event) {
event.preventDefault();
return false;
});
});
// validation input - error if not..
function handleChange(input) {
if (input.value < 0) input.value = "";
else if (input.value < 0.9 || input.value > 20 || input.value.length === 1 || input.value.length === 0) {
input.style.borderColor = 'red';
} else {
input.style.borderColor = '';
}
}
$('input').keypress(function(event) {
event = event || window.event;
var charCode = event.which || event.keyCode;
var charStr = String.fromCharCode(charCode);
if (event.key !== undefined && event.charCode === 0) {
return;
}
if (!/^([0-9])*$/.test(charStr)) {
event.preventDefault();
}
if (!/^[a-zA-Z0-9]+$/.test(charStr)) {
event.preventDefault();
}
});
// If input is empty Send Button Click - error - no action
$('.send_btn').click(function() {
$("input.each_item").each(function() {
if (this.value.trim().length === 0 || this.value.trim().length === 1 || this.value > 20)
$(this).css('border-color', 'red') &&
$('#search').addClass('open') &&
$('html').addClass("noScrollSimple");
else
$(this).css('border-color', '') &&
$('#search').removeClass('open') &&
$('html').removeClass("noScrollSimple");
});
});
html {
overflow-y: scroll;
}
body {
margin: 0px;
font-weight: 400;
font-size: 12px;
-webkit-font-smoothing: antialiased;
width: 100%;
min-width: auto;
background: #ebebeb;
padding: 50px;
}
.button {
width: 250px;
height: 50px;
color: #ebebeb;
background-color: cornflowerblue;
margin: 0 auto;
text-align: center;
font-size: 2.3em;
margin-top: 50px;
font-size: 2.3em;
cursor: pointer;
}
.input_cont {
display: inline-block;
width: 100%;
margin: 0px auto;
text-align: center;
max-width: 1250px;
}
.items {
display: flex;
flex: 1;
padding: 0px 20px 0px;
}
.each_item {
width: 100px;
height: 100px;
min-width: 100px;
min-height: 100px;
line-height: 2.75em;
margin: 0px auto;
display: table-cell;
float: left;
font-weight: bold;
color: #ebebeb;
font-size: 2.3em;
background: rgba(0, 0, 0, .6);
text-align: center;
-webkit-appearance: none;
}
#search {
position: fixed;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-color: rgba(50, 50, 50, .9);
-webkit-transform: translate(-50%, -50%) scale(0, 0);
-moz-transform: translate(-50%, -50%) scale(0, 0);
-o-transform: translate(-50%, -50%) scale(0, 0);
-ms-transform: translate(-50%, -50%) scale(0, 0);
transform: translate(-50%, -50%) scale(0, 0);
opacity: 0;
}
#search input[type=search] {
color: #ebebeb;
background: rgba(0, 0, 0, 0);
font-weight: 300;
text-align: center;
border: 0px;
margin: 0px auto;
margin-top: -51px;
padding-left: 30px;
padding-right: 30px;
outline: none;
}
#search .btn {
background: chocolate;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
border: 0px solid transparent;
}
#search .close {
position: fixed;
top: 15px;
right: 15px;
opacity: 1;
width: 50px;
height: 50px;
}
#search .close:after {
content: '';
height: 45px;
border-left: 5px solid #ebebeb;
position: absolute;
transform: rotate(45deg);
left: 28px;
}
#search .close:before {
content: '';
height: 45px;
border-left: 5px solid #ebebeb;
position: absolute;
transform: rotate(-45deg);
left: 28px;
}
#search.open {
-webkit-transform: translate(-50%, -50%) scale(1, 1);
-moz-transform: translate(-50%, -50%) scale(1, 1);
-o-transform: translate(-50%, -50%) scale(1, 1);
-ms-transform: translate(-50%, -50%) scale(1, 1);
transform: translate(-50%, -50%) scale(1, 1);
opacity: 1;
}
#search,
#search.open {
-webkit-transition: all .35s;
-moz-transition: all .35s;
-ms-transition: all .35s;
-o-transition: all .35s;
transition: all .35s;
transition-property: initial;
transition-duration: 0.35s;
transition-timing-function: initial;
transition-delay: initial;
}
.search__input {
width: 100%;
height: 100%;
background: transparent;
outline: none;
color: #ebebeb;
transition: opacity 0s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="#search">
<div class="button">
Search</div>
</a>
<div id="search">
<div type="button" class="close"></div>
<div class="input_cont">
<div class="items">
<input name="num" type="text" min="1" max="20" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" class="search__input each_item" placeholder="00" />
<input name="num" type="text" min="1" max="20" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" class="search__input each_item" placeholder="00" />
<input name="num" type="text" min="1" max="20" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" class="search__input each_item" placeholder="00" />
</div>
</div>
<button type="submit" class="button btn btn-primary send_btn">Search</button>
</div>
首先,问题是因为你正在逐一检查该值。所以,最后输入的值生效了。另外,您不应该添加
type="text"
,然后检查输入是否不包含数字以外的任何内容。完全没有必要,只需在所有输入中添加 type="number"
即可仅允许数字输入。大多数代码只是一次又一次地进行双重检查和相同的事情。
我已经清理了不必要的部分,现在它工作得很好,就像你想要的 -
这是代码
$(function() {
$('a[href="#search"]').on("click", function(event) {
event.preventDefault();
$("#search").addClass("open");
$('#search > form > input[type="search"]').focus();
});
$("#search, #search button.close").on("click keyup", function(event) {
if (
event.target == this ||
event.target.className == "close" ||
event.keyCode == 27
) {
$(this).removeClass("open");
}
});
$(".send_btn").submit(function(event) {
event.preventDefault();
return false;
});
});
// Added return statements
function handleChange(input) {
if (input.value < 0) input.value = "";
else if (input.value < 0.9 || input.value > 20 || input.value.length === 1 || input.value.length === 0) {
input.style.borderColor = 'red';
return false;
} else {
input.style.borderColor = '';
return true;
}
}
// Verify results for each inputs
$('.send_btn').click(function() {
var result = [];
$('.search__input').each(function() {
result.push(handleChange(this));
});
if (!result.includes(false)) { // Check if all inputs are valid
$('#search').removeClass('open');
$('html').removeClass("noScrollSimple");
}
});
html {
overflow-y: scroll;
}
body {
margin: 0px;
font-weight: 400;
font-size: 12px;
-webkit-font-smoothing: antialiased;
width: 100%;
min-width: auto;
background: #ebebeb;
padding: 50px;
}
.button {
width: 250px;
height: 50px;
color: #ebebeb;
background-color: cornflowerblue;
margin: 0 auto;
text-align: center;
font-size: 2.3em;
margin-top: 50px;
font-size: 2.3em;
cursor: pointer;
}
.input_cont {
display: inline-block;
width: 100%;
margin: 0px auto;
text-align: center;
max-width: 1250px;
}
.items {
display: flex;
flex: 1;
padding: 0px 20px 0px;
}
.each_item {
width: 100px;
height: 100px;
min-width: 100px;
min-height: 100px;
line-height: 2.75em;
margin: 0px auto;
display: table-cell;
float: left;
font-weight: bold;
color: #ebebeb;
font-size: 2.3em;
background: rgba(0, 0, 0, .6);
text-align: center;
-webkit-appearance: none;
}
#search {
position: fixed;
top: 50%;
left: 50%;
width: 100%;
height: 100%;
padding: 0;
margin: 0;
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
background-color: rgba(50, 50, 50, .9);
-webkit-transform: translate(-50%, -50%) scale(0, 0);
-moz-transform: translate(-50%, -50%) scale(0, 0);
-o-transform: translate(-50%, -50%) scale(0, 0);
-ms-transform: translate(-50%, -50%) scale(0, 0);
transform: translate(-50%, -50%) scale(0, 0);
opacity: 0;
}
#search input[type=search] {
color: #ebebeb;
background: rgba(0, 0, 0, 0);
font-weight: 300;
text-align: center;
border: 0px;
margin: 0px auto;
margin-top: -51px;
padding-left: 30px;
padding-right: 30px;
outline: none;
}
#search .btn {
background: chocolate;
outline: none;
-webkit-appearance: none;
-moz-appearance: none;
-ms-appearance: none;
-o-appearance: none;
appearance: none;
border: 0px solid transparent;
}
#search .close {
position: fixed;
top: 15px;
right: 15px;
opacity: 1;
width: 50px;
height: 50px;
}
#search .close:after {
content: '';
height: 45px;
border-left: 5px solid #ebebeb;
position: absolute;
transform: rotate(45deg);
left: 28px;
}
#search .close:before {
content: '';
height: 45px;
border-left: 5px solid #ebebeb;
position: absolute;
transform: rotate(-45deg);
left: 28px;
}
#search.open {
-webkit-transform: translate(-50%, -50%) scale(1, 1);
-moz-transform: translate(-50%, -50%) scale(1, 1);
-o-transform: translate(-50%, -50%) scale(1, 1);
-ms-transform: translate(-50%, -50%) scale(1, 1);
transform: translate(-50%, -50%) scale(1, 1);
opacity: 1;
}
#search,
#search.open {
-webkit-transition: all .35s;
-moz-transition: all .35s;
-ms-transition: all .35s;
-o-transition: all .35s;
transition: all .35s;
transition-property: initial;
transition-duration: 0.35s;
transition-timing-function: initial;
transition-delay: initial;
}
.search__input {
width: 100%;
height: 100%;
background: transparent;
outline: none;
color: #ebebeb;
transition: opacity 0s;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<a href="#search">
<div class="button">
Search</div>
</a>
<div id="search">
<div type="button" class="close"></div>
<div class="input_cont">
<div class="items">
<input name="num" type="number" min="1" max="20" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" class="search__input each_item" placeholder="00" />
<input name="num" type="number" min="1" max="20" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" class="search__input each_item" placeholder="00" />
<input name="num" type="number" min="1" max="20" minlength="2" maxlength="2" oninput="if((this.value.length) > 2) {this.value = this.value.substring(0, 2);}" onchange="handleChange(this);" class="search__input each_item" placeholder="00" />
</div>
</div>
<button type="submit" class="button btn btn-primary send_btn">Search</button>
</div>
您正在为每个输入字段运行该函数,因此当最后一个输入字段有效时,它将隐藏覆盖层 - 这就是发生的情况。在循环外部创建一个新变量,并使用它来跟踪是否有任何输入字段无效,然后在循环之后使用该值根据需要隐藏元素。