ฉันจะตั้งโฟกัสไปยังองค์ประกอบอินพุตแรกในรูปแบบ HTML ที่เป็นอิสระจาก id ได้อย่างไร


88

มีวิธีง่ายๆในการกำหนดโฟกัส (อินพุตเคอร์เซอร์) ของหน้าเว็บในองค์ประกอบอินพุตแรก (กล่องข้อความ, รายการแบบเลื่อนลง, ... ) ในการโหลดหน้าโดยไม่ต้องทราบรหัสขององค์ประกอบหรือไม่

ฉันต้องการใช้มันเป็นสคริปต์ทั่วไปสำหรับทุกหน้า / ทุกรูปแบบของเว็บแอปพลิเคชันของฉัน


7
โปรดจำไว้ว่าหากวางแบบฟอร์มลงในหน้าในลักษณะที่ผู้ใช้ต้องเลื่อนหน้าลงเพื่อดูแบบฟอร์มโดยการตั้งค่าโฟกัสจะเลื่อนหน้าลงโดยอัตโนมัติเช่นเดียวกับจุดยึด สิ่งนี้ไม่ดีนักเนื่องจากผู้ใช้ที่เข้าสู่หน้าดังกล่าวจะเห็นว่ามันถูกเลื่อนลงไปที่ตำแหน่งแบบฟอร์มทันที ฉันทดสอบบน Safari และ FF (IE7 ไม่ทำการเลื่อนหน้า)
Marco Demaio

@Marco_Demaio เว็บแอปของฉันมีโครงสร้างในลักษณะที่ทุกหน้ามีช่องป้อนข้อมูลอยู่ใกล้ด้านบนของหน้าต่าง
splattne

3
จะเกิดอะไรขึ้นถ้าผู้ใช้ปรับขนาดความสูงของหน้าต่างเบราว์เซอร์ให้เล็กกว่า 768px หน้าจะเลื่อนไปยังตำแหน่งที่คุณตั้งโฟกัส อย่างไรก็ตามฉันต้องการเพียงเตือนคุณในกรณีที่คุณไม่ทราบเกี่ยวกับปัญหาเล็กน้อยดังกล่าวฉันไม่รู้เกี่ยวกับเรื่องนี้ก่อนที่จะทำการทดสอบบางอย่าง
Marco Demaio

คำตอบ:


97

คุณยังสามารถลองใช้วิธีที่ใช้ jQuery:

$(document).ready(function() {
    $('form:first *:input[type!=hidden]:first').focus();
});

มันได้ผล! ฉันกำลังเริ่มรวม jQuery ในเว็บแอปพลิเคชันของฉัน ดังนั้นฉันคิดว่าฉันจะยึดแนวทางนี้! ขอบคุณมาก Marko!
splattne

3
จะเกิดอะไรขึ้นถ้าแบบฟอร์มแรกในเพจถูกซ่อนไว้ในกรณีนี้? หรือหากองค์ประกอบแรกในแบบฟอร์มถูกซ่อนผ่าน CSS? แน่นอนว่าสิ่งนี้จะล้มเหลว แน่นอนว่าฉันเป็นคนอวดดี แต่นั่นคือวิธีที่ฉันหมุน
James Hughes

ในกรณีของฉัน (โดยใช้ ASP.NET) ฉันมีเพียงรูปแบบเดียวที่ไม่เคยถูกซ่อน สิ่งนี้ใช้ได้กับฉัน
splattne

@Jame Hughes คุณสามารถเขียนเป็นฟังก์ชันและเรียกใช้เมื่อคุณต้องการและคุณสามารถสร้างข้อยกเว้นได้ สำหรับฉันวิธีนี้ช่วยได้มาก
Luci

สิ่งนี้ใช้ไม่ได้สำหรับฉันด้วยเหตุผลบางประการ ฉันไม่ควรเห็นเคอร์เซอร์
คริส

141

แม้ว่าสิ่งนี้จะไม่ตอบคำถาม (ต้องใช้สคริปต์ทั่วไป) แต่ฉันอาจมีประโยชน์สำหรับคนอื่นที่รู้ว่า HTML5 แนะนำแอตทริบิวต์ "ออโต้โฟกัส":

<form>
  <input type="text" name="username" autofocus>
  <input type="password" name="password">
  <input type="submit" value="Login">
</form>

เจาะลึก HTML5มีข้อมูลเพิ่มเติม


2
ออโต้โฟกัสเป็นแอตทริบิวต์ แล้วค่าของมันล่ะบางอย่างเช่นออโต้โฟกัส = จริงไม่จำเป็น? การไม่ตั้งค่าใด ๆ หมายความว่าอย่างไร
Geek

