防止jQuery UI对话框将焦点设置为第一个文本框
我已经设置了一个jQuery UI模式对话框来显示用户点击链接的时间。 有两个文本框(我只显示为简洁的代码1)在该对话框的div标签,它被改为一个jQuery的UI DatePicker文本框对焦点作出反应。
问题是,jQuery UI对话框(“打开”)以某种方式触发第一个文本框有焦点,然后触发datepicker日历立即打开。
所以我正在寻找一种方法来防止焦点自动发生。
<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,而是使用了各种元素的级联search。 从票:
从[自动对焦]开始,扩展自动对焦,然后:可放大的内容,然后button面板,然后closuresbutton,然后对话框
所以,用autofocus
属性标记一个元素,那就是应该得到焦点的元素:
<input autofocus>
在文档中 ,解释焦点逻辑(就在目录下的“焦点”标题下):
打开对话框后,焦点将自动移至与以下内容匹配的第一个项目:
- 具有
autofocus
属性的对话框中的第一个元素- 第一个
:tabbable
对话框内容中的:tabbable
元素- 第一个
:tabbable
对话框的button窗格内的:tabbable
元素- 对话框的closuresbutton
- 对话本身
在它上面添加一个隐藏的跨度,使用ui-helper-hidden-accessible使其通过绝对定位隐藏。 我知道你有这个类,因为你正在使用jquery-ui中的对话框,它在jquery-ui中。
<span class="ui-helper-hidden-accessible"><input type="text"/></span>
在jQuery UI> = 1.10.2中,可以用安慰剂函数replace_focusTabbable
原型方法:
$.ui.dialog.prototype._focusTabbable = $.noop;
小提琴
这将影响页面中的所有dialog
,而不需要手动编辑每个dialog
。
原始函数只是将焦点设置为具有autofocus
属性/ tabbable
元素的第一个元素/或者回退到对话框本身。 由于它的使用只是把注意力放在一个元素上,所以用noop
replace它是不应该有问题的。
我发现下面的代码是用于打开的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开始,您可以使用HTML5属性 自动对焦来select要关注的input元素 。
您只需在对话框中创build一个虚拟元素作为第一个input。 它会吸引你的焦点。
<input type="hidden" autofocus="autofocus" />
这已经在2013年2月7日在Chrome,Firefox和Internet Explorer(所有最新版本)中进行了testing。
http://jqueryui.com/upgrade-guide/1.10/#added-ability-to-specify-which-element-to-focus-on-open
在玩耍的时候就明白了这一点。
我发现用这些解决scheme来消除焦点,导致ESC键首次进入对话框时停止工作(即closures对话框)。
如果对话框打开,你立即按ESC键,它将不会closures对话框(如果你有这个启用),因为焦点是在一些隐藏的领域或什么,并没有得到按键事件。
我修复它的方法是将其添加到打开的事件中,以从第一个字段中删除焦点:
$('#myDialog').dialog({ open: function(event,ui) { $(this).parent().focus(); } });
这将焦点设置为不可见的对话框,然后按ESC键。
将input的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: function(){ jQuery('input:first').blur(); jQuery('#ui-datepicker-div').hide(); },
简单的解决方法:
只要创build一个不可见的元素与tabindex = 1 …这将不会集中datepicker …
例如。:
<a href="" tabindex="1"></a> ... Here comes the input element
我的内容比对话更长。 在打开的时候,对话框会变成第一个:位于底部的tabbable。 这是我的修复。
$("#myDialog").dialog({ ... open: function(event, ui) { $(this).scrollTop(0); } });
这是我通过阅读jQuery UI票#4731后 ,实施的解决scheme,最初由slolife张贴作为对另一个答案的答复。 (这张票也是由他创build的。)
首先,无论您使用哪种方法将自动填充应用于页面,请添加以下代码行:
$.ui.dialog.prototype._focusTabbable = function(){};
这会禁用jQuery的“自动聚焦”行为。 为了确保您的网站能够继续被广泛访问,请包装您的对话框创build方法,以便添加额外的代码,并添加一个调用来聚焦第一个input元素:
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(); }
为了进一步解决通过键盘select自动完成选项时的可访问性,我们重写jQuery UI的“select”自动完成callback,并添加一些额外的代码,以确保textElement在做出select后不会在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插件问题。 您是否尝试过在打开popup窗口后以编程方式移除焦点?
$('#lnkAddReservation').click(function () { dlg.dialog('open'); // you may want to change the selector below $('input,textarea,select').blur(); return false; });
没有testing,但应该工作正常。
我会遇到同样的问题,并通过在datepicker之前插入一个空的input来解决它,每次打开对话时都会窃取焦点。 该input在对话框的每个开口处都隐藏,并在closures时再次显示。
好吧,现在没有人find解决scheme,这很酷,但看起来我有一些东西给你。 坏消息是,即使没有任何input和链接,对话也会集中在任何情况下。 我使用对话框作为工具提示,并且绝对需要将焦点留在原始元素中。 这是我的解决scheme:
使用选项[autoOpen:false]
$toolTip.dialog("widget").css("visibility", "hidden"); $toolTip.dialog("open"); $toolTip.dialog("widget").css("visibility", "visible");
虽然对话不可见,但重点不在任何地方,并停留在原来的地方。 它适用于只有纯文本的工具提示,但未在更多function对话框中进行testing,在对话框中显示对话框可能很重要。 大概在任何情况下都可以正常工作。
我知道原来的文章只是为了避免把焦点放在第一个元素上,但是你可以很容易地决定打开对话框(在我的代码之后)焦点的位置。
testing在IE,FF和Chrome。
希望这会帮助别人。
在我看来,这个解决scheme非常好:
$("#dialog").dialog({ open: function(event, ui) { $("input").blur(); } });
在这里find: 无法移除自动对焦的UI对话框
我有一个类似的问题。 当validation失败时,我打开一个错误对话框,就像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();
评论是他们的!
这对我来说真的很糟糕,原因有几个。 最烦人的是,用户的第一反应是点击backspace删除最后一个字符,但是他却被提示离开页面,因为backspace被input到input控件之外。
我发现以下解决方法对我来说非常有用:
jqueryFocus = $.fn.focus; $.fn.focus = function (delay, fn) { jqueryFocus.apply(this.filter(':not(.ui-dialog)'), arguments); };
我四处寻找一个不同的问题,但同样的原因。 问题是对话框集中在第一个find的<a href="">.</a>
。 所以如果你的对话框中有很多文字,滚动条会出现,你可能会遇到这样的情况:滚动条会滚动到底部。 我相信这也解决了第一个人的问题。 尽pipe其他人也是如此。
简单易懂的修复。 <a id="someid" href="#">.</a>
作为对话框的第一行。
例:
<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对话框的字段,并且它需要Datepicker,或者你可以在对话框的标题栏中设置焦点对话框的Close(cross)button :
$('.ui-dialog-titlebar-close').focus();
调用这个AFTER对话框被初始化,例如:
$('#yourDialogId').dialog(); $('.ui-dialog-titlebar-close').focus();
因为closuresbutton在调用.dialog()
之后呈现。
如果您使用的是对话框button,只需在其中一个button上设置autofocus
属性:
$('#dialog').dialog({ buttons: [ { text: 'OK', autofocus: 'autofocus' }, { text: 'Cancel' } ] });
<script src="jquery/1.12.4/jquery.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>
你可以提供这个选项,来closuresclosuresbutton。
.dialog({ open: function () { $(".ui-dialog-titlebar-close").focus(); } });
我遇到了同样的问题。
我所做的解决方法是在对话框容器的顶部添加虚拟文本框。
<input type="text" style="width: 1px; height: 1px; border: 0px;" />
如前所述,这是一个已知的与jQuery UI的错误,应该尽快修复。 直到那时…
这是另一个选项,所以你不必与tabindex混淆:
暂时禁用dateselect器,直到打开对话框:
dialog.find(".datepicker").datepicker("disable"); dialog.dialog({ "open": function() {$(this).find(".datepicker").datepicker("enable");}, });
为我工作。
重复的问题: 如何模糊对话框打开的第一个表单input
为了扩展一些以前的答案(并忽略辅助dateselect器方面),如果要防止focus()
事件在对话框打开时将第一个input字段聚焦,请尝试以下操作:
$('#myDialog').dialog( { 'open': function() { $('input:first-child', $(this)).blur(); } });
我有一个类似的问题,打开后关注对话框来解决它:
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?)
但在我的情况下,第一个元素是一个锚,所以我不知道是否在你的情况下,将离开datepicker打开。
编辑:只适用于IE浏览器
在jquery.ui.js中find
d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(0).focus();
并replace为
d.find(".ui-dialog-buttonpane :tabbable").get().concat(d.get()))).eq(-1).focus();
jQuery 1.9发布了,似乎没有修复。 尝试通过某些build议的方法防止第一个文本框的焦点在1.9中不起作用。 我认为,因为方法试图模糊焦点或移动焦点发生之后,对话框中的文本框已经获得焦点,并完成其肮脏的工作。
我在API文档中看不到任何东西,这让我觉得任何事情都会根据预期的function而改变。 closures添加一个开瓶器button…
我有类似的问题。 在我的页面上,第一个input是带有jQuery UI日历的文本框。 第二个元素是button。 由于date已经有价值,我把焦点放在button上,但是首先在文本框上添加模糊的触发器。 这解决了所有的浏览器,可能在所有版本的jQuery中的问题。 testing版本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(); });
这对于智能手机和平板电脑非常重要,因为当input焦点时,键盘会出现。 这就是我所做的,在div的开头添加这个input:
<input type="image" width="1px" height="1px"/>
不适用于大小0px
。 我想这是更好的一个真正的透明图像,无论是.png
或.gif
但我没有尝试过。
在iPad上工作得很好。
你可以添加这个:
…
dlg.dialog({ autoOpen:false, modal: true, width: 400, open: function(){ // There is new line $("#txtStartDate").focus(); } });
…
作为第一个input: <input type="text" style="position:absolute;top:-200px" />