HTML Select with disabled Option returns wrong selectedIndex in FireFox
I have a Select
with a disabled Option
wich is the default selected one:
<select name="select" size="1">
<option>0</option>
<option selected disabled>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
</select>
If I get the selected, it returns 1
. Everything OK.
But if I open the popup and hover with the cursor over another Option
(for Example '4')
and Cancel it via ESC or by clicking anywhere else.
The Select
input shows the old value 1
but returns on get selected 4
.
Example with jsfiddle
It doesn't happen with Chrome only FireFox (4/5)
It appears that the display is not changed when you exit your select this way however firefox is looking for a different selectedValue because it finds the currently selected option as disabled, which in firefox' eyes should be impossible.
The onChange event was not triggered until the onBlur event (which is when the selectedValue would get changed, but this is not what the display is changed to). If we were to reset our value in the onChange event this event might get called again. So by utilising the onBlur event we can provide the following workaround:
onBlur="javascript:document.getElementsByName('select')[0].selectedIndex = document.getElementsByName('select')[0].selectedIndex;"
http://jsfiddle.net/aRMpt/22/
I hope I'm making sense here.
The following code is ugly, but it does exactly what you want (I think). Basically, I am intercepting all onChange events, and only processing them if there is a corresponding onClick event that results in a changed value. ALso note that change events are processed before click events. EDIT: Just relaized this does not work in chrome, so i added some browser detection code so that it only executes in firefox.
NOTE: The current code would not work if the user had tabbed into the select box and made his changes with the error keys, but the method below can be easily adapted to handle that case as well. You'd simply need to process key events like arrow up or arrow down or TAB or ENTER in the same way clicks are processed below, but only when the select box had focus.
NOTE 2: Playing with this more, the behavior is very strange. If you escape out of the select, the onChange event is not triggered, but it is saved up. If at any later time you click anywhere on the screen the onChange event will be triggered for the value you were hovering over when you escaped, even though that value was actually changed as soon as you escaped. So this is getting tricky. I think you may have to handle the 2 cases separately. One case to handle click aways, and one to handle escape outs (which patrick answered).
It's getting hairy and I see no elegant way to code this. How about a note to the user next to the text box saying "Your currently selected option, 1, is no longer available." Then you could have a select box with only the avalable options.
<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>
Detect the esc
key and reset it, here is an example using jQuery (and a dash of your code)
$('select').keyup(function(e) {
if (e.keyCode == 27) {
document.getElementsByName('select')[0].selectedIndex = 1;
}
});
UPDATE No jQuery Solution
UPDATE 2 Abstracted out finding event and keycode for re-usability.
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>
链接地址: http://www.djcxy.com/p/8748.html
上一篇: 与用户搭乘CSS