简体   繁体   English

HTML:当浏览器滚动到输入时,如何使整个输入的父视图可见?

[英]HTML: When a browser scrolls to an input, how can one make it bring the entire input's parent into view?

I'm not a web guy, so this might be something really simple I'm missing, but: 我不是网络专家,所以这可能是我所缺少的非常简单的东西,但是:
Consider the following page: 考虑以下页面:
http://pastehtml.com/view/1bg9qno.html http://pastehtml.com/view/1bg9qno.html

Which is basically a list of <input> s, and each input has a helper <span> with text (that will change along with the input's value on keyUp ). 这基本上是<input>的列表,每个输入都有一个带有文本的辅助<span> (随keyUp上的输入值一起变化)。

So when the list is long enough (like in the above HTML page), if you tab thru the inputs, you will eventually get to the input on the bottom of the page, tab again, and the browser will scroll down to the next input. 因此,当列表足够长时(例如上述HTML页面中的内容),如果您通过输入进行制表,则最终将进入页面底部的输入,再次制表,浏览器将向下滚动至下一个输入。

In my case, the input has the helper text which is crucial to my app. 就我而言,输入包含对我的应用程序至关重要的帮助程序文本。

The problem is that when the user tabs down to the input that is not visible, the browser only brings that input into the view, and not his entire parent ( <div class="item"> ) which contains the helper text. 问题在于,当用户向下导航到不可见的输入时,浏览器仅将输入带入视图,而不是其包含帮助者文本的整个父级( <div class="item"> )。 As a result, this helper text is not visible to the user while he enters stuff in the input. 结果,当用户在输入中输入内容时,该帮助者文本对于用户不可见。

How can one tell the browser to bring the entire parent into view when focusing the out-of-view input? 在聚焦视线外输入时,如何告诉浏览器将整个父级视线显示?
Is there any elegant solution? 有什么优雅的解决方案吗?

BTW: This doesn't happen in Chrome, since Chrome always scrolls down a part-page, but it always happens in Firefox which always scrolls as little as possible to the input. 顺便说一句:在Chrome中不会发生这种情况,因为Chrome总是向下滚动部分页面,但是在Firefox中总是会发生这种情况,而Firefox只会向输入内容尽可能少地滚动。

The HTML looks like this: HTML看起来像这样:

<body>
    <div class="item">
        <input type="text" value="text" />
        <br />
        <span>helper text</span>
    </div>
    <hr />
    ...
    <hr />
    <div class="item">
        <input type="text" value="text" />
        <br />
        <span>helper text</span>
    </div>
</body>
<html>
  <head>
    <script>
      function scrollParentIntoView(elem){
        setTimeout(function(){
           var children  = elem.parentNode.children;
           var lastChild = children[children.length - 1];
           lastChild.scrollIntoView();
           elem.parentNode.scrollIntoView();
           //elem.ScrollIntoView();
         },1);
      }
    </script>
  </head>
  <body>
    ...
    <div>
      <input onfocus="scrollParentIntoView(this);" />
      ...
      <p>end</p>
    </div>
    ...
  </body>
</html>

I've tested on FF and Chrome and seems to do the job - you can see the input and 'end' when each '...' is replaced with a dozen 我已经在FF和Chrome上进行了测试,似乎可以完成工作-当每个“ ...”替换为一打时,您可以看到输入和“结束”
tags 标签

Here is a solution using jQuery. 这是使用jQuery的解决方案。 It's based on the height of your item container. 它基于项目容器的高度。

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        $(".item input").focus(function() {
            var parent = $(this).parent();

            // Check if the bottom of the item container is below the viewport
            if ($(parent).position().top + $(parent).height() > $(window).scrollTop() + $(window).height())
            {
                // Adjust the scroll position according to the height of the item container
                $(window).scrollTop($(window).scrollTop() + $(parent).height());
            }
        });
    });
</script>

Edit 编辑

Here is a demo for you: http://pastehtml.com/view/1bnv1xb.html 这是给您的演示: http : //pastehtml.com/view/1bnv1xb.html

This Javascript works in FF 3.6, IE 8, Safari 4, and Chrome 3.1. 该Javascript可在FF 3.6,IE 8,Safari 4和Chrome 3.1中使用。 It doesn't require JQuery, doesn't need setTimeout s, and can be condensed to about 8 lines: 它不需要JQuery,不需要setTimeout ,并且可以压缩为大约8行:

//Collect the elements 
var ALL = document.getElementsByTagName("INPUT");

for(x=0;x<ALL.length;x++) {
  //Add relative position style to allow offset math
  ALL.style.position = 'relative';

  ALL[x].onfocus = function() {
    //Find scroll offset distance
    var temp = this.offsetParent.offsetTop + 
               this.offsetParent.offsetHeight - 
               document.documentElement.clientHeight;

    //Detect webkit browser and apply scroll offset as appropriate
    window.devicePixelRatio ? 
      document.body.scrollTop = temp : 
      document.documentElement.scrollTop = temp;
  }
}

Of course, the obvious solution here is to put all the important content above the input element, but it's obvious that that won't do for whatever reason, so here's another solution: 当然,这里显而易见的解决方案是将所有重要内容放在input元素上方,但是很明显,无论出于何种原因都不会这样做,因此这是另一个解决方案:

Remember that tabindex can be used to allow any element to be focused. 请记住, tabindex可用于允许任何元素集中。 This means that we can simply drop a tabindex on the parent of the input elements to allow the entire parent to gain focus and scroll into view. 这意味着我们可以简单地在input元素的父元素上放置一个tabindex ,以使整个父元素获得焦点并滚动到视图中。

However, this also means that tab must be tapped twice to get the input element focused. 但是,这也意味着必须点按两次制表符才能使input元素聚焦。 You will also need to explicitly set tabindex on the input element to have them be the next in line to gain focus. 您还需要在input元素上显式设置tabindex ,以使它们成为下一行以获取焦点。

<ol id="input">
    <li tabindex="3">
        <input type="text" tabindex="5" />
        <p>Helper Text</p>
    </li>
    <li tabindex="7">
        <input type="text" tabindex="10" />
        <p>Helper Text</p>
    </li>
</ol>

You'll also want to give the parent elements a :focus style instead of the rather ugly dotted outline. 您还需要给父元素一个:focus样式,而不是一个难看的虚线轮廓。

See: http://www.jsfiddle.net/F2fwy/2 请参阅: http//www.jsfiddle.net/F2fwy/2

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM