2011-08-03 105 views
7

我有一個殘疾Option至極一個Select是選擇一個默認的:HTML選擇與禁用選項返回錯誤的selectedIndex在FireFox

<select name="select" size="1"> 
    <option>0</option> 
    <option selected disabled>1</option> 
    <option>2</option> 
    <option>3</option> 
    <option>4</option> 
</select> 

如果我能選擇的,則返回1。一切還好。

但是,如果我打開彈出式窗口,用光標移到另一個Option懸停(例如,「4」)
,並通過ESC或通過點擊其他地方取消它。

Select輸入顯示舊值1但返回時得到所選4

Example with jsfiddle

它不適用於Chrome只發生在火狐(4/5)

+2

這是什麼意圖?對我來說,至少禁用和選擇聲音,因爲它們應該是相互排斥的,雖然我無法在規範中找到明確說明這一點的任何地方,但我不確定爲什麼選擇和禁用某些內容是有道理的。你想用這個做什麼? – Chris

+0

用戶從框中選擇一些東西。管理員可以啓用或取消箱子中的物品。當用戶選擇並保存了一些值後,管理員禁用此項目,則用戶應該將其設置看作禁用的選定項目。用戶打開盒子,但沒有找到他喜歡的任何其他選項,因此按下了ESC。但下一次保存會改變選定的值。 – oliholz

+3

啊。我明白你來自哪裏。對我而言,感覺就像解決方案不讓用戶繼續擁有一個已被管理員明確禁用的值,並給他們一個「不適用」的選擇或者強制他們選擇一個新的。儘管我已經有了一些戲,並沒有比亞歷山大更進一步。當你失去焦點時,Firefox會明確地啓動它的更改事件,這意味着瀏覽器認爲它已被更改。也許如果保留這個選項實際上是有效的,那麼如果它也被「選擇」,你不想「禁用」。這似乎可以解決你的問題 – Chris

回答

1

看來,當你離開你選擇這種方式然而Firefox是尋找一個不同的顯示器不改變selectedValue,因爲它發現當前選中的選項被禁用,這在firefox眼中應該是不可能的。

onChange事件直到onBlur事件(即selectedValue被更改,但這不是顯示更改爲)時才被觸發。如果我們要在onChange事件中重置我們的值,則可能會再次調用此事件。因此,通過利用onblur事件,我們可以提供以下解決方法:

onBlur="javascript:document.getElementsByName('select')[0].selectedIndex = document.getElementsByName('select')[0].selectedIndex;"

http://jsfiddle.net/aRMpt/22/

我希望我做的意義在這裏。

+0

感謝您的建議,但我希望原始禁用的選項獲得selectedItem,因爲我用'ESC'取消了選擇。 – oliholz

1

檢測的esc鍵和復位,這裏是使用jQuery的例子(和你的代碼的破折號)

$('select').keyup(function(e) { 
    if (e.keyCode == 27) { 
    document.getElementsByName('select')[0].selectedIndex = 1; 
    } 
}); 

UPDATE沒有jQuery的解決方案

更新2抽象出來發現事件和鍵碼用於重新使用。

DEMO:http://wecodesign.com/demos/stackoverflow-6923135.htm

<script type="text/javascript"> 
function getEvent(event) { 
    if (window.event) return window.event; 
    return event; 
} 
function getKeycode (event) { 
    if (event.which) return event.which; 
    else return event.keyCode; 
} 
changeToDefaultListener = function(event) { 
    theEvent = getEvent(event); 
    theKeyCode = getKeycode(theEvent); 
    if(theKeyCode == 27) { 
     document.getElementsByName('select')[0].selectedIndex = 1; 
    } 
}; 
</script> 
<select name="select" size="1"> 
    <option>0</option> 
    <option selected disabled>1</option> 
    <option>2</option> 
    <option>3</option> 
    <option>4</option> 
</select> 

<a href="javaScript:alert(document.getElementsByName('select')[0].selectedIndex);">getSelected</a> 

