Проверка наличия фокуса элемента DOM
У меня есть текстовое поле lightbox, которое отображается с помощью вызова AJAX из ASP.NET UpdatePanel. Когда отображается лайтбокс, я использую метод focus()
текстового поля, который находится в лайтбоксе, чтобы сразу же переключить фокус на текстовое поле.
Когда в Firefox текстовое поле получает фокус без проблем. В IE текстовое поле не фокусируется, если я не использую
setTimeout(function(){txtBx.focus()}, 500);
чтобы ускорить метод фокусировки позже, после того, как элемент DOM был загружен, я предполагаю.
Проблема заключается в том, что непосредственно над этой строкой я уже проверяю, есть ли элемент null/ undefined, поэтому объект уже должен существовать, если он попадает в эту строку, он просто не позволит себе получить сосредоточиться сразу по какой-то причине.
Очевидно, что установка таймера для "исправления" этой проблемы - не лучший или самый элегантный способ решить эту проблему. Я хотел бы сделать что-то вроде следующего:
var txtBx = document.getElementById('txtBx');
if (txtPassword != null) {
txtPassword.focus();
while (txtPassword.focus === false) {
txtPassword.focus();
}
}
Есть ли способ сказать, что текстовое поле имеет фокус, чтобы я мог сделать что-то вроде выше?
Или я смотрю на это неправильно?
Edit
Чтобы уточнить, я не вызываю код при загрузке страницы. script находится в верхней части страницы, однако он находится внутри функции, вызываемой при завершении асинхронной обратной передачи ASP.NET, а не при загрузке страницы.
Поскольку это отображается после обновления Ajax, DOM уже должен быть загружен, поэтому я предполагаю, что событие jQuery $(document).ready()
здесь не поможет.
Ответы
Ответ 1
Попробуйте поместить javascript, который устанавливает фокус в конце страницы вместо начала или после того, как он загорится после события, загруженного страницей. Это поможет обеспечить полную загрузку DOM перед настройкой фокуса.
Я использовал FastInit для этого. JQuery $(document).ready() также будет работать.
Ответ 2
вы можете попробовать что-то вроде этого [IE Specific]. (Непроверенные)
theAjaxCreatedElement.onreadystatechange = function() {
if ( this.readyState != "complete" )
return;
this.focus();
};
Другим способом может быть изменение цвета фона элемента с помощью onfocus, затем извлечение его с помощью js-проверки, если это то, что должно быть, если нет: переориентировать элемент.
Ответ 3
Вы можете попробовать следующее:
- Используйте endRequest событие PageRequestManager. Это событие срабатывает после завершения обновления Ajax.
- Сосредоточьте текстовое поле в обработчике событий
Вот пример кода:
<script type="text/javascript">
function onRequestEnd()
{
var txtBx = $get('txtBx');
txtBx.focus();
}
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(onRequestEnd);
</script>
Чтобы сфокусировать текстовое поле, вы можете использовать функцию pageLoad (ярлык к load события Application клиентский объект):
<script type="text/javascript">
function pageLoad()
{
var txtBx = $get('txtBx');
txtBx.focus();
}
</script>
Ответ 4
В IE есть несколько вещей, которые делают трюк:
-
Если у фокусировочного элемента есть другой z-индекс, вы можете быстро установить z-index в значение текущего сфокусированного элемента (возможно, установить атрибут "скрытый" ), установить фокус, а затем установить его обратно в исходный z-индекс.
-
Попробуйте размыть() текущий сфокусированный элемент.
-
Если элемент "подгоняется" - сфокусируйте элемент "прокладка".
Ответ 5
Кажется, что IE не обновляет DOM до тех пор, пока script не закончит работу. Таким образом, тестирование цикла для фокуса не позволит обновлять DOM. Использование setTimeout
, вероятно, является единственным рабочим решением.
Ваш пример с .focus()
является хорошо известным примером, см., например, этот ответ.
Ответ 6
Вы пытались добавить атрибут autofocus="autofocus"
к элементу текстового поля, который вы вызываете через Ajax?
Обычно, когда мне нужно иметь некоторые дополнительные функции JavaScript для работы в динамическом контенте, я просто добавлю этот JavaScript в вызываемый контент.
Этот JavaScript будет выполняться после его добавления в DOM. Я не вижу смысла писать JavaScript в ваш родительский файл и затем "прослушивать" изменения в DOM. Как вы уже упоминали, setTimeout() больше взломан, чем что-либо еще для чего-то подобного: