javascript 需要 HTML5 输入,在提交时滚动到带有固定导航栏的输入
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19814673/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
HTML5 input required, scroll to input with fixed navbar on submit
提问by Augustin Riedinger
When trying to submit a form with missing required fields, my browser (Chrome), displays a message mentionning there is a field missing, and if it's out of my screen, it scrolls up to it.
当尝试提交缺少必填字段的表单时,我的浏览器 (Chrome) 会显示一条消息,指出缺少一个字段,如果它不在我的屏幕上,它会向上滚动到该字段。
My problem is that I have a 50px fixed header in my webpage, and as a result, the input field is hidden, and the message seems to come out of nowhere:
我的问题是我的网页中有一个 50px 的固定标题,因此,输入字段被隐藏,并且消息似乎无处不在:
Instead of
代替
Is there a way around this?
有没有解决的办法?
I tried both applying the 50px margin to <html>
and to <body>
我尝试将 50px 边距应用到<html>
和<body>
Cheers
干杯
EDIT
编辑
Here's a fiddle of the problem: http://jsfiddle.net/LL5S6/1/
这是问题的一个小提琴:http: //jsfiddle.net/LL5S6/1/
采纳答案by ausi
In modern browsersthere is a new CSS property for that use case:
在现代浏览器中,该用例有一个新的 CSS 属性:
html {
scroll-padding-top: 50px;
}
Your JSFiddle updated: http://jsfiddle.net/5o10ydbk/
您的 JSFiddle 已更新:http: //jsfiddle.net/5o10ydbk/
Browser Support for scroll-padding
: https://caniuse.com/#search=scroll-padding
浏览器支持scroll-padding
:https: //caniuse.com/#search=scroll-padding
回答by T.J. Moats
I had the exact same problem and resolved it using jquery with this bit of code:
我遇到了完全相同的问题,并使用 jquery 和这段代码解决了它:
var delay = 0;
var offset = 150;
document.addEventListener('invalid', function(e){
$(e.target).addClass("invalid");
$('html, body').animate({scrollTop: $($(".invalid")[0]).offset().top - offset }, delay);
}, true);
document.addEventListener('change', function(e){
$(e.target).removeClass("invalid")
}, true);
Offset should be the height of your header and delay is how long you want it to take to scroll to the element.
偏移量应该是标题的高度,延迟是您希望滚动到元素所需的时间。
回答by A1rPun
The only way I found is adding an 'override' to the invalid handler. To implement this for every input in your form you can do something like this.
我发现的唯一方法是向无效处理程序添加“覆盖”。要为表单中的每个输入实现这一点,您可以执行以下操作。
var elements = document.querySelectorAll('input,select,textarea');
var invalidListener = function(){ this.scrollIntoView(false); };
for(var i = elements.length; i--;)
elements[i].addEventListener('invalid', invalidListener);
This requires HTML5 and this is tested on IE11, Chrome and Firefox.
Credits to @HenryW for finding that scrollIntoView
works like expected.
这需要 HTML5,并且在 IE11、Chrome 和 Firefox 上进行了测试。
感谢@HenryW 发现它按scrollIntoView
预期工作。
Note that the false parameter for scrollIntoView
aligns the input with the bottom, so if you have a large form it may be aligned with the bottom of the page.
请注意,用于scrollIntoView
将输入与底部对齐的 false 参数,因此如果您有一个大表单,它可能会与页面底部对齐。
jsfiddle
提琴手
回答by Alf Eaton
When there are several invalid inputs in the form, you only want to scroll to the first of them:
当表单中有多个无效输入时,您只想滚动到其中的第一个:
var form = $('#your-form')
var navbar = $('#your-fixed-navbar')
// listen for `invalid` events on all form inputs
form.find(':input').on('invalid', function (event) {
var input = $(this)
// the first invalid element in the form
var first = form.find(':invalid').first()
// only handle if this is the first invalid input
if (input[0] === first[0]) {
// height of the nav bar plus some padding
var navbarHeight = navbar.height() + 50
// the position to scroll to (accounting for the navbar)
var elementOffset = input.offset().top - navbarHeight
// the current scroll position (accounting for the navbar)
var pageOffset = window.pageYOffset - navbarHeight
// don't scroll if the element is already in view
if (elementOffset > pageOffset && elementOffset < pageOffset + window.innerHeight) {
return true
}
// note: avoid using animate, as it prevents the validation message displaying correctly
$('html,body').scrollTop(elementOffset)
}
})
回答by HenryW
ok, i did a dirty test with a code snippet i found here on SO
好的,我用我在 SO 上找到的代码片段做了一个肮脏的测试
As it is a code from someone else, i just alter it to scroll to the element that had a missing input requirement. I do not want any credit for it, and it maybe is not even what you have in mind, you or someone else could use it as a reference.
由于它是来自其他人的代码,我只是将其更改为滚动到缺少输入要求的元素。我不想要任何功劳,它甚至可能不是您的想法,您或其他人可以将其用作参考。
The goal was to get the id of the forgotten/wrong input element:
目标是获取被遗忘/错误输入元素的 id:
var myelement = input.id;
var el = document.getElementById(myelement);
el.scrollIntoView(false);
Please keep in mind that this fiddle only works for your posted fiddle above, it not handles multiple forgotten or wrong input fields.I only wanted to show an alternative.
请记住,这个小提琴只适用于你上面张贴的小提琴,它不能处理多个被遗忘或错误的输入字段。我只想展示一个替代方案。
回答by Abhilash Sharma
You can use oninvalid
event attribute of HTML5 and in your script's tag write a function for redirecting it.
您可以使用oninvalid
HTML5 的 event 属性,并在脚本的标签中编写一个函数来重定向它。
Here is the example:
这是示例:
<input type="text" required oninvalid="scroll_to_validator(this)">
<script>
function scroll_to_validator(input)
{
input.focus();
}
</script>
And on clicking on your submit button it will scroll to the invalid field.
单击您的提交按钮后,它将滚动到无效字段。
For radio button please add only on one radio with same name
Here is the example (jsfiddle)
对于单选按钮,请仅添加一个具有相同名称的收音机
这是示例(jsfiddle)
回答by DaniP
Two solutions:
两种解决方案:
One: apply padding to the body -->
body { padding-top:50px; }
Two : apply margin to the main container -->
#content { margin-top:50px; }
一:给body应用padding -->
body { padding-top:50px; }
二:对主容器应用margin -->
#content { margin-top:50px; }
回答by kibus90
I tried to use the way of T.J. Moats, but it did not work as needed, because I often came back to the field, which was incorrect first.
我尝试使用TJ Moats的方式,但没有按需要工作,因为我经常回到现场,这首先是错误的。
So, I made it:
所以,我做到了:
var navhei = $('header').height();
var navheix = navhei + 30;
document.addEventListener('invalid', function(e){
$(e.target).addClass("invalid");
$('html, body').animate({scrollTop: $($(".invalid")[0]).offset().top - navheix }, 0);
setTimeout(function() {
$('.invalid').removeClass('invalid');
},0300);
}, true);
body {
margin: 0;
margin-top: 50px;
text-align: center;
}
header {
position: fixed;
width: 100%;
height: 50px;
background-color: #CCCCCC;
text-align:center;
top: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.1/jquery.min.js"></script>
<header>This is the header</header>
<div>
<form action="">
<br>
<input id="text" type="text" required="required" /><br><br>
<input id="text" type="text" required="required" /><br><br><br><br>
<input id="text" type="text" required="required" /><br><br>
<input id="text" type="text" required="required" /><br><br><br><br>
<input id="text" type="text" required="required" /><br><br><br><br><br><br>
<input id="text" type="text" required="required" /><br><br>
<p>Click send (at the bottom of the page), without filling the input field.</p><br><br><br><br><br><br>
<input id="text" type="text" required="required" /><br><br>
<input type="submit" id="btnSubmit" />
</form>
</div>
I hope it will be helpfull for people :)
我希望它会对人们有所帮助:)
回答by bluedisk
Here's an EASY and FAST way.
这是一个简单快捷的方法。
$('input').on('invalid', function(e) {
setTimeout(function(){
$('html, body').animate({scrollTop: document.documentElement.scrollTop - 150 }, 0);
}, 0);
});