【问题标题】:HTML5 input required, scroll to input with fixed navbar on submit需要 HTML5 输入,在提交时滚动到带有固定导航栏的输入
【发布时间】:2013-11-17 20:14:00
【问题描述】:

当尝试提交缺少必填字段的表单时,我的浏览器 (Chrome) 会显示一条消息,指出缺少一个字段,如果它不在我的屏幕上,它会向上滚动。

我的问题是我的网页中有一个 50px 的固定标题,结果输入字段被隐藏了,并且消息似乎无处不在:

代替

有没有办法解决这个问题?

我尝试将 50px 边距应用到 <html><body>

干杯


编辑

这里有一个问题:http://jsfiddle.net/LL5S6/1/

【问题讨论】:

  • 遇到了同样的问题,可惜没有人想出解决办法。
  • 我认为我们需要将required="required" html 属性视为目前不稳定的东西......它使用起来很棘手,兼容性不高,并且仍然有像这样的副作用......
  • 使用 Chrome 版本 37.0.2062.120 它可以像你想要的那样工作。你试过了吗?
  • 试试这个:jsfiddle.net/LL5S6/46

标签: javascript css html


【解决方案1】:

我遇到了完全相同的问题,并使用 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);

偏移量应该是标题的高度,延迟是您希望滚动到元素所需的时间。

【讨论】:

  • 正是我需要的!但请注意:如果您使用延迟 > 0,则浏览器消息“请填写此字段”将在滚动开始时消失(因此仅在几毫秒内可见)
  • IMO 这个解决方案是错误的,因为根据developer.mozilla.org/en-US/docs/Web/Events/invalid 'invalid' 事件不会冒泡
【解决方案2】:

我发现的唯一方法是向无效处理程序添加“覆盖”。 要为表单中的每个输入实现此功能,您可以执行以下操作。

var elements = document.querySelectorAll('input,select,textarea');
var invalidListener = function(){ this.scrollIntoView(false); };

for(var i = elements.length; i--;)
    elements[i].addEventListener('invalid', invalidListener);

这需要 HTML5,并且在 IE11、Chrome 和 Firefox 上进行了测试。
感谢@HenryW 发现scrollIntoView 按预期工作。

请注意scrollIntoView 的 false 参数会将输入与底部对齐,因此如果您的表单较大,它可能会与页面底部对齐。

jsfiddle

【讨论】:

  • 谢谢@HenryW 我会把它添加到答案中。
  • 相当不错!虽然浏览器调试会更好!
  • scrollIntoView 不适用于页面顶部的固定定位标题。
  • @feeela 它解决了 OP 的问题,它有一个固定定位的标题。您能否具体说明一下不起作用
  • 如果有多个无效输入,这将不起作用,因为它将滚动到最后一个无效输入,然后浏览器将滚动回顶部的第一个并被固定导航栏隐藏。应该有一种方法可以仅为第一个无效输入执行 scrollIntoView 但我不知道如何。
【解决方案3】:

modern browsers 中有一个用于该用例的新 CSS 属性:

html {
    scroll-padding-top: 50px;
}

您的 JSFiddle 已更新:http://jsfiddle.net/5o10ydbk/

浏览器支持scroll-padding:https://caniuse.com/#search=scroll-padding

【讨论】:

【解决方案4】:

当表单中有多个无效输入时,您只想滚动到其中的第一个:

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)
    }
})

JSFiddle

【讨论】:

  • 这个答案对我来说效果最好......我的表格很长,而且不用担心“只有第一个错误”,它总是会向下滚动太远。
  • 在此数学中添加 navbarHeight 后也可以正常工作: if ( ( elementOffset > ( pageOffset + navbarHeight ) ) && ( elementOffset
  • 请注意,如果您的输入在字段集中,则 form.find(':invalid').first() 将返回一个字段集。
【解决方案5】:

好的,我用a code snippet i found here on SO做了一个肮脏的测试

由于它是来自其他人的代码,我只是将其更改为滚动到缺少输入要求的元素。 我不想要它的任何功劳,它甚至可能不是您的想法,您或其他人可以将其用作参考。

目标是获取忘记/错误输入元素的 id:

            var myelement = input.id;
            var el = document.getElementById(myelement);
            el.scrollIntoView(false);

请记住,这个小提琴只适用于您在上面发布的小提琴,它不能处理多个忘记或错误的输入字段。我只是想展示一个替代方案。

----->jSFiddle

【讨论】:

  • 你刚刚通过将正确的部分组合在一起解决了一个难题;)我想出了一个更短的解决方案,我将在一秒钟内发布。
  • this fiddle。因为您将 false 指定为 scrollIntoView,所以该元素位于页面底部。所以解决方案并不完美(我的也不是)
  • 我认为需要有false,如果为true,它不起作用。我用THIS作为我的参考来给出答案
  • 如果可以通过添加margin-top: 50px; 或获取字段位置来调整alignWithTop,这两个代码都很好:),我认为这取决于OP 进行微调。
  • 我的第一个解决方案是获取getBoundingClientRect 并检查顶部是否小于标题的底部......然后相应地滚动窗口。我认为 scrollIntoView 是可以接受的 ;)
【解决方案6】:

我尝试使用 T.J. 的方式。护城河,但它没有按需要起作用,因为我经常回到外地,这首先是错误的。

所以,我做到了:

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>

希望对大家有所帮助:)

【讨论】:

    【解决方案7】:

    您可以使用 HTML5 的 oninvalid 事件属性,并在脚本的标签中编写一个重定向函数。

    示例如下:

    <input type="text" required oninvalid="scroll_to_validator(this)">
    
    <script>
        function scroll_to_validator(input)
            {
            input.focus(); 
            }
    </script>
    

    点击提交按钮后,它会滚动到无效字段。

    对于单选按钮,请仅在一个同名单选上添加
    Here is the example (jsfiddle)

    【讨论】:

    • 你好阿比拉什。我看你是新用户。为了您的信息,我已使用 {} 作为源代码格式化您的代码。这比使用 ` 字符突出显示文本并使用大量
      来模拟换行要好。
    • @schlebe 非常感谢
    【解决方案8】:

    两种解决方案:

    • 一:对body应用padding -->

      body {
       padding-top:50px;
      }
      
    • 二:对主容器应用边距 -->

       #content {
         margin-top:50px;
       }
      

    【讨论】:

    • 显然你无法解决这个问题.. 这是将页面直接引导到输入字段的发送按钮的功能问题。就像一个内部参考。
    • 你不能在文本栏下方添加一个 50px 的隐藏元素,然后将 send buttpn 引导到那里吗?
    • 这里的问题是你不能修改函数...是html5还是可以?
    • 有趣的是(使用 Chrome),当您使用 tab 键更改焦点时,它会正确滚动(尊重 50px 偏移量),而在提交时滚动,它不会。感觉有问题...
    【解决方案9】:

    这是一种简单快捷的方法。

    $('input').on('invalid', function(e) {
            setTimeout(function(){
                $('html, body').animate({scrollTop: document.documentElement.scrollTop - 150 }, 0);
            }, 0);
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多