Как установить фокус на первый элемент ввода в форме HTML независимо от идентификатора?

88

Есть ли простой способ установить фокус (курсор ввода) веб-страницы на первом элементе ввода (текстовое поле, раскрывающийся список, ...) при загрузке страницы без необходимости знать идентификатор элемента?

Я хотел бы реализовать его как общий сценарий для всех моих страниц / форм моего веб-приложения.

Splattne
источник
7
ЗАМЕТКА, если форма размещена на странице таким образом, чтобы пользователь мог прокрутить страницу вниз, чтобы увидеть форму, установка фокуса автоматически прокручивает страницу вниз, как при привязке. Это не очень хорошо, потому что пользователь, попавший на такую ​​страницу, сразу увидит, что она прокручивается вниз до позиции формы. Я тестировал в Safari и FF (IE7 не выполняет прокрутку страниц).
Marco Demaio 05
@Marco_Demaio Мое веб-приложение структурировано таким образом, что на каждой странице есть поля ввода в верхней части окна.
splattne 05
3
что, если бы пользователь изменил размер окна браузера до значения менее 768 пикселей. Страница будет прокручиваться до того места, где вы установили фокус. В любом случае, я хотел только предупредить вас на случай, если вы не знали о такой незначительной проблеме, я тоже не знал об этом до проведения некоторых тестов.
Марко Демайо,

Ответы:

97

Вы также можете попробовать метод на основе jQuery:

$(document).ready(function() {
    $('form:first *:input[type!=hidden]:first').focus();
});
Марко Думич
источник
Оно работает! Я начинаю интегрировать jQuery в свое веб-приложение. Итак, я думаю, что буду придерживаться этого подхода! Большое спасибо, Марко!
splattne
3
Что будет, если в этом случае первая форма на странице будет скрыта? Или если первый элемент формы скрыт через CSS? Конечно, это не удастся. Я, конечно, педантичен, но вот как катаюсь.
Джеймс Хьюз
В моем случае (с использованием ASP.NET) у меня есть только ОДНА форма, которая никогда не скрывается. Так что это работает для меня.
splattne
@Jame Hughes, вы можете написать его как функцию и вызывать ее, когда вам это нужно, и вы можете делать исключения. Мне это решение действительно помогло.
Люси
по какой-то причине это не работает для меня. я не должен видеть курсор.
Крис
141

Хотя это не отвечает на вопрос (требуется общий сценарий), я, хотя другим может быть полезно знать, что HTML5 вводит атрибут «автофокус»:

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

Подробнее об HTML5 .

Джейкоб Стэнли
источник
2
автофокус - это имя атрибута. Что насчет его значения? Что-то вроде autofocus = true не нужно? Что значит не устанавливать никакого значения?
Geek
4
В HTML5 для некоторых атрибутов не обязательно иметь значение, «checked» - еще один атрибут, в котором это так. Я считаю, что когда значение не указано, подразумевается, что оно совпадает с именем (например, autofocus = "autofocus" и checked = "checked").
Джейкоб Стэнли
Мое приложение Spring ломается, когда я пытаюсь использовать его autofocusбез значения spring:form. autofocus="autofocus"хотя работает нормально. Спасибо, @Jacob.
Сергей Таченов
2
@Geek Атрибут autofocus, как и многие другие, является логическим типом атрибута. Вот почему он используется только декларативно, а не путем присвоения ему значения. Подробнее см. В спецификации w3c: w3.org/TR/html5/infrastructure.html#boolean-attribute
n1kkou,
35
document.forms[0].elements[0].focus();

Это можно уточнить, используя цикл, например. не фокусировать определенные типы полей, отключенные поля и так далее. Лучше может быть , чтобы добавить класс = «автофокус» в поле вы на самом деле действительно сосредоточены хотите, и перебрать формы [я] .elements [J] ищет для этого Classname.

В любом случае: обычно не рекомендуется делать это на каждой странице. Когда вы фокусируете ввод, пользователь теряет возможность, например. прокрутите страницу с клавиатуры. Если неожиданно, это может раздражать, поэтому автоматическая фокусировка только тогда, когда вы уверены, что использование поля формы будет тем, что пользователь хочет сделать. т.е. если вы Google.

бобинс
источник
3
Должен быть правильный ответ, потому что в вопросе нет тега jquery.
Калле Х. Вяравас
@ KalleH.Väravas нет, за него следует проголосовать против, потому что он делает предположения, которые нигде не подлежат сомнению, например. есть хотя бы одна форма. Как правило, это не работает.
9ilsdx 9rvj 0lo 05
18

Наиболее полное выражение jQuery, которое я нашел работающим, - это (с помощью здесь )

$(document).ready(function() {
    $('input:visible:enabled:first').focus();
});
нгик
источник
1
Я использовал это, заметил, что он работает очень медленно в IE, когда в таблице имеется большое количество> 1000 флажков. Не уверен, что с этим делать, возможно, придется просто отказаться от фокусировки на первом поле ввода.
Сэм Уоткинс
7

Если вы используете платформу Prototype JavaScript, вы можете использовать метод focusFirstElement :

Form.focusFirstElement(document.forms[0]);
Джон Топли
источник
5

Вам также необходимо пропустить любые скрытые входы.

for (var i = 0; document.forms[0].elements[i].type == 'hidden'; i++);
document.forms[0].elements[i].focus();
Марко Думич
источник
Возможно, я ошибаюсь, но этот цикл не имеет определенного поведения, если в forms [0] нет скрытых входов.
xtofl
Точно. Он используется для пропуска любых ведущих скрытых входов. Причем написано в предположении, что в форме есть не скрытые поля. Я мог бы сделать это и с jQuery (я отправлю другой ответ), но вы не упомянули, что хотите задействовать jQuery.
Марко Думич
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 и проверки видимости каждого предка, что, на мой взгляд, является серьезным излишеством для такого рода ситуаций.
Джеймс Хьюз
А как насчет <input type = "text" readonly = "readonly"> Думаю, вам следует добавить такой случай в свой код. Обычно люди не хотят сосредотачиваться на текстовом поле ввода только для чтения. В любом случае хороший код и +1 спасибо!
Марко Демайо
Не тестировалось, но я обновил его с помощью !forms [i] [j] .readonly! = Undefined
Джеймс Хьюз
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, например, с обычным javascript:

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

работает в Safari, но не в Chrome 75 (апрель 2019 г.)

localhostdotdev
источник
0

С AngularJS:

angular.element('#Element')[0].focus();
ЭпокК
источник
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;
                }
            }
        }
    }   
}
thecoolmacdude
источник
0

Без сторонних библиотек используйте что-то вроде

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

Убедитесь, что вы учитываете все теги элементов формы, исключите скрытые / отключенные, как в других ответах, и так далее.

cghislai
источник