<script type="text/javascript"> 
document.getElementsByName('select')[0].onkeyup=changeToDefaultListener; 
</script> 
+0

因爲他沒有使用jQuery嘗試給出一個不在jQuery中的例子... – Bot

+0

@jostster我已經用非jQuery解決方案更新了我的示例。 –

+0

這不幸是不夠的,因爲錯誤不僅發生在單擊Escape之後,而且還會發生,例如,如果你點擊文檔的其他部分,如果你關注另一個窗口等等。 – duri

1

下面的代碼是醜陋,但它正是你想要的(我認爲)。基本上,我攔截所有onChange事件,並且只有在對應的onClick事件導致更改的值時才處理它們。還注意到更改事件在點擊事件之前處理。編輯:只是介紹了這不適用於鉻,所以我添加了一些瀏覽器檢測代碼,以便它只在Firefox執行。

注意:如果用戶已將選項框標籤並使用錯誤鍵進行了更改,則當前代碼將不起作用,但下面的方法也可輕鬆適用於處理該情況。您只需按照向上箭頭或向下箭頭或TAB或ENTER鍵的方式處理關鍵事件,方法與下面的處理點擊方式相同,但僅在選擇框具有焦點時進行。

注2:玩這個更多,這種行爲是非常奇怪的。如果您退出選擇,onChange事件不會被觸發,但會被保存起來。如果在以後任何時候點擊屏幕上的onChange事件將被觸發,以查找您在轉義時懸停的值,即使該值在您轉義後實際上已更改。所以這變得棘手。我想你可能需要分開處理這兩個案件。一個處理點擊的案例,一個處理逃跑出局(帕特里克回答)。

它變得毛茸茸的,我看不到優雅的方式來編碼。如何在文本框旁邊的用戶提示「您當前選擇的選項1不再可用」。然後你可以有一個只有可用選項的選擇框。

<select name="select" size="1" onChange="handleChange()" onClick="handleClick()" > 
    <option>0</option> 
    <option selected disabled>1</option> 
    <option>2</option> 
    <option>3</option> 
    <option>4</option> 
</select> 
<br /> 


<script> 
var initialValue = document.getElementsByName('select')[0].selectedIndex; 
var potentialChange; 
var processClick; 

function handleClick() { 

    //ignore this code if not firefox 
    if (navigator.userAgent.indexOf("Firefox") === -1) 
     return; 

    var curVal = document.getElementsByName('select')[0].selectedIndex; 
    if (!processClick) 
     return; 
    // a value change click occured, now we actually process it. 
    document.getElementsByName('select')[0].value = potentialChange; 
} 
function handleChange() { 
    // save the potential change, which will be used if a real click was detected 
    potentialChange = document.getElementsByName('select')[0].selectedIndex; 
    processClick = (potentialChange !== initialValue); 
    // undo the attempted change, in case of an escape or page click 
    // but only on firefox 
    if (navigator.userAgent.indexOf("Firefox")!=-1) 
     document.getElementsByName('select')[0].value = initialValue; 

    document.getElementsByName('select')[0].value = initialValue; 
} 
</script> 

<a href="javaScript:alert(document.getElementsByName('select')[0].selectedIndex);">getSelected</a> 
0

我必須使用的解決方法是將事件偵聽器置於未選定選項的單擊事件下拉列表中。在事件監聽器的函數中,我設置了一個全局布爾值。

var selectChanged = false; 
$('#select option:not(:selected)').click(function() { 
    selectChanged = true; 
}); 

然後在我需要下降的設定值的向下碼的區域,我查布爾:

如果布爾是真的,我就可以使用它的新價值

如果布爾值爲假,我可以從Html屬性(包含下拉的初始值)獲取值。

var selectValue = selectChanged ? $('#select').val() : $($('#select').outerHtml()).find('option:selected').val() 

這是醜陋的我知道,但這是我能找到的唯一工作。