Myślę, że to rzeczywiście jakiś błąd, który ma do czynienia z szerokością elementu select vs scrollHeight elementu.
Im więcej masz opcji, tym może być szersza i nadal działa dobrze. Jeśli mam znacznik wyboru z 39 opcjami, maksimum wydaje się wynosić około 510px, zanim zacznie się pojawiać.
Średnio maksymalna szerokość, którą może obsłużyć wybrany użytkownik, wydaje się wynosić około 13 pikseli za opcję. Więc jeśli masz selektor z 13 opcjami, to max wynosi około 169px (13 * 13)
Po przewinięciu do opcji 2, scrollTop ma rozmiar 14px, a do opcji trzeciej 28px. Więc każdy element, który przewijasz, ma 14 pikseli. Tak długo, jak szerokość jest mniejsza niż scrollHeight minus pewna liczba pikseli, działa ... Jeśli używasz 13 pikseli na opcję, wydaje się, że działa dobrze.
Masz 2 opcje.
- Upewnij się, że szerokość Twój select jest mniejsza niż 13 * liczba opcji
LUB
- użyć JavaScript, aby uzyskać pożądany zachowanie ... wymyśliłem JsFiddle, który działa. A dla tych, którzy lubią przy użyciu jQuery, spróbuj tego JsFiddle
Trzeba tylko słuchać keyDown i dostosować zwój tak, że wybrany element w widoku, zanim zostanie wybrany.
Ponadto, w celu uczynienia scrollByLines (numberOfLines) praca metoda na elemencie przewijania, musi mieć następujące style:
overflow-y: scroll;
Oto krótki dokument HTML, który działa
<!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>
A oto wersja 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>
przeżywam ten sam problem. Złożyłem raport o błędzie z jabłkiem i czekam na odpowiedź – michaelsmith
@michaelsmith Czy masz link do raportu o błędzie? Czy masz odpowiedź? –
Numer błędu z jabłkiem to 19365694 Opublikowałem go 2 stycznia, ale nie odpowiadają. – michaelsmith