Làm cách nào để đặt tiêu điểm thành phần tử đầu vào đầu tiên trong biểu mẫu HTML độc lập với id?


84

Có cách nào đơn giản để đặt tiêu điểm (con trỏ đầu vào) của trang web trên phần tử đầu vào đầu tiên (hộp văn bản, danh sách thả xuống, ...) khi tải trang mà không cần biết id của phần tử đó không?

Tôi muốn triển khai nó như một tập lệnh chung cho tất cả các trang / biểu mẫu ứng dụng web của tôi.


7
LƯU Ý nếu biểu mẫu được đặt xuống trang theo cách người dùng phải cuộn xuống trang để xem biểu mẫu, bằng cách đặt tiêu điểm sẽ tự động cuộn xuống trang giống như một ký tự liên kết sẽ làm. Điều này không tốt lắm vì người dùng truy cập trang như vậy sẽ thấy nó ngay lập tức được cuộn xuống vị trí biểu mẫu. Tôi đã thử nghiệm trên Safari và FF (IE7 không thực hiện việc cuộn trang).
Marco Demaio

@Marco_Demaio Ứng dụng web của tôi được cấu trúc theo cách mà mọi trang đều có các hộp nhập ở gần đầu cửa sổ.
splattne

3
điều gì sẽ xảy ra nếu người dùng thay đổi kích thước chiều cao cửa sổ trình duyệt thành một thứ gì đó nhỏ hơn 768px. Trang sẽ cuộn đến nơi bạn đặt tiêu điểm. Dù sao tôi chỉ muốn cảnh báo bạn trong trường hợp bạn không biết về vấn đề nhỏ như vậy, tôi cũng không biết về nó trước khi thực hiện một số thử nghiệm.
Marco Demaio

Câu trả lời:


96

Bạn cũng có thể thử phương pháp dựa trên jQuery:

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

Nó hoạt động! Tôi đang bắt đầu tích hợp jQuery vào ứng dụng web của mình. Vì vậy, tôi nghĩ rằng tôi sẽ gắn bó với cách tiếp cận này! Cảm ơn rất nhiều, Marko!
splattne

3
Điều gì xảy ra nếu biểu mẫu đầu tiên trên trang bị ẩn trong trường hợp này? Hoặc nếu phần tử đầu tiên trên biểu mẫu bị ẩn qua CSS? Chắc chắn điều này sẽ thất bại. Tất nhiên, tôi đang trở nên khổng lồ nhưng đó là cách tôi lăn lộn.
James Hughes

Trong trường hợp của tôi (sử dụng ASP.NET), tôi chỉ có MỘT biểu mẫu không bao giờ bị ẩn. Vì vậy, điều này làm việc cho tôi.
splattne

@Jame Hughes, bạn có thể viết nó dưới dạng một hàm và gọi nó khi bạn cần, và bạn có thể đặt ngoại lệ. Đối với tôi giải pháp này thực sự hữu ích.
Luci

điều này không làm việc cho tôi vì một số lý do. tôi không nên nhìn thấy một con trỏ.
Chris

136

Mặc dù điều này không trả lời câu hỏi (yêu cầu một tập lệnh chung), tôi mặc dù có thể hữu ích cho những người khác khi biết rằng HTML5 giới thiệu thuộc tính 'tự động lấy nét':

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

Tìm hiểu thêm về HTML5 để có thêm thông tin.


2
tự động lấy nét là tên thuộc tính. Còn giá trị của nó thì sao? Một số ví dụ như autofocus = true không cần thiết? Không đặt bất kỳ giá trị nào có nghĩa là gì?
Geek

4
Trong HTML5, một số thuộc tính không cần phải có giá trị, 'đã kiểm tra' là một thuộc tính khác trong trường hợp này. Tôi tin rằng khi giá trị bị bỏ đi, nó được ngụ ý rằng nó giống như tên (ví dụ: autofocus = "autofocus" và check = "đã kiểm tra").
Jacob Stanley

Ứng dụng Spring của tôi bị hỏng khi tôi cố gắng sử dụng autofocusmà không có giá trị spring:form. autofocus="autofocus"hoạt động tốt, mặc dù. Cảm ơn, @Jacob.
Sergei Tachenov

2
@Geek Thuộc tính tự động lấy nét, cũng như nhiều thuộc tính khác, là một loại thuộc tính boolean. Đó là lý do tại sao nó chỉ được sử dụng theo cách khai báo, không phải bằng cách gán giá trị cho nó. Xem thêm chi tiết trong thông số kỹ thuật w3c: w3.org/TR/html5/infraosystem.html#boolean-attribute
n1kkou

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

Điều này có thể được tinh chỉnh bằng cách sử dụng một vòng lặp để ví dụ. không tập trung vào một số loại trường nhất định, trường bị vô hiệu hóa, v.v. Tốt hơn có thể để thêm một class = "tự động lấy nét" đến lĩnh vực bạn thực sự làm muốn tập trung, và vòng lặp so với các dạng [i] .elements [j] tìm kiếm className đó.

