提问人:Freddan 提问时间:7/18/2023 最后编辑:Freddan 更新时间:11/5/2023 访问量:54
仅当输入没有错误时才关闭搜索叠加
Close Search overlay only if inputs have no error
问:
我正在尝试开发一个全屏搜索字段,并希望橙色的“搜索”按钮仅在所有输入都有效时关闭覆盖。
每个输入限制为 2 位数字,只有数字,介于 1 到 20 之间。 一切正常,除了“搜索”按钮在最后一个输入有效时关闭覆盖层,即使前 2 个输入留空(错误)......
是否有任何冲突或脚本错误?
$(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>
答:
1赞
Velimir Tchatchevsky
7/18/2023
#1
您正在为每个输入字段运行该函数,因此当最后一个字段有效时,它将隐藏叠加层 - 这就是发生的事情。在循环外部创建一个新变量,并使用它来跟踪是否有任何输入字段无效,然后在循环之后根据需要使用该值隐藏元素。
2赞
Codemaster United
7/18/2023
#2
首先,问题是因为您正在逐个检查值。因此,最终最后一个输入的值将生效。此外,您不应该添加然后检查输入是否不包含数字以外的任何内容。这是完全没有必要的,只需添加到所有输入中,它就只允许数字输入。大多数代码只是一次又一次地进行双重检查和同样的事情。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>
评论
1赞
Freddan
7/18/2023
这太棒了,这正是我想要实现的目标,非常感谢曼联@Codemaster。完整脚本还包括从剪贴板复制/粘贴数字(删除空格、“.”、“、”等)并将其拆分到所有输入中的功能。我在Firefox上遇到了许多冲突,它将数字粘贴到一个唯一的输入中而不拆分它,因此不尊重maxlength。我发现的唯一折衷方案是切换回 type=“text”,只接受数字
评论