2010-02-20 29 views
11

Điều này đang thúc đẩy tôi hạt. Một trong những khó khăn của nó để giải thích nhưng tôi sẽ có một đi.Tôi gặp sự cố với sự kiện keydown và tự động hoàn tất trong Firefox trên mac

Tôi có một trường nhập văn bản trên trang đầu của trang web của tôi. Tôi đã mã hóa một người quan sát sự kiện keydown mà kiểm tra keyCode và nếu nó ENTER (hoặc equiv), nó sẽ kiểm tra giá trị đầu vào (email). Nếu email hợp lệ và duy nhất trong DB, nó sẽ gửi biểu mẫu. Công cụ cơ bản, hoặc vì vậy bạn sẽ nghĩ.

Nếu tôi nhập địa chỉ email của mình vào trường và nhấn enter, nó hoạt động tốt trong tất cả các trình duyệt. Tuy nhiên, nếu tôi gõ vài chữ cái đầu tiên, và sau đó sử dụng các phím mũi tên để chọn email từ hộp thả xuống lịch sử (hy vọng bạn biết ý tôi ở đây), và sau đó nhấn enter kết quả là khác nhau. Giá trị của trường biểu mẫu đang được ghi lại chỉ bằng vài chữ cái tôi đã nhập và do đó xác thực không thành công. Có vẻ như khi tôi nhấn phím enter để "chọn" email từ trình đơn thả xuống lịch sử, trình duyệt sẽ làm gián đoạn điều đó như thể tôi đang gõ.

Trong Chrome và Safari, nó hoạt động như mong muốn. Vì nó có nghĩa là khi bạn nhấn enter để "chọn" email từ danh sách thả xuống lịch sử, tất cả những gì nó làm là đặt địa chỉ email đó vào hộp văn bản. Chỉ khi nhấn phím ENTER lần thứ hai, nó sẽ kích hoạt trình quan sát sự kiện và email được xác thực.

Hy vọng ai đó có thể làm sáng tỏ lý do tại sao điều này xảy ra ... Cảm giác ruột của tôi là một điều trình duyệt và sẽ là thứ tôi không thể sửa được.

Cảm ơn Lee

EDIT: Để thêm làm rõ câu hỏi của tôi cho tôi thêm rằng Im bằng cách sử dụng "KeyDown" sự kiện để ghi lại khoảnh khắc khi vào phím được nhấn. Tôi đã thử sự kiện "keyup" và điều này giải quyết vấn đề của tôi ở trên, nhưng sau đó tôi không thể dường như ngừng các hình thức trình của chính nó. Sự kiện "keyup" kích hoạt SAU hành vi mặc định, do đó, nó không phải là lựa chọn đúng cho việc này.

EDIT THÊM:

Cảm ơn bạn một lần nữa, và btw, tiếng Anh của bạn là tuyệt vời (để đáp ứng với nhận xét của bạn về tiếng Anh xấu).

Tôi đã thay đổi xử lý sự kiện của tôi từ này:

$("emailInputBox").observe("keydown", function(event) { 
    return submitViaEnter(event, submitSignupFormOne); 
}); 

này:

$("emailInputBox").observe("keydown", function(event) { 
    setTimeout(submitViaEnter.curry(event, submitSignupFormOne),0); 
}); 

submitViaEnter:

function submitViaEnter(event, callback) { 
var code = event.keyCode; 
if (code == Event.KEY_RETURN) { 
    event.stop(); 
    return callback(event); 
} 
return true; 
} 

Dường như làm việc nhưng vấn đề bây giờ là trình duyệt được phép thực hiện hành động mặc định trước khi chạy submitViaEnter chức năng có nghĩa là biểu mẫu đang được gửi khi tôi nhấn ENTER.

Trả lời

6

trả lời cho câu hỏi ban

Vâng, đó là một lỗi Gecko (không Mac-cụ thể mặc dù).

The last part of this comment chứa mô tả về công việc xung quanh: sử dụng hết thời gian chờ.

