首页 > 解决方案 > 当列表中的项目数超过屏幕高度时,列表项目不会从第一个开始显示

问题描述

我们需要播放视频,当用户按下“m”键时,我们需要将屏幕垂直分成两半。一半应仅显示文本“DVR”,另一半应显示列表和 30 个列表项(此数字仅用于测试目的。最初我们将从服务器获取数字)。每个列表项都将包含一个图像和一些文本。当我们显示菜单时,总是列表项应该从第一个可见并且第一个项应该具有焦点。当我们按下键时,焦点应该转移到第二项......下面是代码。

HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>VOD</title>
        <script src='lib/hls.js'></script>
        <script src='js/index.js'></script>
        <style>
            html, body
            {
                height:100%;
                width: 100%;
                overflow: hidden;
            }

            #vid
            {
                position: fixed;
                top: 50%;
                left: 50%;
                z-index: -1;
                min-width: 100%;
                min-height: 100%;
                width: auto;
                height: auto;
                transform: translate(-50%, -50%);
            }

            #mid {
                display: flex;
                width: 100%;
                height: 100%;
                justify-content: stretch;
                flex-flow: row nowrap;
                z-index: 2;
            }

            #mid.hidden {
                display: none;
            }

            #mid1, #mid2 {
                display: flex;
                flex: 1;
                align-items: center;
            }

            #mid1 {
                justify-content: center;
                background-color: rgba(255, 255, 255, 0.5);
            }

            #mid2 {
                background-color: rgba(255, 255, 255, 0.6);
            }

            #ulid {
                list-style-type: none;
                width: 100%;
                margin: 0;
                border: 0;
                padding: 0;
            }

            .list-item {
                width: 100%;
                height: 150px;
                border-style: solid;
                border-width: 1px;
                display:flex;
                align-items: center;
                justify-content: flex-start;
            }

            li:focus {
                background-color: lightslategray;
            }
        </style>
    </head>
    <body>
        <video id='vid' src='textMotion.mp4' autoplay loop></video>
        <div id='mid' class='hidden'>
            <div id="mid1">
                <h1>DVR</h1>
            </div>
            <div id="mid2">
                <ol id='ulid'></ol>
            </div>
        </div>
    </body>
</html>

JavaScript:

var foc_list_index = 0;

function processListEvent(event) {
    console.log('list Event : ' + event.keyCode + 'focused li ' + foc_list_index);

    let keyCode = event.keyCode;

    // Down
    if(keyCode == 40) {
        foc_list_index ++;
        document.getElementById('li' + foc_list_index).focus();
    }

    // Up
    if(keyCode == 38) {
        if(foc_list_index == 0) {
            console.log('Ignoring key up as we are already at first list index');
            return;
        }

        foc_list_index --;
        document.getElementById('li' + foc_list_index).focus();
    }
}

function displayMenu() {

    let mid = document.getElementById('mid');

    // If already menu is visible, hide it
    if(mid.classList.contains('hidden') == false) {
        mid.classList.toggle('hidden');
        let ulid = document.getElementById('ulid');
        while(ulid.firstChild) {
            ulid.removeChild(ulid.firstChild);
        }
        return;
    }

    let ulid = document.getElementById('ulid');

    for(let index = 0; index < 30; index ++) {
        let lItem = document.createElement('li');
        lItem.classList.add('list-item');
        lItem.setAttribute('id', 'li' + index);
        lItem.setAttribute('tabindex', index);
        lItem.addEventListener('keydown', processListEvent, false);

        let img = document.createElement("img");
        img.src = 'img/TNT.png';

        lItem.appendChild(img);

        lItem.appendChild(document.createTextNode('Showing ID : ' + index));
        ulid.appendChild(lItem);
    }

    mid.classList.toggle("hidden");
    document.getElementById('li0').focus();
    foc_list_index = 0;
}

function processKeyPress(e) {
    console.log('received keyEvent : ' + e.keyCode);
    let keyCode = e.keyCode;

    let mid = document.getElementById('mid');

    // Menu button or key 'm'
    if((keyCode == 77) || (keyCode == 462)) {
        displayMenu();
    }
}

document.addEventListener('keydown', processKeyPress);

除以下问题外,此代码工作正常。

1)当用户按下'm'时,菜单正在显示,后半部分从列表项12中显示。即使从0到29的列表项存在,它也从列表项12中显示。但它应该从列表中显示item 0. 我找到了这个问题的原因。这是因为我保留'align-items:center;' mid1 和 mid2 将文本保留在第一个屏幕上并将列表保留在第二个屏幕上应垂直居中。如果我删除 'align-items: center;' 对于 mid2,列表显示正常,但是当列表中只有很少的项目(如 3(而不是 30)时),列表不会垂直居中显示。不知道如何解决这个问题。

2)当我按下键时,一旦焦点穿过可见列表项,屏幕的左半部分也会移动,不应该移动。

第一个问题的屏幕截图(当用户选择“m”时,列表项应从 0 开始显示)

在此处输入图像描述

如果我删除 'align-items: center;' 问题的屏幕截图 对于 mid2,列表有 3 个项目(而不是 30 个)。列表应垂直居中。

在此处输入图像描述

第二个问题的屏幕截图(屏幕的左半部分正在移动,当焦点通过按下键穿过可见列表项时不应移动)

在此处输入图像描述

任何人都可以帮我解决这些问题。

标签: javascriptcsshtml

解决方案


我认为如果你使用justify-content:flex-start(或baseline)这将解决数字问题(见这个小提琴)如果你包括一个高度img,这将比第一个小提琴更清楚地显示项目(见这个),但是它会影响宽度。左手视频在这些小提琴中没有移动,只有 h1。我不清楚这一点。您可以将其包含在视频 div 中吗?(但也许你想要它作为一个覆盖?..)

无论如何,这是一个开始..希望这会有所帮助..


推荐阅读