[英]How do I convert Enter to Tab (with focus change) in IE9? It worked in IE8
我有一個帶有onkeydown事件處理程序的文本輸入,它通過將事件的keyCode從13更改為9來將<Enter>轉換為<Tab>。
<input type="text" onkeydown="enterToTab(event);" onchange="changeEvent(this);"
name="" value="" />
<!-- Other inputs exist as created via the DOM, but they are not sibling elements. -->
使用Javascript:
function enterToTab(myEvent) {
if (myEvent.keyCode == 13) {
myEvent.keyCode = 9;
}
}
function changeEvent(myInput) { var test = "hello"; }
在IE8中,這導致onchange事件觸發,但在IE9中不會發生這種情況。 相反,輸入字段保留焦點。 我怎么能做到這一點? (它適用於Firefox 3.6和Chrome 10.0。)如果我將文檔模式設置為“IE8標准”,這甚至可以在瀏覽器模式IE9中使用。 但它不適用於“IE9標准”的文檔模式。 (我的DocType是XHTML 1.0 Transitional。)
由於它適用於IE7和8,這可能是IE9中的一個錯誤,將被修復?
請注意:我不能使用input.blur()
或手動設置新焦點 ,這是我讀過的所有其他解決方案的建議。 我已經嘗試過onkeypress和onkeyup而沒有運氣。 我需要一個通用的解決方案,它會使Web應用程序表現得像我點擊<Tab>一樣。 另外,我沒有jQuery,但Dojo 1.5可供我使用。
還要注意:我知道這是“錯誤的”行為,並且輸入應該提交表單。 但是,我的客戶的工作人員最初來自綠屏環境,其中Enter在字段之間移動它們。 我們必須保留相同的UI。 就是這樣。
更新:我發現IE8和IE9之間存在差異。 在IE8中,我的myEvent.keyCode
設置成立。 在IE9中,它沒有。 我可以更新window.event.keyCode
,它會保留,但這不會影響以后發生的事情。 唉...有什么想法嗎?
看起來IE9事件是不可變的。 一旦它們被解雇,你就無法改變它們的屬性,只需要使用preventDefault()或取消它們。 因此,您最好的選擇是取消任何“輸入”事件並從文本輸入重新分配新的DOM事件。
例
function enterToTab(event){
if(event.keyCode == 13){
var keyEvent = document.createEvent("Event");
// This is a lovely method signature
keyEvent.initKeyboardEvent("onkeydown", true, true, window, 9, event.location, "", event.repeat, event.locale);
event.currentTarget.dispatchEvent(keyEvent);
// you may want to prevent default here
}
}
這是關於IE9 DOM事件的MSDN文檔:
事件對象 - http://msdn.microsoft.com/en-us/library/ms535863(v=vs.85).aspx
createEvent - http://msdn.microsoft.com/en-us/library/ff975304(v=vs.85).aspx
初始化鍵盤事件 - http://msdn.microsoft.com/en-us/library/ff975297(v=vs.85).aspx
以前的IE版本允許非標准的可寫event.keyCode
屬性,IE9現在符合標准。
您可能需要考慮以下功能 :您希望使輸入鍵的行為類似於Tab鍵,即將焦點移動到下一個(文本)輸入字段。 還有更多方法可以做到這一點。 其中一個是使用文本輸入字段的tabindex
屬性。 如果使用此tabindex屬性在表單中排序字段,則此處顯示的函數可能會產生與先前keyCode方法相同的結果。 這是我在這個jsfiddle中測試的兩個函數。 (文本)輸入字段現在看起來像:
<input type="text"
onkeypress="nextOnEnter(this,event);"
name="" value=""
tabindex="1"/>
用於制表的功能:
function nextOnEnter(obj,e){
e = e || event;
// we are storing all input fields with tabindex attribute in
// a 'static' field of this function using the external function
// getTabbableFields
nextOnEnter.fields = nextOnEnter.fields || getTabbableFields();
if (e.keyCode === 13) {
// first, prevent default behavior for enter key (submit)
if (e.preventDefault){
e.preventDefault();
} else if (e.stopPropagation){
e.stopPropagation();
} else {
e.returnValue = false;
}
// determine current tabindex
var tabi = parseInt(obj.getAttribute('tabindex'),10);
// focus to next tabindex in line
if ( tabi+1 < nextOnEnter.fields.length ){
nextOnEnter.fields[tabi+1].focus();
}
}
}
// returns an array containing all input text/submit fields with a
// tabindex attribute, in the order of the tabindex values
function getTabbableFields(){
var ret = [],
inpts = document.getElementsByTagName('input'),
i = inpts.length;
while (i--){
var tabi = parseInt(inpts[i].getAttribute('tabindex'),10),
txtType = inpts[i].getAttribute('type');
// [txtType] could be used to filter out input fields that you
// don't want to be 'tabbable'
ret[tabi] = inpts[i];
}
return ret;
}
如果您不想使用tabindex並且所有輸入字段都是'tabbable', 請參閱此jsfiddle
[ 編輯 ]編輯了函數(參見jsfiddles)以利用事件委托,並使其在Opera中也能正常工作。 這個版本也模仿shift-TAB。
這是一個不同的想法; 更改提交,以便它調用函數而不是處理表單。 在函數中檢查所有字段以查看它們是否為空,然后關注下一個沒有值的字段。
因此,他們在字段1中鍵入一個值,按Enter鍵,然后運行該函數。 它看到字段1已滿,但字段2未滿,因此請關注字段2。
然后,當所有字段都已滿時,提交表單進行處理。
如果表單具有可以為空的字段,則可以使用布爾數組來跟蹤使用onfocus()事件接收焦點的字段。
只是一個外面的想法。
上面的代碼會導致問題。 這里有一些可以幫助你的代碼。 適用於IE9,FF5等
function getNextElement(field) {
var form = field.form;
for ( var e = 0; e < form.elements.length; e++) {
if (field == form.elements[e]) {
break;
}
}
return form.elements[++e % form.elements.length];
}
function tabOnEnter(field, evt) {
if (evt.keyCode === 13) {
if (evt.preventDefault) {
evt.preventDefault();
} else if (evt.stopPropagation) {
evt.stopPropagation();
} else {
evt.returnValue = false;
}
getNextElement(field).focus();
return false;
} else {
return true;
}
}
然后你應該創建輸入文本或其他任何東西
<input type="text" id="1" onkeydown="return tabOnEnter(this,event)"/>
<input type="text" id="2" onkeydown="return tabOnEnter(this,event)"/>
<input type="text" id="3" onkeydown="return tabOnEnter(this,event)"/>
<input type="text" id="4" onkeydown="return tabOnEnter(this,event)"/>
頁面上的<button>
元素將導致此問題。
在IE9中,按下Enter鍵時, <button>
元素將獲得焦點。 任何提交或重置按鈕也會導致問題。 如果您沒有使用提交/重置,則可以通過將所有按鈕更改為<input type="button">
或將按鈕的類型屬性設置為按鈕來解決此問題。 即
<button type="button">Click me!</button>
或者根據KooiInc的回答,您可以編輯您的javascript以使用event.preventDefault();
防止Enter鍵以這種方式動作,並在Tab鍵順序中的下一個元素上顯式調用focus()。
下面是我編寫的一些測試代碼,演示了按鈕元素的問題(注意IE9中button3上的藍色焦點環):
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>IE problem with Enter key and <button> elements</title>
</head>
<body>
<script>
function press(event) {
if (event.keyCode == 13) {
document.getElementById('input2').focus();
// In IE9 the focus shifts to the <button> unless we call preventDefault(). Uncomment following line for IE9 fix. Alternatively set type="button" on all button elements and anything else that is a submit or reset too!.
// event.preventDefault && event.preventDefault();
}
}
</script>
<input id="input1" type="text" onkeypress="press(event)" value="input1. Press enter here." /><br />
<input id="input2" type="text" value="input2. Press enter here." /><br />
<input id="button1" type="button" value='I am an <input type="button">' /><br />
<button id="button2" type="button">I am a <button type="button"></button><br />
<button id="button3">I am a <button>. I get focus when enter key pressed in IE9 - wooot!</button><span>As per Microsoft docs on <a target="_tab" href="http://msdn.microsoft.com/en-us/library/ms534696%28v=vs.85%29.aspx">BUTTON.type</a> it is because type defaults to submit.</span>
</body>
</html>
Mike Fdz的代碼非常棒。 為了跳過隱藏的字段,您可能想要更改該行
return form.elements[++e % form.elements.length];
對此:
e++;
while (form.elements[e % form.elements.length].type == "hidden") {
e++;
}
return form.elements[e % form.elements.length];
使用onpaste和onkeypress一樣
考慮你已經編寫了一個javascript函數來檢查文本長度,所以我們需要在按鍵上驗證它,如下所示
<asp:TextBox ID="txtInputText" runat="server" Text="Please enter some text" onpaste="return textboxMultilineMaxNumber(this,1000);" onkeypress="return textboxMultilineMaxNumber(this,1000);"></asp:TextBox>
onkeypress將在FF和IE中工作
但如果你嘗試在文本框中執行ctr + V,那么onpaste將在FF中處理onkeypress處理它
要防止在IE9中的表單中由Enter-Keyboard觸發“提交事件”,請退出表單區域內的任何按鈕。 將他(按鈕)放在表格區域的外面。
function enterAsTab() { var keyPressed = event.keyCode; // get the Key that is pressed if (keyPressed == 13) { //case the KeyPressed is the [Enter] var inputs = $('input'); // storage a array of Inputs var a = inputs.index(document.activeElement); //get the Index of Active Element Input inside the Inputs(array) if (inputs[a + 1] !== null) { // case the next index of array is not null var nextBox = inputs[a + 1]; nextBox.focus(); // Focus the next input element. Make him an Active Element event.preventDefault(); } return false; } else {return keyPressed;} }
<HTML> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <body onKeyPress="return enterAsTab();"> <input type='text' /> <input type='text' /> <input type='text' /> <input type='text' /> <input type='text' /> </body> </HTML>
這就是我通過互聯網所做的事情:
function stopRKey(evt)
{
var evt = (evt) ? evt : ((event) ? event : null);
var node = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null);
if ((evt.keyCode == 13) && ((node.type=="text") || (node.type=="radio")))
{
getNextElement(node).focus();
return false;
}
}
function getNextElement(field)
{
var form = field.form;
for ( var e = 0; e < form.elements.length; e++) {
if (field == form.elements[e]) {
break;
}
}
e++;
while (form.elements[e % form.elements.length].type == "hidden")
{
e++;
}
return form.elements[e % form.elements.length];;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.