简体   繁体   English

向下和向上滚动键上的内部 div

[英]Scrolling inner div on key down and up

I have build an autocomplete container which displays the first four results and the rest are hidden and can be seen when scrolling the inner div element which holds all the results.我已经构建了一个自动完成容器,它显示前四个结果,其余的被隐藏,当滚动包含所有结果的内部 div 元素时可以看到。

I have implemented the on key up when pressing the up and down keys in order to let the users navigate easily through the results but the inner div with the results isn't scrolling.我在按下向上和向下键时实现了向上键,以便让用户轻松浏览结果,但带有结果的内部 div 不滚动。

How can you scroll an element which has overflow-y:hidden and not the window ?你怎么能滚动一个有overflow-y:hidden而不是 window 的元素?

jsFiddle example here jsFiddle 示例在这里

In the example , just press any key inside the input box and use your arrows to go down, you will see that the div isn't scrolling在示例中,只需按输入框中的任意键并使用箭头向下移动,您将看到 div 没有滚动

You can update your script to find the relative position of the selected element and scroll to it:您可以更新脚本以查找所选元素的相对位置并滚动到它:

$(".someInput").on("keyup", function(e) {
   $(".wrapper").show(); 
    if (e.which == 40) {
        $('.element:not(:last-child).element-hover').removeClass('element-hover').next().addClass('element-hover');
    } else if (e.which == 38) {
        $('.element:not(:first-child).element-hover').removeClass('element-hover').prev().addClass('element-hover');    
    }
    //scroll to element:
    $(".wrapper .inner_div").scrollTop(0);//set to top
    $(".wrapper .inner_div").scrollTop($('.element-hover:first').offset().top-$(".wrapper .inner_div").height());//then set equal to the position of the selected element minus the height of scrolling div
});

http://jsfiddle.net/kMzR9/3/ http://jsfiddle.net/kMzR9/3/

By using tabIndex="-1" attribute on each of the children of a container, the browser will automatically scroll the container to have the child with the current focus in-view.通过在容器的每个子项上使用tabIndex="-1"属性,浏览器将自动滚动容器以使具有当前焦点的子项在视图中。

Demo (vanilla javascript):演示(香草javascript):

 var listElm = document.querySelector('ul') // Mark first list item listElm.firstElementChild.focus() // Event listener window.addEventListener('keydown', onKeyDown) // Event callback function onKeyDown(e){ e.preventDefault() var selectedElm = document.activeElement, goToStart, // map actions to event's key action = {ArrowUp:"previous", Up:"previous", ArrowDown:"next", Down:"next"} selectedElm = selectedElm[action[e.key] + "ElementSibling"]; // loop if top/bottom edges reached or "home"/"end" keys clicked if( !selectedElm || e.key == 'Home' || e.key == 'End' ){ goToStart = action[e.key] == "next" || e.key == 'Home' selectedElm = listElm.children[goToStart ? 0 : listElm.children.length - 1] } selectedElm.focus() }
 ul{ list-style: none; border : 1px solid silver; max-height: 170px; padding : 0; margin : 0; scroll-behavior: smooth; /* nice smooth movement */ overflow : hidden; /* set to hidden by OP's request */ } li{ padding:.5em; margin:0; } li:focus{ background:LIGHTSALMON; outline:none; }
 <ul> <li tabIndex="-1">item 1</li> <li tabIndex="-1">item 2</li> <li tabIndex="-1">item 3</li> <li tabIndex="-1">item 4</li> <li tabIndex="-1">item 5</li> <li tabIndex="-1">item 6</li> <li tabIndex="-1">item 7</li> <li tabIndex="-1">item 8</li> <li tabIndex="-1">item 9</li> <li tabIndex="-1">item 10</li> <li tabIndex="-1">item 11</li> <li tabIndex="-1">item 12</li> <li tabIndex="-1">item 13</li> <li tabIndex="-1">item 14</li> <li tabIndex="-1">item 15</li> </ul>

To make this list accessible ( ARIA ) read this要使此列表可访问( ARIA ), 请阅读此

There are several ways to implement it.有几种方法可以实现它。 and the exact solution for you need to consider your context.以及您需要考虑您的上下文的确切解决方案。

Anyway, one possible solution is to use in the container div ' position: relative ' and in the inner div (which hold the content) use ' position: absolute ' and ' top: 0px '.无论如何,一种可能的解决方案是在容器div 中使用“ position: relative ”,在内部div(保存内容)中使用“ position: absolute ”和“ top: 0px ”。 When user press on the up/down arrows you changing the top property accordingly.当用户按下向上/向下箭头时,您会相应地更改顶部属性。

CSS: CSS:

.container {
    position: relative;
    height: 50px;
    width: 200px;
    overflow: hidden;
    border: 1px solid blue;
}

.content {
    position: absolute;
    top: 0px;
}

JavaScript: JavaScript:

function moveContent(px) {
    var top = $('.content').position().top;
    $(".content").css("top", top+px);
}

$(document).keydown(function(e){
    if (e.keyCode == 38) { 
       moveContent(-5);
    }
    if (e.keyCode == 40) { 
       moveContent(5);
    }
});

HTML: HTML:

<div class="container">
    <div class="content">
        hello 1<br/>
        hello 2<br/>
        hello 3<br/>
        hello 4<br/>
        hello 5<br/>
        hello 6<br/>
    </div>
</div>

See my example in: http://jsfiddle.net/Kq2Qq/3/请参阅我的示例: http : //jsfiddle.net/Kq2Qq/3/

Two years passed... just in case someone stumbles over this, like me.两年过去了……以防万一有人像我一样绊倒这个。 In addition to the last two lines in Moobs answer (can't do any comments yet...), plain Javascript:除了 Moobs 回答中的最后两行(还不能做任何评论......),纯 Javascript:

(Left out: how to get elements in pure JS), then: (省略:如何在纯 JS 中获取元素),然后:

$innerDiv.scrollTop = $hoveredElement.offsetTop - $innerDiv.clientHeight;

There also seems to be no need to "reset" scrollTop to zero before assigning the new value在分配新值之前似乎也不需要“重置” scrollTop为零

Recently I faced the same problem and solved it by using .最近我遇到了同样的问题并通过使用 . emphasized text scrollIntoView(), sample code is below.强调文本scrollIntoView(),示例代码如下。 Example of two function respectively for up arrow key and down arrow key分别为向上箭头键和向下箭头键的两个函数示例

moveUp: function(e) {
        if (current > 0) {
            current--;
            var allNOdes = document.getElementById('list').childNodes;
            e.stopPropagation();
            if (allNOdes[current]) {
                allNOdes[current].scrollIntoView(true);
            }
        }
    },
    moveDown: function(e) {
        if (current <  10) {
            current++;
            var allNOdes = document.getElementById('list').childNodes;
            e.stopPropagation();
            if (allNOdes[current]) {
                allNOdes[current].scrollIntoView(true);
            }
        }
    }

Initially define current as 0 HTML:最初将 current 定义为 0 HTML:

<div class="wrapper">
 <div class="result" id="list">
   <div>1</div>
   <div>2</div>
   <div>3</div>
   <div>4</div>
 </div>
</div>

CSS: CSS:

.wrapper{
    position: relative;
    height: 150px;
    width: 100px;
    overflow: hidden;
}

.result{
    position: absolute;
}

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

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