4
ใน HTML5 แอตทริบิวต์บางอย่างไม่จำเป็นต้องมีค่า "ตรวจสอบ" เป็นแอตทริบิวต์อื่นในกรณีนี้ ฉันเชื่อว่าเมื่อปิดค่านี้จะบอกเป็นนัยว่าค่านั้นเหมือนกับชื่อ (เช่นออโต้โฟกัส = "ออโต้โฟกัส" และกาเครื่องหมาย = "ตรวจสอบ")
เจคอบสแตนลีย์

ฤดูใบไม้ผลิแบ่ง app ของฉันเมื่อฉันพยายามที่จะใช้ที่มีค่าไม่มีในautofocus ทำงานได้ดีแม้ว่า ขอบคุณ @Jacob spring:formautofocus="autofocus"
Sergei Tachenov

2
@Geek แอตทริบิวต์ออโต้โฟกัสเป็นแอตทริบิวต์ประเภทบูลีน นั่นเป็นเหตุผลว่าทำไมจึงใช้ในลักษณะที่เปิดเผยเท่านั้นไม่ใช่โดยการกำหนดค่าให้กับมัน ดูรายละเอียดเพิ่มเติมใน w3c spec: w3.org/TR/html5/infrastructure.html#boolean-attribute
n1kkou

35
document.forms[0].elements[0].focus();

สิ่งนี้สามารถปรับแต่งได้โดยใช้การวนซ้ำเพื่อเช่น ไม่เน้นฟิลด์บางประเภทฟิลด์ที่ปิดใช้งานและอื่น ๆ ที่ดีกว่าคือการเพิ่ม class = "autofocus" ลงในช่องที่คุณทำจริงต้องการที่มุ่งเน้นและห่วงมากกว่ารูปแบบ [ผม] .elements [เจ] มองหา className ว่า

อย่างไรก็ตามปกติแล้วไม่ใช่ความคิดที่ดีที่จะทำในทุกหน้า เมื่อคุณโฟกัสอินพุตผู้ใช้จะสูญเสียความสามารถเช่น เลื่อนหน้าจากแป้นพิมพ์ หากไม่คาดคิดอาจเป็นเรื่องที่น่ารำคาญดังนั้นการโฟกัสอัตโนมัติก็ต่อเมื่อคุณค่อนข้างแน่ใจว่าการใช้ฟิลด์ฟอร์มจะเป็นสิ่งที่ผู้ใช้ต้องการทำ กล่าวคือ. ถ้าคุณเป็น Google


3
ควรเป็นคำตอบที่ถูกต้องเนื่องจากคำถามไม่มีแท็ก jquery
Kalle H. Väravas

@ KalleH.Väravasไม่ควรลงคะแนนเนื่องจากทำให้สมมติฐานที่ไม่มีที่ใดที่จะพบในคำถามเช่น มีอย่างน้อยหนึ่งรูปแบบ โดยทั่วไปจะไม่ทำงาน
9ilsdx 9rvj 0lo

18

นิพจน์ jQuery ที่ครอบคลุมที่สุดที่ฉันพบว่าใช้งานได้คือ (ผ่านความช่วยเหลือจากตรงนี้ )

$(document).ready(function() {
    $('input:visible:enabled:first').focus();
});

1
ฉันใช้สิ่งนี้สังเกตเห็นว่ามันทำงานช้ามากบน IE เมื่อมีช่องทำเครื่องหมายจำนวนมาก> 1,000 ช่องในตาราง ไม่แน่ใจว่าจะทำอย่างไรกับมันอาจต้องเลิกโฟกัสช่องป้อนข้อมูลแรก
Sam Watkins



5

คุณต้องข้ามอินพุตที่ซ่อนอยู่ด้วย

for (var i = 0; document.forms[0].elements[i].type == 'hidden'; i++);
document.forms[0].elements[i].focus();

ฉันอาจจะผิด แต่ลูปนี้ไม่ได้กำหนดพฤติกรรมถ้าฟอร์ม [0] ไม่มีอินพุตที่ซ่อนอยู่
xtofl

ตรง ใช้เพื่อข้ามอินพุตที่ซ่อนอยู่ชั้นนำใด ๆ และมันถูกเขียนขึ้นภายใต้สมมติฐานว่ามีฟิลด์ที่ไม่ได้ซ่อนอยู่ในแบบฟอร์ม ฉันสามารถทำได้ด้วย jQuery เช่นกัน (ฉันจะโพสต์คำตอบอื่น) แต่คุณไม่ได้ระบุว่าคุณต้องการให้ jQuery เกี่ยวข้อง
Marko Dumic

1
@MarkoDumic ทำไมต้องเปลืองหน่วยความจำถ้าคุณสามารถใช้whileคำสั่ง?
Lucio

3

การวางโค้ดนี้ไว้ที่ส่วนท้ายของbodyแท็กจะเน้นองค์ประกอบที่เปิดใช้งานที่มองเห็นได้และไม่ได้ซ่อนเป็นครั้งแรกบนหน้าจอโดยอัตโนมัติ มันจะจัดการกับกรณีส่วนใหญ่ที่ฉันสามารถแจ้งให้ทราบสั้น ๆ

