防止 jQueryUI 对话框将焦点设置为第一个文本框

我已经设置了一个 jQueryUI 模式对话框,用于在用户单击链接时显示。那个对话 div 标记中有两个文本框(为了简洁起见,我只显示了代码1) ,它被改为一个 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>
131966 次浏览

这可能是浏览器行为而不是 jQuery 插件的问题。您是否尝试过在打开弹出式窗口后以编程方式移除焦点。

$('#lnkAddReservation').click(function () {
dlg.dialog('open');


// you may want to change the selector below
$('input,textarea,select').blur();


return false;
});

还没测试过,但应该可以用。

将输入的 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");
}
});
});

我发现以下代码是用于 open 的 jQueryUI 对话框函数。

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可以作为解决方案使用。

我的内容比对话要长。在打开的时候,对话框会骂到底部的第一个: 表格。这是我的解决办法。

$("#myDialog").dialog({
...
open: function(event, ui) { $(this).scrollTop(0); }
});

您可以添加以下内容:

...

dlg.dialog({ autoOpen:false,
modal: true,
width: 400,
open: function(){                  // There is new line
$("#txtStartDate").focus();
}
});

...

JQuery UI 1.10.0 Changelog 列出了正在修复的 4731号罚单

看起来 focus usSelector 没有实现,但是使用了对各种元素的级联搜索:

扩展 autofocus,从[ autofocus ]开始,然后: 表格内容,然后按钮窗格,然后关闭按钮,然后对话框

因此,用 autofocus属性标记一个元素,这个元素就是应该获得焦点的元素:

<input autofocus>

文件中,焦点逻辑被解释(就在目录下,标题‘ Focus’下) :

打开对话框后,焦点会自动移到第一个项目 符合以下条件:

  1. 对话框中具有 autofocus属性的第一个元素
  2. 对话框内容中的第一个 :tabbable元素
  3. 对话框按钮窗格中的第一个 :tabbable元素
  4. 对话框的关闭按钮
  5. 对话本身

我也遇到过同样的问题,解决方法是在数据采集器前插入一个空输入,这样每次打开对话框时都会偷走焦点。该输入隐藏在对话框的每个开口处,并在关闭时再次显示。

我也有同样的问题。

我所做的变通方法是在对话框容器的顶部添加虚拟文本框。

<input type="text" style="width: 1px; height: 1px; border: 0px;" />

我的解决办法:

open: function(){
jQuery('input:first').blur();
jQuery('#ui-datepicker-div').hide();
},

如前所述,这是 jQuery UI 的一个已知错误,应该很快就能修复。

这里还有另一个选择,所以你不必去干扰 tabindex:

暂时禁用数据采集器,直到对话框打开:

dialog.find(".datepicker").datepicker("disable");
dialog.dialog({
"open": function() {$(this).find(".datepicker").datepicker("enable");},
});

我没问题。

重复问题: 如何在打开对话框时模糊第一个表单输入

简单的解决办法:

只要创建一个 tabindex = 1的不可见元素..。 这样不会让数据采集器聚焦。

例如:

<a href="" tabindex="1"></a>
...
Here comes the input element

为了扩展前面的一些答案(并忽略辅助数据采集器方面) ,如果您想阻止 focus()事件在对话框打开时聚焦第一个输入字段,请尝试这样做:

$('#myDialog').dialog(
{ 'open': function() { $('input:first-child', $(this)).blur(); }
});

现在还没人找到解决办法,这很酷,但看起来我有东西给你。坏消息是,无论如何,即使没有输入和链接在里面,对话框也会抓住焦点。 我使用这个对话框作为一个工具提示,并且确实需要将焦点放在原始元素中:

Use 选项[ autoOpen: false ]

$toolTip.dialog("widget").css("visibility", "hidden");
$toolTip.dialog("open");
$toolTip.dialog("widget").css("visibility", "visible");

当对话框不可见时,焦点不会设置在任何地方,而是保持在原来的位置。 它适用于只有纯文本的工具提示,但不测试更多功能性对话框,因为在开始时可见对话框可能很重要。也许在任何情况下都会工作得很好。

我知道最初的文章只是为了避免把焦点放在第一个元素上,但是在打开对话框之后(在我的代码之后) ,你可以很容易地决定焦点应该放在哪里。

在 IE,FF 和 Chrome 中测试。

希望这能帮到别人。

我也遇到过类似的问题,解决方法是在打开之后专注于对话框:

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?)

但是在我的例子中,第一个元素是一个锚,所以我不知道在您的例子中是否会打开数据采集器。

编辑: 只能在 IE 上工作

在它上面添加一个隐藏跨度,使用 ui-helper-hide-access 通过绝对定位使其隐藏。我知道您有这个类,因为您使用的是 jquery-ui 中的对话框,它位于 jquery-ui 中。

<span class="ui-helper-hidden-accessible"><input type="text"/></span>

在 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();

在我看来,这个解决方案非常好:

$("#dialog").dialog({
open: function(event, ui) {
$("input").blur();
}
});

在这里发现: 无法删除的自动对焦对话框

我也有类似的问题。当验证失败时,我会打开一个错误对话框,它会抓住焦点,就像 Flugan 在他的 回答中显示的那样。问题是,即使对话框中没有元素是可选的,对话框本身仍然是有焦点的。下面是来自 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);
};

我在寻找一个不同的问题,但同样的原因。问题是对话框将焦点设置为它找到的第一个 <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>获得焦点,但随后被隐藏。所以总体效果就是预期效果。

我知道这是一个老线程,但作为 UI 文档有没有修复这一点。这不需要模糊或聚焦工作。不知道是不是最优雅的。但是对任何人解释起来都很有道理,也很容易。

JQuery 1.9已经发布,而且似乎没有修复。在1.9中,试图通过一些建议的方法来阻止第一个文本框的焦点是不起作用的。我认为是因为这些方法试图模糊焦点或移动焦点发生在对话框中的文本框已经获得焦点并完成其脏工作之后。

我在 API 文档中看不到任何让我认为在预期功能方面有任何改变的东西。关闭添加一个开始按钮..。

从 jQuery UI 1.10.0开始,您可以选择 使用 HTML5属性关注哪个输入元素 自动对焦

您所需要做的就是创建一个虚拟元素作为对话框中的第一个输入。 它会吸引你的注意力。

<input type="hidden" autofocus="autofocus" />

这已经在2013年2月7日的 Chrome、 Firefox 和 Internet Explorer (所有最新版本)中进行了测试。

Http://jqueryui.com/upgrade-guide/1.10/#added-ability-to-specify-which-element-to-focus-on-open

在 jQuery UI > = 1.10.2中,可以用一个安慰剂函数替换 _focusTabbable原型方法:

$.ui.dialog.prototype._focusTabbable = $.noop;

小提琴

这将影响页面中的所有 dialog,而无需手动编辑每个 dialog

原始函数只是将焦点设置为具有 autofocus属性/tabbable元素/的第一个元素,或者回到对话框本身。由于它的使用只是将焦点设置在一个元素上,所以用 noop代替它应该没有问题。

下面是我在阅读了 JQuery UI 票据 # 4731之后实现的解决方案,它最初是由懒人发布的,作为对另一个答案的回应。(这张彩票也是他制作的。)

首先,无论使用什么方法将自动完成应用到页面,添加以下代码行:

$.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 的“ select”自动完成回调,并添加了一些额外的代码,以确保 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;
}

如果您只有一个 Jquery 对话框形式的字段,并且它是需要 Datepicker 的字段,那么您也可以将焦点放在对话框标题栏中的对话框 关闭(交叉)按钮上:

$('.ui-dialog-titlebar-close').focus();

初始化之后调用这个对话框,例如:

$('#yourDialogId').dialog();
$('.ui-dialog-titlebar-close').focus();

因为关闭按钮是在调用 .dialog()之后呈现的。

作为第一个输入: <input type="text" style="position:absolute;top:-200px" />

我也有过类似的问题。 在我的页面上,第一个输入是带有 jQueryUI 日历的文本框。 第二个元素是按钮。 由于日期已经有价值,我设置焦点按钮,但首先添加触发器的模糊文本框。这解决了所有浏览器中的问题,可能还包括所有版本的 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();


});

只是在玩的时候发现的。

我发现这些解决方案移除焦点,导致 ESC键停止工作(即关闭对话框)时,第一次进入对话框。

如果对话框打开并且您立即按下 ESC,它将不会关闭对话框(如果您已经启用了该对话框) ,因为焦点是在某个隐藏字段或某个东西上,并且它没有得到按键事件。

我修正它的方法是将它添加到打开事件中,从第一个字段中移除焦点:

$('#myDialog').dialog({
open: function(event,ui) {
$(this).parent().focus();
}
});

这将焦点设置为不可见的对话框,然后 ESC键就可以工作了。

这对于智能手机和平板电脑来说非常重要,因为当输入有焦点时,键盘就会出现。这就是我所做的,在 div 的开头添加这个输入:

<input type="image" width="1px" height="1px"/>

不适用于 0px尺寸。我想这是更好的一个真正的透明图像,无论是 .png.gif,但我还没有尝试。

目前在 iPad 上运行良好。

如果使用对话框按钮,只需在其中一个按钮上设置 autofocus属性:

$('#dialog').dialog({
buttons: [
{
text: 'OK',
autofocus: 'autofocus'
},
{
text: 'Cancel'
}
]
});
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script src="https://code.jquery.com/ui/1.11.4/jquery-ui.min.js"></script>
<link href="https://code.jquery.com/ui/1.11.4/themes/smoothness/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>

您可以提供这个选项,将关闭按钮作为焦点。

.dialog({
open: function () {
$(".ui-dialog-titlebar-close").focus();
}
});