2014-11-24 47 views
23

在OS X Yosemite上使用Safari 8中的多個選擇字段時,我遇到了問題。如果選擇字段具有應用寬度(無論是內聯還是類),我無法使用鍵盤箭頭鍵按照常規行爲向下滾動選擇內容。Safari 8多選滾動問題

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

多重選擇JSFiddle

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

風格標籤JSFiddle

當select具有樣式時,選擇移出視圖,而不是向下滾動列表以保持所選項目在視圖中。

這是我使用的Safari版本(版本8.0(10600.1.25))中的一個錯誤。我正在使用BrowserStack進行測試。或者這是我可以通過我的代碼解決的問題?

謝謝。

+1

我遇到同樣的問題。 我已經提交了一個蘋果的錯誤報告,並等待回覆 – michaelsmith 2015-01-06 13:47:43

+0

@michaelsmith你有一個錯誤報告的鏈接?你有迴應嗎? – 2015-01-31 10:08:07

+0

蘋果的bug數是19365694 我已經發布了它1月2日,但他們不回答。 – michaelsmith 2015-02-01 11:19:42

回答

1

我認爲這確實是一些類型的錯誤,它與select元素的寬度和元素的scrollHeight有關。

你有更多的選擇,它可以越寬,仍然工作正常。如果我有一個帶有39個選項的選擇標籤,max在混亂之前似乎大約爲510px。

平均而言,選擇可處理的最大寬度似乎大約爲每個選項13px。所以如果你有一個有13個選項的選擇器,那麼最大值約爲169px(13 * 13)

當你滾動到第二個選項時,scrollTop是14px,第三個選項是28px。所以你滾動到的每個元素都是14px。因此,只要寬度小於scrollHeight減去一定數量的像素,它就可以工作...如果您使用每個選項13像素,它似乎工作正常。

所以,你有2個選項。

  1. 確保你選擇的寬度小於13 *的期權數量

OR

  • 使用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>