Nhưng dù sao thì: thông thường không phải là ý kiến ​​hay khi làm điều này trên mọi trang. Khi bạn tập trung một đầu vào, người dùng sẽ mất khả năng ví dụ. cuộn trang từ bàn phím. Nếu không mong muốn, điều này có thể gây phiền nhiễu, vì vậy chỉ tự động lấy nét khi bạn khá chắc chắn rằng việc sử dụng trường biểu mẫu sẽ là điều người dùng muốn làm. I E. nếu bạn là Google.


3
Phải là câu trả lời chính xác, vì câu hỏi không có thẻ jquery.
Kalle H. Väravas

@ KalleH.Väravas không, nó nên bị từ chối vì nó đưa ra các giả định không có ở đâu trong câu hỏi, ví dụ. có ít nhất một biểu mẫu. Nói chung, nó không hoạt động.
9ilsdx 9rvj 0lo

18

Biểu thức jQuery toàn diện nhất mà tôi thấy đang hoạt động là (thông qua sự trợ giúp ở đây )

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

1
Tôi đang sử dụng cái này, nhận thấy nó chạy cực kỳ chậm trên IE khi có một số lượng lớn> 1000 hộp kiểm trong một bảng. Không chắc phải làm gì với nó, có thể phải từ bỏ việc tập trung vào trường đầu vào đầu tiên.
Sam Watkins



5

Bạn cũng cần bỏ qua bất kỳ đầu vào ẩn nào.

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

Tôi có thể sai, nhưng vòng lặp này không có hành vi được xác định nếu biểu mẫu [0] không có đầu vào ẩn.
xtofl

Chính xác. Nó được sử dụng để bỏ qua bất kỳ đầu vào ẩn hàng đầu nào. Và nó được viết dưới giả định rằng có các trường không ẩn trong biểu mẫu. Tôi cũng có thể làm điều đó với jQuery (tôi sẽ đăng một câu trả lời khác) nhưng bạn không đề cập đến việc bạn muốn jQuery tham gia.
Marko Dumic

1
@MarkoDumic Tại sao lại lãng phí bộ nhớ nếu bạn có thể sử dụng một whilecâu lệnh?
Lucio

3

Đặt mã này vào cuối bodythẻ của bạn sẽ tự động tập trung phần tử được kích hoạt không ẩn, có thể nhìn thấy đầu tiên trên màn hình. Nó sẽ xử lý hầu hết các trường hợp tôi có thể đưa ra trong thời gian ngắn.

<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
Một điều cần xem xét ở đây là nó có thể phù hợp với các yếu tố không phải là bản thân chúng ẩn nhưng là tổ tiên. Điều đó sẽ yêu cầu theo dõi sao lưu DOM và kiểm tra khả năng hiển thị của từng tổ tiên mà tôi cảm thấy là quá mức cần thiết nghiêm trọng đối với loại tình huống này.
James Hughes

Còn về <input type = "text" readonly = "readonly"> Tôi nghĩ bạn nên thêm một trường hợp như vậy vào mã của mình. Thông thường mọi người không muốn tập trung vào trường văn bản đầu vào chỉ đọc. Dù sao mã đẹp và +1 cảm ơn!
Marco Demaio

Chưa được kiểm tra nhưng tôi đã cập nhật nó bằng! Form [i] [j] .readonly! = Undefined
James Hughes


3

Tôi đang sử dụng cái này:

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

2

Điều này nhận được đầu tiên của bất kỳ đầu vào chung nào có thể nhìn thấy, bao gồm các textareas và các hộp chọn. Điều này cũng đảm bảo chúng không bị ẩn, bị vô hiệu hóa hoặc chỉ đọc. nó cũng cho phép một div đích mà tôi sử dụng trong phần mềm của mình (tức là, đầu vào đầu tiên bên trong biểu mẫu này).

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

1

Đối với những người sử dụng JSF2.2 + và không thể chuyển tự động lấy nét làm thuộc tính không có giá trị của nó, hãy sử dụng điều này:

 p:autofocus="true"

Và thêm nó vào không gian tên p (Cũng thường dùng pt. Bất cứ thứ gì bạn thích).

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

0

Với AngularJS:

angular.element('#Element')[0].focus();

0

Điều này bao gồm các textareas và không bao gồm các nút radio

$(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

Bạn có thể sử dụng clientHeight thay vì kiểm tra thuộc tính display, vì cha mẹ có thể đang ẩn phần tử này:

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

Nếu không có lib của bên thứ ba, hãy sử dụng những thứ như

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

Đảm bảo rằng bạn xem xét tất cả các thẻ phần tử biểu mẫu, loại trừ những thẻ bị ẩn / bị vô hiệu hóa như trong các câu trả lời khác, v.v.


0

không có jquery, ví dụ với javascript thông thường:

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

hoạt động trên Safari nhưng không hoạt động trên Chrome 75 (tháng 4 năm 2019)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.