2011-08-03 22 views
7

Tôi có một Select với một khuyết tật Option mà là mặc định đã chọn một:HTML Select với lựa chọn tàn tật trả selectedIndex sai trong FireFox

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

Nếu tôi có được chọn, nó sẽ trả 1. Mọi thứ OK.

Nhưng nếu tôi mở popup và di chuột với con trỏ trên một Option(ví dụ '4')
và Hủy bỏ nó qua ESC hoặc bằng cách nhấn vào bất cứ nơi nào khác.

Đầu vào Select hiển thị giá trị cũ 1 nhưng trả về khi được chọn 4.

Example with jsfiddle

Nó không xảy ra với Chrome chỉ FireFox (4/5)

+2

Mục đích của việc này là gì? Đối với tôi ít nhất là vô hiệu hóa và chọn âm thanh như họ nên được loại trừ lẫn nhau và mặc dù tôi không thể tìm thấy bất cứ nơi nào trong spec đó một cách rõ ràng nói rằng tôi không chắc chắn tại sao có một cái gì đó được lựa chọn và vô hiệu hóa có ý nghĩa. Bạn đang cố gắng làm gì với điều này? – Chris

+0

Người dùng chọn thứ gì đó từ hộp. Quản trị viên có thể bật hoặc bỏ các mục khỏi hộp. Khi người dùng đã chọn và lưu một số giá trị, aftwerwards Quản trị sẽ vô hiệu hóa mục này, sau đó người dùng sẽ thấy cài đặt của anh ấy là mục đã chọn bị vô hiệu hóa. Người dùng mở hộp, nhưng không tìm thấy bất kỳ tùy chọn nào khác mà anh thích, vì vậy nhấn ESC. Nhưng SAVE tiếp theo sẽ thay đổi giá trị đã chọn. – oliholz

+3

Ah. Tôi biết bạn đến từ đâu. Đối với mắt bên ngoài của tôi, có vẻ như giải pháp không cho phép người dùng tiếp tục có giá trị đã bị quản trị viên tắt một cách rõ ràng và cung cấp cho họ lựa chọn "không áp dụng" hoặc chỉ buộc họ chọn một giá trị mới. Tôi đã có một chút của một vở kịch mặc dù và không có xa hơn Alexander dưới đây. Firefox rõ ràng đang kích hoạt sự kiện thay đổi của nó khi bạn mất tập trung ngụ ý rằng trình duyệt cho rằng nó đã bị thay đổi. Có lẽ nếu giữ tùy chọn đó là trong thực tế hợp lệ thì bạn không muốn "vô hiệu hóa" nếu nó cũng "được chọn". Điều này dường như giải quyết vấn đề của bạn – Chris

Trả lời

1

Dường như màn hình hiển thị là không thay đổi khi bạn thoát khỏi chọn cách này của bạn tuy nhiên firefox đang tìm kiếm một khác nhau selectedValue vì nó tìm thấy tùy chọn hiện đang được chọn là bị vô hiệu hóa, mà trong mắt firefox 'là không thể.

Sự kiện onChange không được kích hoạt cho đến khi sự kiện onBlur (đó là khi lựa chọnValue sẽ thay đổi, nhưng đây không phải là những gì màn hình được thay đổi thành). Nếu chúng ta đặt lại giá trị của chúng ta trong sự kiện onChange, sự kiện này có thể được gọi lại. Vì vậy, bằng cách sử dụng sự kiện onBlur chúng tôi có thể cung cấp cách giải quyết như sau:

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

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

Tôi hy vọng tôi làm cho ý nghĩa ở đây.

+0

Cảm ơn bạn đã gợi ý của bạn, nhưng tôi muốn ban đầu bị vô hiệu hóa Tùy chọn trên get selectedItem, vì tôi hủy bỏ lựa chọn với 'ESC'. – oliholz

1

Detect phím esc và đặt lại nó, đây là một ví dụ sử dụng jQuery (và một chút mã của bạn)

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

CẬP NHẬT Không Giải pháp jQuery

UPDATE 2 trừu tượng ra việc tìm kiếm sự kiện và mã khóa để sử dụng lại.

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

Vì anh ấy không sử dụng jQuery, hãy thử đưa ra một ví dụ không có trong jQuery ... – Bot

+0

@jostster Tôi đã cập nhật ví dụ của mình bằng giải pháp không phải jQuery. –

+0

Thật không may là không đủ vì lỗi xảy ra không chỉ sau khi nhấp Escape, mà còn nếu bạn, ví dụ, hãy nhấp vào phần khác của tài liệu, nếu bạn tập trung vào một cửa sổ khác, v.v. – duri

1

Các mã sau là xấu xí, nhưng nó thực hiện chính xác những gì bạn muốn (tôi nghĩ). Về cơ bản, tôi chặn tất cả các sự kiện onChange và chỉ xử lý chúng nếu có sự kiện onClick tương ứng dẫn đến giá trị thay đổi. Cũng lưu ý rằng các sự kiện thay đổi được xử lý trước khi các sự kiện nhấp chuột. EDIT: Chỉ cần relaized này không hoạt động trong chrome, vì vậy tôi đã thêm một số mã phát hiện trình duyệt để nó chỉ thực hiện trong firefox. LƯU Ý: Mã hiện tại sẽ không hoạt động nếu người dùng đã được gắn thẻ vào hộp chọn và thực hiện thay đổi bằng các phím lỗi, nhưng phương pháp bên dưới có thể dễ dàng điều chỉnh để xử lý trường hợp đó. Bạn chỉ cần xử lý các sự kiện quan trọng như mũi tên lên hoặc mũi tên xuống hoặc TAB hoặc ENTER theo cách tương tự khi các nhấp chuột được xử lý bên dưới, nhưng chỉ khi hộp chọn có tiêu điểm.

CHÚ Ý 2: Chơi với điều này nhiều hơn, hành vi rất lạ. Nếu bạn thoát ra khỏi lựa chọn, sự kiện onChange không được kích hoạt, nhưng nó được lưu lên. Nếu bất kỳ lúc nào bạn nhấp vào ở bất kỳ đâu trên màn hình, sự kiện onChange sẽ được kích hoạt cho giá trị bạn đang di chuột qua khi bạn thoát, ngay cả khi giá trị đó thực sự thay đổi ngay khi bạn thoát. Vì vậy, điều này là nhận được khôn lanh. Tôi nghĩ bạn có thể phải xử lý riêng 2 trường hợp. Một trường hợp để xử lý nhấp vào aways, và một để xử lý thoát ra ngoài (mà patrick trả lời).

Nó đang bị lông và tôi thấy không có cách nào thanh lịch để viết mã này. Cách ghi chú cho người dùng bên cạnh hộp văn bản có nội dung "Tùy chọn hiện đang được chọn của bạn, 1, không còn khả dụng". Sau đó, bạn có thể có một hộp chọn chỉ với các tùy chọn có sẵn.

<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

Công việc xung quanh tôi phải sử dụng cho việc này là đặt người xem sự kiện vào sự kiện nhấp của tùy chọn không được chọn trong trình đơn thả xuống. Trong hàm của người nghe sự kiện, tôi đặt một boolean toàn cục.

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

Sau đó, trong lĩnh vực mã nơi tôi cần những giá trị được lựa chọn thả xuống, tôi kiểm tra boolean:

nếu boolean là đúng tôi sau đó có thể sử dụng giá trị của nó mới

nếu boolean là false tôi có thể nhận được giá trị từ thuộc tính Html (có chứa giá trị ban đầu của trình đơn thả xuống).

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

Điều này thật xấu xí, nhưng đây là công việc duy nhất tôi có thể tìm thấy.

Các vấn đề liên quan