2014-11-24 14 views
23

Wystąpił problem podczas korzystania z wielu zaznaczonych pól w obszarze Safari 8 w systemie OS X Yosemite. Jeśli pole wyboru ma zastosowaną szerokość, w linii lub jako klasa, nie mogę używać klawiszy strzałek na klawiaturze do przewijania w dół zaznaczenia zgodnie z normalnym zachowaniem.Przeglądarka Safari 8 z kilkoma wybranymi opcjami przewijania

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

Multiple wybrać JSFiddle.

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

z stylu taguJSFiddle.

Po wybraniu stylu zaznaczenie zostaje usunięte z widoku zamiast przewijania listy w dół, zachowując zaznaczony element w widoku.

Czy jest to błąd w wersji Safari (wersja 8.0 (10600.1.25)) Używam. Używam BrowserStack do moich testów. Czy jest to coś, co mogę rozwiązać za pomocą mojego kodu?

Dziękuję.

+1

przeżywam ten sam problem. Złożyłem raport o błędzie z jabłkiem i czekam na odpowiedź – michaelsmith

+0

@michaelsmith Czy masz link do raportu o błędzie? Czy masz odpowiedź? –

+0

Numer błędu z jabłkiem to 19365694 Opublikowałem go 2 stycznia, ale nie odpowiadają. – michaelsmith

Odpowiedz

1

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.

  1. Upewnij się, że szerokość Twój select jest mniejsza niż 13 * liczba opcji

LUB

  1. 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> 
Powiązane problemy