HTML Select with disabled选项在FireFox中返回错误的selectedIndex

时间:2011-08-03 07:40:05

标签: html firefox drop-down-menu

我有一个Select被禁用的Option是默认选择的一个:

<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 FireFox(4/5)

时不会发生这种情况

4 个答案:

答案 0 :(得分:1)

当您以这种方式退出select时,显示不会更改,但firefox正在寻找不同的selectedValue,因为它会将当前选中的选项视为已禁用,这在firefox的眼中应该是不可能的。

onClnge事件直到onBlur事件才被触发(这是selectValue会被更改的时候,但这不是显示更改的内容)。如果我们要在onChange事件中重置我们的值,则可能会再次调用此事件。因此,通过使用onBlur事件,我们可以提供以下解决方法:

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

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

我希望我在这里有意义。

答案 1 :(得分:1)

检测esc密钥并重置它,这是一个使用jQuery(以及一些代码)的示例

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

更新没有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>

答案 2 :(得分:1)

以下代码很难看,但它完全符合您的要求(我认为)。基本上,我正在拦截所有onChange事件,并且只有在存在导致更改值的相应onClick事件时才处理它们。另请注意,在单击事件之前处理更改事件。编辑:刚刚重新启动这在chrome中不起作用,所以我添加了一些浏览器检测代码,以便它只在firefox中执行。

注意:如果用户已选中选项框并使用错误键进行更改,则当前代码将不起作用,但下面的方法也可以轻松调整以处理该情况。您只需处理关键事件,如向上箭头或向下箭头或TAB或ENTER,就像下面处理点击一样,但只有当选择框有焦点时才需要。

注意2:玩这个更多,行为很奇怪。如果退出select,则不会触发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>

答案 3 :(得分:0)

我必须使用的工作是在下拉列表中的未选择选项的click事件上放置一个事件监听器。在事件监听器的函数中,我设置了一个全局布尔值。

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

然后在我需要下拉列表的选定值的代码区域中,我检查布尔值:

如果布尔值为真,我可以使用它的新值

如果布尔值为false,我可以从Html属性中获取值(包含下拉列表的初始值)。

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

我知道这很难看,但这是我能找到的唯一工作。