Safari 8多选滚动问题

Jon*_*han 23 html css browserstack osx-yosemite safari8

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

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

多选JSFiddle.

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

带有样式标签 JSFiddle.

当选择具有样式时,选择移出视图而不是向下滚动列表,从而保持所选项目在视图中.

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

谢谢.

Ray*_*rea 1

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

您拥有的选项越多,它的范围就越大,并且仍然可以正常工作。如果我有一个包含 39 个选项的选择标签,则在出现混乱之前最大值似乎约为 510px。

平均而言,选择可以处理的最大宽度似乎约为每个选项 13px。因此,如果您有一个包含 13 个选项的选择器,则最大值约为 169px (13 * 13)

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

所以,你有两个选择。

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

或者

  1. 使用 javascript 来获得您想要的行为...我想出了一个可以工作的JsFiddle。对于那些喜欢使用 jQuery 的人,可以尝试这个JsFiddle

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

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

overflow-y: scroll;
Run Code Online (Sandbox Code Playgroud)

这是一个可以使用的快速 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>
Run Code Online (Sandbox Code Playgroud)

这是 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>
Run Code Online (Sandbox Code Playgroud)