<script>
    (function(){
        var forms = document.forms || [];
        for(var i = 0; i < forms.length; i++){
            for(var j = 0; j < forms[i].length; j++){
                if(!forms[i][j].readonly != undefined && forms[i][j].type != "hidden" && forms[i][j].disabled != true && forms[i][j].style.display != 'none'){
                    forms[i][j].focus();
                    return;
                }
            }
        }
    })();
</script>

1
สิ่งหนึ่งที่ควรพิจารณาคือมันอาจจะเข้ากับองค์ประกอบที่ไม่ได้ซ่อนอยู่ แต่บรรพบุรุษคือ นั่นจะต้องมีการติดตามการสำรองข้อมูล DOM และทดสอบการมองเห็นของบรรพบุรุษแต่ละคนซึ่งฉันรู้สึกว่าเกินความจริงสำหรับสถานการณ์แบบนี้
James Hughes

แล้ว <input type = "text" readonly = "readonly"> ฉันคิดว่าคุณควรเพิ่มกรณีดังกล่าวลงในโค้ดของคุณ โดยปกติผู้คนไม่ต้องการโฟกัสที่ช่องข้อความป้อนข้อมูลแบบอ่านอย่างเดียว ยังไงก็รหัสที่ดีและขอบคุณ +1!
Marco Demaio

ยังไม่ทดสอบ แต่ฉันอัปเดตด้วย! แบบฟอร์ม [i] [j] .readonly! = undefined
James Hughes


3

ฉันใช้สิ่งนี้:

$("form:first *:input,select,textarea").filter(":not([readonly='readonly']):not([disabled='disabled']):not([type='hidden'])").first().focus();

2

สิ่งนี้จะรับอินพุตทั่วไปที่มองเห็นได้เป็นครั้งแรกรวมถึงพื้นที่ข้อความและกล่องเลือก นอกจากนี้ยังช่วยให้แน่ใจว่าไม่ได้ซ่อนปิดใช้งานหรืออ่านอย่างเดียว นอกจากนี้ยังอนุญาตให้มี div เป้าหมายซึ่งฉันใช้ในซอฟต์แวร์ของฉัน (เช่นอินพุตแรกในแบบฟอร์มนี้)

$("input:visible:enabled:not([readonly]),textarea:visible:enabled:not([readonly]),select:visible:enabled:not([readonly])", 
    target).first().focus();

1

สำหรับผู้ที่ใช้ JSF2.2 + และไม่สามารถส่งต่อออโต้โฟกัสเป็นแอตทริบิวต์ที่ไม่มีค่าให้ใช้สิ่งนี้:

 p:autofocus="true"

และเพิ่มลงในเนมสเปซ p (มักใช้ pt. อะไรก็ได้ที่คุณต้องการ)

<html ... xmlns:p="http://java.sun.com/jsf/passthrough">

1

ไม่มี jquery เช่นด้วยจาวาสคริปต์ปกติ:

document.querySelector('form input:not([type=hidden])').focus()

ใช้งานได้กับ Safari แต่ไม่ใช่ Chrome 75 (เมษายน 2019)



0

ซึ่งรวมถึงพื้นที่ข้อความและไม่รวมปุ่มตัวเลือก

$(document).ready(function() {
    var first_input = $('input[type=text]:visible:enabled:first, textarea:visible:enabled:first')[0];
    if(first_input != undefined){ first_input.focus(); }
});

0

คุณควรจะใช้ clientHeight แทนการตรวจสอบแอตทริบิวต์ display ได้เนื่องจากผู้ปกครองอาจซ่อนองค์ประกอบนี้:

function setFocus() {
    var forms = document.forms || [];
        for (var i = 0; i < forms.length; i++) {
            for (var j = 0; j < forms[i].length; j++) {
            var widget = forms[i][j];
                if ((widget && widget.domNode && widget.domNode.clientHeight > 0) && typeof widget.focus === "function")
                 && (typeof widget.disabled === "undefined" || widget.disabled === false)
                 && (typeof widget.readOnly === "undefined" || widget.readOnly === false)) {
                        widget.focus();
                        break;
                }
            }
        }
    }   
}

0

หากไม่มี libs ของบุคคลที่สามให้ใช้สิ่งที่ต้องการ

  const inputElements = parentElement.getElementsByTagName('input')
  if (inputChilds.length > 0) {
    inputChilds.item(0).focus();
  }

ตรวจสอบให้แน่ใจว่าคุณได้พิจารณาแท็กองค์ประกอบของฟอร์มทั้งหมดตัดแท็กที่ซ่อน / ปิดใช้งานเหมือนในคำตอบอื่น ๆ เป็นต้น ..

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.