23

在 OS X Yosemite 上的 Safari 8 中使用多个选择字段时,我遇到了问题。如果选择字段具有应用的宽度,无论是内联的还是作为类的,我都无法按照正常行为使用键盘箭头键向下滚动选择。

<select size="5" name="selectMultiple" multiple="multiple">

多选JSFiddle

<select size="5" name="selectMultiple" multiple="multiple" style="width:100%;">

带有样式标签 JSFiddle

When the select has style the selection moves out of view instead of scrolling the list downwards keeping the selected item in view.

这是我正在使用的 Safari 版本(版本 8.0 (10600.1.25))中的错误吗?我正在使用 BrowserStack 进行测试。或者这是我可以通过我的代码修复的问题吗?

谢谢你。

4

1 回答 1

1

我认为这确实是某种类型的错误,与选择元素的宽度与元素的滚动高度有关。

您拥有的选项越多,它就可以越广泛并且仍然可以正常工作。如果我有一个带有 39 个选项的选择标签,那么最大值似乎在 510px 左右,然后才搞砸。

平均而言,一个选择可以处理的最大宽度似乎是每个选项大约 13 像素。所以如果你有一个有 13 个选项的选择器,那么最大值约为 169px (13 * 13)

当您滚动到第二个选项时,scrollTop 为 14 像素,滚动到第三个选项时为 28 像素。因此,您滚动到的每个元素都是 14 像素。因此,只要宽度小于 scrollHeight 减去一定数量的像素,它就可以工作......如果您使用每个选项 13 个像素,它似乎工作正常。

所以,你有2个选择。

  1. 确保您选择的宽度小于 13 * 选项数

或者

  1. 使用 javascript 来获得你想要的行为......我想出了一个有效的JsFiddle。对于那些喜欢使用 jQuery 的人,试试这个JsFiddle

您只需要监听 keydown 事件并调整滚动,以便所选元素在被选中之前处于视图中。

此外,为了使 scrollByLines(numberOfLines) 方法在滚动元素上起作用,它必须具有以下样式:

overflow-y: scroll;

这是一个有效的快速 HTML 文档

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script type="text/javascript">

        // This happens on document load
        function myOnLoad() {

            // Get the selector element
            var mySelector = document.getElementById('mySelector');

            // If the selector is doomed to glitch out on us because it's wider than the max allowed width, we need to fix it
            if (mySelector.offsetWidth > 13 * mySelector.options.length) {

                // Figure out the pixels for a single scroll line
                mySelector.scrollByLines(1);
                var scrollLineHeight = mySelector.scrollTop;

                // Scroll back to the top
                mySelector.scrollTop = 0;

                // Add a keydown event listener so that we can scroll programatically before it messes up
                mySelector.addEventListener('keydown', function (e) {

                    // Only listen to up and down arrows
                    if (e.keyCode !== 38 && e.keyCode !== 40) {
                        return;
                    }

                    // Figure out where the selector is scrolled to
                    var scrollTop = this.scrollTop;
                    var scrolledToLine = parseInt(scrollTop / scrollLineHeight);

                    // If we hit the up arrow and the selected index is equal to the scrolled line, simply move us up by one
                    if (e.keyCode === 38 && this.selectedIndex === scrolledToLine) {
                        this.scrollByLines(-1);
                    }

                    // If we hit the down arrow and the selected index is equal to the scrolled line + the number of visible lines - 1, move us down by one
                    if (e.keyCode === 40 && this.selectedIndex === scrolledToLine + (this.size - 1)) {
                        this.scrollByLines(1);
                    }
                });
            }
        }
    </script>
</head>
<body onload="myOnLoad();">
<select size="5" name="selectMultiple" multiple="multiple" style="width:100%; overflow-y: scroll;" id="mySelector">
    <option value="0">line 0</option>
    <option value="1">line 1</option>
    <option value="2">line 2</option>
    <option value="3">line 3</option>
    <option value="4">line 4</option>
    <option value="5">line 5</option>
    <option value="6">line 6</option>
    <option value="7">line 7</option>
    <option value="8">line 8</option>
    <option value="9">line 9</option>
    <option value="10">line 10</option>
    <option value="11">line 11</option>
    <option value="12">line 12</option>
</select>
</body>
</html>

这是 jQuery 版本:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title></title>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
    <script type="text/javascript">

        $( document ).ready(function() {

            // Get the selector element
            var mySelectorObj = $('#mySelector');
            var mySelector = mySelectorObj[0];

            // If the selector is doomed to glitch out on us because it's wider than the max allowed width, we need to fix it
            if (mySelector.offsetWidth > 13 * mySelector.options.length) {

                // Figure out the pixels for a single scroll line
                mySelector.scrollByLines(1);
                var scrollLineHeight = mySelector.scrollTop;

                // Scroll back to the top
                mySelector.scrollTop = 0;

                // Add a keydown event listener so that we can scroll programatically before it messes up
                mySelectorObj.on('keydown', function(e) {

                    // Only listen to up and down arrows
                    if (e.keyCode !== 38 && e.keyCode !== 40) {
                        return;
                    }

                    // Figure out where the selector is scrolled to
                    var scrollTop = this.scrollTop;
                    var scrolledToLine = parseInt(scrollTop / scrollLineHeight);

                    // If we hit the up arrow and the selected index is equal to the scrolled line, simply move us up by one
                    if (e.keyCode === 38 && this.selectedIndex === scrolledToLine) {
                        this.scrollByLines(-1);
                    }

                    // If we hit the down arrow and the selected index is equal to the scrolled line + the number of visible lines - 1, move us down by one
                    if (e.keyCode === 40 && this.selectedIndex === scrolledToLine + (this.size - 1)) {
                        this.scrollByLines(1);
                    }
                });
            }
        });
    </script>
</head>
<body>
<select size="5" name="selectMultiple" multiple="multiple" style="width:100%; overflow-y: scroll;" id="mySelector">
    <option value="0">line 0</option>
    <option value="1">line 1</option>
    <option value="2">line 2</option>
    <option value="3">line 3</option>
    <option value="4">line 4</option>
    <option value="5">line 5</option>
    <option value="6">line 6</option>
    <option value="7">line 7</option>
    <option value="8">line 8</option>
    <option value="9">line 9</option>
    <option value="10">line 10</option>
    <option value="11">line 11</option>
    <option value="12">line 12</option>
</select>
</body>
</html>
于 2015-05-24T00:04:01.810 回答