[sửa] kể từ khi bạn yêu cầu làm rõ các lỗi

Khi bạn nhấn Enter và tự động hoàn tất được kích hoạt, Firefox (sai lầm) đầu tiên bắn xử lý chủ chốt của trang, sau đó chính nội bộ của Trình duyệt trình xử lý đóng cửa sổ bật lên tự động hoàn tất và cập nhật giá trị vùng văn bản, trong khi nó cho là chỉ nên kích hoạt nó ở cửa sổ bật lên tự động hoàn tất và chỉ cho phép trang biết giá trị của hộp văn bản đã thay đổi.

Điều này có nghĩa là khi trình xử lý khóa của bạn được gọi, trình xử lý tự động hoàn tất chưa chạy - cửa sổ bật lên tự động hoàn tất vẫn mở và giá trị hộp văn bản giống như trước khi quá trình tự động hoàn thành.

Khi bạn thêm lệnh gọi setTimeout vào trình xử lý khóa, bạn đang nói với trình duyệt "hey, hãy chạy hàm này ngay sau khi bạn hoàn thành công việc đã có trong danh sách công việc P1 của mình". Vì vậy, trình xử lý tự động hoàn tất chạy vì nó đã có trong danh sách việc cần làm, sau đó mã bạn đặt vào một thời gian chờ - khi cửa sổ bật lên tự động hoàn tất đã được đóng và giá trị của hộp văn bản được cập nhật.

[sửa] trả lời các câu hỏi trong "chỉnh sửa Hơn nữa"

Đúng vậy. Bạn cần phải hủy bỏ hành động mặc định trong xử lý sự kiện, không phải trong thời gian chờ, nếu bạn muốn nó để làm việc:

function onKeyPress(ev) { 
    if (... enter pressed ...) { 
    setTimeout(function() { 
     ... check the new textbox value after letting autocomplete work ... 
    }, 0); 
    // but cancel the default behavior (submitting the form) directly in the event listener 
    ev.preventDefault(); 
    return false; 
    } 
} 

Nếu bạn vẫn muốn gửi biểu mẫu trên Enter, nó sẽ là một bài tập thú vị hơn, nhưng có vẻ như bạn không làm.

+0

Cảm ơn !! Ive đã làm việc xung quanh nó bằng cách vô hiệu hóa chức năng tự động hoàn thành cho biểu mẫu nhưng tôi không thích nó. Bạn có biết "thời gian chờ" là gì không, và nếu có, bạn có thể xây dựng được không? Cảm ơn bạn lần nữa. –

+0

@LeeRM: trong trình xử lý gọi hàm setTimeout (handler2, 0) và di chuyển mã xác nhận của bạn vào | Hàm handler2() {} |. – Nickolay

+0

Tôi hiểu rồi. Im xin lỗi nếu Im đang dày ở đây. Chỉ khi tôi nghĩ rằng Im đang làm tốt công cụ này ... Kết quả của việc này là gì? Tôi biết nó khắc phục được vấn đề mà tôi có nhưng làm thế nào? Tôi thích hiểu những gì đang xảy ra. Cảm ơn sự giúp đỡ của bạn! –

2

ok đã sắp xếp. Cám ơn rất nhiều về sự giúp đỡ của bạn. Đó là chức năng cà ri mà tôi đã bỏ lỡ trước đây. Tôi đã cố gắng làm việc trên sự kiện bên trong phạm vi của hàm setTimeout.

Điều này hoạt động bên dưới. Các submitViaEnter được gọi là từ eventobserver và phản ứng với các sự kiện KeyDown:

function submitViaEnter(event, callback) { 
var code = event.keyCode; 
if (code == Event.KEY_RETURN) { 
    event.stop(); 
    setTimeout(callback.curry(event),0);   
    // return callback(event); 
    // return false;  
} 
return true; 
} 

Dừng hành động mặc định bên trong eventObserver có nghĩa là không có ký tự có thể được gõ. Vì vậy, tôi bị mắc kẹt bên trong nếu khoản ENTER phím.

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