Я установил модальный диалог jQuery UI для отображения, когда пользователь нажимает ссылку. Есть два текстовых поля (я только показываю код для 1 для краткости) в этом теге div div и он изменен как текстовое поле jQuery UI DatePicker, которое реагирует на фокус.
Проблема заключается в том, что диалоговое окно jQuery UI ('open') каким-то образом запускает первый текстовый блок с фокусом, который затем запускает календарь датпикера для немедленного открытия.
Итак, я ищу способ предотвратить автоматическое выполнение фокуса.
<div><a id="lnkAddReservation" href="#">Add reservation</a></div>
<div id="divNewReservation" style="display:none" title="Add reservation">
<table>
<tr>
<th><asp:Label AssociatedControlID="txtStartDate" runat="server" Text="Start date" /></th>
<td>
<asp:TextBox ID="txtStartDate" runat="server" CssClass="datepicker" />
</td>
</tr>
</table>
<div>
<asp:Button ID="btnAddReservation" runat="server" OnClick="btnAddReservation_Click" Text="Add reservation" />
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
var dlg = $('#divNewReservation');
$('.datepicker').datepicker({ duration: '' });
dlg.dialog({ autoOpen:false, modal: true, width:400 });
$('#lnkAddReservation').click(function() { dlg.dialog('open'); return false; });
dlg.parent().appendTo(jQuery("form:first"));
});
</script>
jQuery UI 1.10.0 Список изменений содержит билет 4731 как фиксированный.
Похоже, что focusSelector не был реализован, но вместо этого использовался каскадный поиск для различных элементов. Из билета:
Расширьте автофокус, начиная с [автофокусировки], затем: tabbable content, затем кнопку, затем нажмите кнопку закрытия, затем диалог
Итак, отметьте элемент с атрибутом autofocus
, и это элемент, который должен получить фокус:
<input autofocus>
В документации объясняется логика фокуса (только под оглавлением, под заголовком "Фокус" ):
При открытии диалога фокус автоматически перемещается в первый элемент который соответствует следующему:
- Первый элемент в диалоге с атрибутом
autofocus
- Первый элемент
:tabbable
в содержимом диалога- Первый элемент
:tabbable
в панели кнопок диалога- Кнопка закрытия диалогового окна
- Сам диалог
Добавьте скрытый пролет над ним, используйте ui-helper-hidden-access, чтобы он был скрыт путем абсолютного позиционирования. Я знаю, что у вас есть этот класс, потому что вы используете диалог из jquery-ui и его в jquery-ui.
<span class="ui-helper-hidden-accessible"><input type="text"/></span>
В jQuery UI >= 1.10.2 вы можете заменить прототип _focusTabbable
функцией плацебо:
$.ui.dialog.prototype._focusTabbable = $.noop;
Это повлияет на все dialog
на странице, без необходимости вручную редактировать их.
Исходная функция не делает ничего, кроме установки фокуса на первый элемент с элементом autofocus
attribute/tabbable
/или возвращается к самому диалогу. Поскольку его использование просто фокусирует внимание на элементе, не должно быть никаких проблем с его заменой на noop
.
Я нашел следующий код для функции диалога jQuery UI для открытия.
c([]).add(d.find(".ui-dialog-content :tabbable:first")).add(d.find(".ui-dialog-buttonpane :tabbable:first")).add(d).filter(":first").focus();
Вы можете либо обойти поведение jQuery, либо изменить поведение.
tabindex -1 работает как обходной путь.
Начиная с jQuery UI 1.10.0, вы можете выбрать , с каким элементом ввода следует сфокусироваться, используя атрибут .
Все, что вам нужно сделать, это создать фиктивный элемент в качестве вашего первого ввода в диалоговом окне. Это поглотит фокус для вас.
<input type="hidden" autofocus="autofocus" />
Это было протестировано в Chrome, Firefox и Internet Explorer (все последние версии) 7 февраля 2013 года.
http://jqueryui.com/upgrade-guide/1.10/#added-ability-to-specify-which-element-to-focus-on-open
Просто подумал об этом во время игры.
Я нашел с этими решениями удаление фокуса, заставив клавишу ESC перестать работать (т.е. закрыть диалоговое окно), когда вы впервые входите в диалог.
Если откроется диалоговое окно и вы сразу же нажмете ESC, он не закроет диалоговое окно (если оно включено), потому что фокус находится в каком-то скрытом поле или что-то еще, и он не получает события нажатия клавиш.
Как я исправил это, нужно добавить это в открытое событие, чтобы удалить фокус из первого поля:
$('#myDialog').dialog({
open: function(event,ui) {
$(this).parent().focus();
}
});
Это устанавливает фокус на диалоговое окно, которое не отображается, а затем работает клавиша ESC.
Мое обходное решение:
open: function(){
jQuery('input:first').blur();
jQuery('#ui-datepicker-div').hide();
},
:first
селектор или .first()
в FF / Chrome / IE9. Бросок в dialogopen
тоже работает.
open: function(){ $('a').blur(); // no autofocus on links }
Установите tabindex ввода в -1, а затем установите dialog.open для восстановления tabindex, если вам это нужно позже:
$(function() {
$( "#dialog-message" ).dialog({
modal: true,
width: 500,
autoOpen: false,
resizable: false,
open: function()
{
$( "#datepicker1" ).attr("tabindex","1");
$( "#datepicker2" ).attr("tabindex","2");
}
});
});
Простой способ:
Просто создайте невидимый элемент с tabindex = 1... Это не будет сфокусировано на datepicker...
например:.
<a href="" tabindex="1"></a>
...
Here comes the input element
У меня был контент, который был длиннее, чем диалог. В открывшемся диалоговом окне будет изменен первый: tabbable, который был внизу. Вот мое решение.
$("#myDialog").dialog({
...
open: function(event, ui) { $(this).scrollTop(0); }
});
$('...').blur();
вместо прокрутки.
Вот решение, которое я реализовал после прочтения jQuery UI ticket # 4731, первоначально отправленного slolife в ответ на другой ответ. (Билет также был создан им.)
Во-первых, в любом методе, который вы используете для применения автозаполнения к странице, добавьте следующую строку кода:
$.ui.dialog.prototype._focusTabbable = function(){};
Это отключает поведение "автофокусировки" jQuery. Чтобы ваш сайт по-прежнему был широкодоступным, оберните методы создания диалога, чтобы добавить дополнительный код и добавьте вызов для фокусировки первого элемента ввода:
function openDialog(context) {
// Open your dialog here
// Usability for screen readers. Focus on an element so that screen readers report it.
$("input:first", $(context)).focus();
}
Для дальнейшего доступа к доступности, когда параметры автозаполнения выбраны с клавиатуры, мы переопределяем jQuery UI "выберите" автозавершение обратного вызова и добавим дополнительный код, чтобы гарантировать, что textElement не потеряет фокус в IE 8 после выбора.
Вот код, который мы используем для применения автозаполнения к элементам:
$.fn.applyAutocomplete = function () {
// Prevents jQuery dialog from auto-focusing on the first tabbable element.
// Make sure to wrap your dialog opens and focus on the first input element
// for screen readers.
$.ui.dialog.prototype._focusTabbable = function () { };
$(".autocomplete", this)
.each(function (index) {
var textElement = this;
var onSelect = $(this).autocomplete("option", "select");
$(this).autocomplete("option", {
select: function (event, ui) {
// Call the original functionality first
onSelect(event, ui);
// We replace a lot of content via AJAX in our project.
// This ensures proper copying of values if the original element which jQuery UI pointed to
// is replaced.
var $hiddenValueElement = $("#" + $(textElement).attr('data-jqui-acomp-hiddenvalue'));
if ($hiddenValueElement.attr("value") != ui.item.value) {
$hiddenValueElement.attr("value", ui.item.value);
}
// Replace text element value with that indicated by "display" if any
if (ui.item.display)
textElement.value = ui.item.display;
// For usability purposes. When using the keyboard to select from an autocomplete, this returns focus to the textElement.
$(textElement).focus();
if (ui.item.display)
return false;
}
});
})
// Set/clear data flag that can be checked, if necessary, to determine whether list is currently dropped down
.on("autocompleteopen", function (event, ui) {
$(event.target).data().autocompleteIsDroppedDown = true;
})
.on("autocompleteclose", function (event, ui) {
$(event.target).data().autocompleteIsDroppedDown = false;
});
return this;
}
Вы можете указать эту опцию, чтобы вместо этого нажать кнопку закрытия.
.dialog({
open: function () {
$(".ui-dialog-titlebar-close").focus();
}
});
Если вы используете диалоговые кнопки, просто установите атрибут autofocus
на одну из кнопок:
$('#dialog').dialog({
buttons: [
{
text: 'OK',
autofocus: 'autofocus'
},
{
text: 'Cancel'
}
]
});
<script src="/jquery-1.12.4.min.js"></script>
<script src="/jquery-ui.min.js"></script>
<link href="/jquery-ui.css" rel="stylesheet"/>
<div id="dialog" title="Basic dialog">
This is some text.
<br/>
<a href="www.google.com">This is a link.</a>
<br/>
<input value="This is a textbox.">
</div>
Если у вас есть только одно поле в форме диалогового окна JQuery, и ему нужен Datepicker, вы можете просто установить фокус на диалог Закрыть (крест) в строке заголовка диалога:
$('.ui-dialog-titlebar-close').focus();
Вызвать этот диалог ПОСЛЕ инициализации, например:
$('#yourDialogId').dialog();
$('.ui-dialog-titlebar-close').focus();
Поскольку кнопка закрытия отображается после вызова .dialog()
.
Я искал другую проблему, но по той же причине. Проблема в том, что в диалоговом окне основное внимание уделяется первому найденному <a href="">.</a>
. Поэтому, если у вас много текста в вашем диалоговом окне и появляются полосы прокрутки, у вас может быть ситуация, когда полоса прокрутки будет прокручиваться вниз. Я считаю, что это также исправляет вопрос о первых лицах. Хотя другие делают тоже.
Простая для понимания проблема.
<a id="someid" href="#">.</a>
в качестве первой строки в диалоговом окне div.
Пример:
<div id="dialogdiv" title="some title"> <a id="someid" href="#">.</a> <p> //the rest of your stuff </p> </div>
Когда инициировано ваше диалоговое окно
$(somediv).dialog({ modal: true, open: function () { $("#someid").hide(); otherstuff or function }, close: function () { $("#someid").show(); otherstuff or function } });
Вышеупомянутое не будет иметь ничего сфокусированного, и полосы прокрутки останутся наверху, где он принадлежит. <a>
получает фокус, но затем скрывается. Таким образом, общий эффект - желаемый эффект.
Я знаю, что это старый поток, но, как и в пользовательском интерфейсе, нет никакого исправления. Это не требует размытия или фокусировки. Не уверен, что это самый элегантный. Но это просто понятно и легко объяснить кому-либо.
У меня аналогичная проблема. Я открываю диалоговое окно с ошибкой, когда проверка не выполняется, и она захватывает фокус, точно так же, как Flugan показывает это в ответе . Проблема в том, что даже если ни один элемент внутри диалогового окна не является tabbable, само диалоговое окно все еще сфокусировано. Вот исходный unminified код из jquery-ui-1.8.23\js\jquery.ui.dialog.js:
// set focus to the first tabbable element in the content area or the first button
// if there are no tabbable elements, set focus on the dialog itself
$(self.element.find(':tabbable').get().concat(
uiDialog.find('.ui-dialog-buttonpane :tabbable').get().concat(
uiDialog.get()))).eq(0).focus();
Комментарий у них!
Это действительно плохо для меня по нескольким причинам. Самое неприятное, что первая реакция пользователя заключается в том, чтобы ударить по обратному пространству, чтобы удалить последний символ, но вместо этого ему будет предложено покинуть страницу, потому что обратное пространство попадает за пределы элемента управления ввода.
Я обнаружил, что следующее обходное решение работает очень хорошо для меня:
jqueryFocus = $.fn.focus;
$.fn.focus = function (delay, fn) {
jqueryFocus.apply(this.filter(':not(.ui-dialog)'), arguments);
};
По-моему, это решение очень приятно:
$("#dialog").dialog({
open: function(event, ui) {
$("input").blur();
}
});
Найдено здесь: не удалось удалить-autofocus-in-ui-dialog
Ну, здорово, что на данный момент никто не нашел решение, но похоже, что у меня есть что-то для вас. Плохая новость заключается в том, что диалог захватывает фокус в любом случае, даже если входы и ссылки не находятся внутри. Я использую диалог в качестве всплывающей подсказки и обязательно нуждаюсь в фокусе пребывания в исходном элементе. Вот мое решение:
использовать опцию [autoOpen: false]
$toolTip.dialog("widget").css("visibility", "hidden");
$toolTip.dialog("open");
$toolTip.dialog("widget").css("visibility", "visible");
Пока диалог невидим, фокус не устанавливается нигде и остается в исходном месте. Он работает со всплывающими подсказками только с простым текстом, но не проверен для более функциональных диалогов, где может быть важно иметь диалог, видимый в момент открытия. Вероятно, все будет нормально работать.
Я понимаю, что исходный пост был просто для того, чтобы не фокусироваться на первом элементе, но вы можете легко решить, где именно фокус должен быть после открытия диалога (после моего кода).
Протестировано в IE, FF и Chrome.
Надеюсь, это поможет кому-то.
У меня была бы такая же проблема и ее решить, вставив пустой файл перед datepicker, который крадет фокус каждый раз, когда открывается диалог. Этот ввод скрывается при каждом открытии диалога и отображается снова при закрытии.
Это может быть поведение браузера, а не плагин jQuery. Вы пытались удалить фокус программно после открытия всплывающего окна.
$('#lnkAddReservation').click(function () {
dlg.dialog('open');
// you may want to change the selector below
$('input,textarea,select').blur();
return false;
});
Не тестировали, но должны работать нормально.
Это действительно важно для смартфонов и планшетов, потому что клавиатура появляется, когда вход имеет фокус. Это то, что я сделал, добавьте этот ввод в начале div:
<input type="image" width="1px" height="1px"/>
Не работает с размером 0px
. Я думаю, это даже лучше с реальным прозрачным изображением, либо .png
, либо .gif
, но я не пробовал.
Работает хорошо в iPad.
У меня была аналогичная проблема. На моей первой странице ввода находится текстовое поле с календарем пользовательского интерфейса jQuery. Второй элемент - это кнопка. Поскольку дата уже имеет значение, я устанавливаю фокус на кнопку, но сначала добавляю триггер для размытия в текстовом поле. Эта проблема разрешима во всех браузерах и, вероятно, во всех версиях jQuery. Протестировано в версии 1.8.2.
<div style="padding-bottom: 30px; height: 40px; width: 100%;">
@using (Html.BeginForm("Statistics", "Admin", FormMethod.Post, new { id = "FormStatistics" }))
{
<label style="float: left;">@Translation.StatisticsChooseDate</label>
@Html.TextBoxFor(m => m.SelectDate, new { @class = "js-date-time", @tabindex=1 })
<input class="button gray-button button-large button-left-margin text-bold" style="position:relative; top:-5px;" type="submit" id="ButtonStatisticsSearchTrips" value="@Translation.StatisticsSearchTrips" tabindex="2"/>
}
<script type="text/javascript">
$(document).ready(function () {
$("#SelectDate").blur(function () {
$("#SelectDate").datepicker("hide");
});
$("#ButtonStatisticsSearchTrips").focus();
});
jQuery 1.9 выпущен и, похоже, не исправлено. Попытка предотвратить фокусировку первого текстового поля некоторыми из предложенных методов не работает в 1.9. Я думаю, что если методы попытаются размыть фокус или переместить фокус, ПОСЛЕ того, как текстовое поле в диалоговом окне уже приобрело фокус и проделало свою грязную работу.
Я не вижу ничего в документации API, которая заставляет меня думать, что что-то изменилось с точки зрения ожидаемой функциональности. Выкл., Чтобы добавить открывающую кнопку...
найти в jquery.ui.js
d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();
и замените на
d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(-1).focus();
У меня была аналогичная проблема и она была решена путем фокусировки на диалоговом окне после открытия:
var $dialog = $("#pnlFiltros")
.dialog({
autoOpen: false,
hide: "puff",
width: dWidth,
height: 'auto',
draggable: true,
resizable: true,
closeOnScape : true,
position: [x,y]
});
$dialog.dialog('open');
$("#pnlFiltros").focus(); //focus on the div being dialogued (is that a word?)
Но в моем случае первый элемент является якорем, поэтому я не знаю, откроется ли в вашем случае, что датпикер будет открыт.
EDIT: работает только с IE
Чтобы расширить некоторые предыдущие ответы (и игнорировать вспомогательный аспект даты), если вы хотите, чтобы событие focus()
не фокусировалось на первом поле ввода при открытии диалога, попробуйте следующее:
$('#myDialog').dialog(
{ 'open': function() { $('input:first-child', $(this)).blur(); }
});
Как уже упоминалось, это известная ошибка с пользовательским интерфейсом jQuery и должна быть исправлена относительно скоро. До тех пор...
Вот еще один вариант, поэтому вам не нужно связываться с tabindex:
Отключить datepicker временно, пока не откроется диалоговое окно:
dialog.find(".datepicker").datepicker("disable");
dialog.dialog({
"open": function() {$(this).find(".datepicker").datepicker("enable");},
});
Работает для меня.
Дублирующий вопрос: Как размыть ввод первой формы при открытии диалога
У меня такая же проблема.
Обходной путь, который я сделал, - добавить текстовое поле в верхней части диалогового контейнера.
<input type="text" style="width: 1px; height: 1px; border: 0px;" />
Вы можете добавить это:
...
dlg.dialog({ autoOpen:false,
modal: true,
width: 400,
open: function(){ // There is new line
$("#txtStartDate").focus();
}
});
...
как первый вход: <input type="text" style="position:absolute;top:-200px" />