Настройка фокуса на элемент ввода после настройки отображения: блок - PullRequest
2 голосов
/ 09 сентября 2009

У меня есть HTML-код в следующих строках:

<div class="hiddenClass"> // this implies display:none
 <span>
    <input type="text" id="hiddenInput"/>
 </span>
</div>

и событие Javascript (запускаемое методом "succes" при вызове jQuery $ .ajax ()), которое должно сделать этот div видимым, а затем установить фокус на элемент управления. Что-то вроде:

 this.DOMElements.divElement.className="showClass"; //a CSS class with display:block;
 this.DOMElements.hiddenInputElement.focus();
 this.DOMElements.hiddenInputElement.select();

Как ни странно, этот код работает только часть времени. В некоторых случаях (только иногда !!) команды focus / select генерируют предупреждения о фокусировке / выборе невидимого элемента управления. Элемент управления будет сделан видимым, но фокус не будет перемещен, а текст не выделен.

Я нашел (в некоторой степени) решение, переместив код фокусировки / выбора в отдельную функцию и вызвав его с помощью

.
this.DOMElements.divElement.className="showClass"; //a CSS class with display:block;
setTimeout("focusinput('hidddenInput')",1);

Хорошо, наконец, мой вопрос: так как javascript является однопоточным ... как получилась задержка между временем, когда я сделал родительский div видимым, и временем, когда я могу установить фокус / выбор на дочернем элементе ввода? Как это может быть состояние гонки?

Редактировать: происходит в IE8

Ответы [ 4 ]

1 голос
/ 10 сентября 2009

Хорошо, наконец, мой вопрос: так как javascript является однопоточным ... как получается, что между временем, когда я сделал родительский div видимым, и временем, которое я могу установить фокус / выбор для дочернего элемента ввода? 1002 *

Вы только что ответили на свой вопрос: это происходит , потому что JS является однопоточным; то есть он блокирует браузер от обновления своего рендеринга до тех пор, пока скрипт не завершит выполнение.

Итак, когда вы выполняете код:

divElement.className="showClass";

свойство className элемента обновлено, но, поскольку ваш скрипт все еще выполняется, элемент не сразу перерисовывается как видимый. Поэтому при выполнении

hiddenInputElement.focus();

элемент все еще скрыт, и вы получаете ошибку.

Итак, в вашей первой версии последовательность выполнения в одном потоке:

  1. Сценарий устанавливает className;
  2. Сценарий устанавливает фокус;
  3. Браузер выдает исключение, потому что сфокусированный элемент скрыт;
  4. Сценарий заканчивается из-за ошибки;
  5. Браузер обновляет данные, основываясь на изменениях, сделанных скриптом, до момента отказа.

При использовании подхода setTimeout последовательность выглядит следующим образом:

  1. Сценарий устанавливает className;
  2. Скрипт заканчивается;
  3. Браузер обновляет информацию, основываясь на изменениях, сделанных скриптом;
  4. Тайм-аут пожаров;
  5. Сценарий тайм-аута устанавливает фокус, который теперь успешно выполняется.
1 голос
/ 10 сентября 2009

Если вы используете jQuery, используйте это для отображения и установки фокуса:

$(".hiddenClass").fadeIn("fast", 
    function() {
        $("#hiddenInput").focus();
    }
);

или

$(".hiddenClass").show(0, 
    function() {
        $("#hiddenInput").focus();
    }
);

Если вы хотите показать это без какого-либо появления.

По сути, он исчезает из скрытого div (вы можете заменить .hiddenClass на id, если хотите, чтобы показывался конкретный div, а не все элементы с .hiddenClass), и как только это будет сделано, он выполняет функцию обратного вызова, чтобы дать фокус на вход.

Таким образом, вы не будете пытаться установить фокус ввода до тех пор, пока div не будет полностью показан.

0 голосов
/ 10 сентября 2009

У меня было такое раньше со мной. В большинстве случаев я обнаружил, что установив тайм-аут после настройки, экран устраняет проблему в IE. К сожалению, это не самое чистое решение.

0 голосов
/ 09 сентября 2009

Я не уверен, что здесь происходит, но это может быть неплохой идеей - захватить ссылку на используемый вами div, сохранить его в переменной, а затем оперировать этим вместо того, чтобы захватывать его с помощью getElementByID ( ) каждый раз.

Таким образом, вы выше код будет:

 var myDiv = document.getElementById("hiddenInput");
 if(myDiv)
 {
    myDiv.className="showClass"; //a CSS class with display:block;
    myDiv.focus();
    myDiv.select();
 }

Также: есть определенные функции javascript, в которых браузеру разрешено раскручивать другую игру (например, функция load ()); просто что-то иметь в виду:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...