2016-09-14 107 views
12

我在下面有一个jQuery对话框。我使用的是jQuery UI 1.11。jQuery对话框失去焦点滚动

$("#contactContainer").dialog({ 
    closeOnEscape: false, 
    modal: true, 
    dialogClass: 'contactsFooter', 
    open: function(event, ui) { 
    $(".ui-dialog-titlebar-close").show(); 
    $('#dialog_footer').remove(); 
    $(".contactsFooter").append('<div class="" id="dialog_footer"><div class="dialog-footer-buttons"><button type="button" id ="close" class="button-style-2" onclick="$(\'#hasChangedForm\').val(\'\');" style="margin-left: 5px;">Cancel</button></div></div>'); 
    }, 
    autoOpen: false,   
    width: 300, 
    minHeight: 'auto', 
    maxHeight: 400, 
    position: { my: 'top', at: 'top+50' }, 
    close:function() { 
    $('#contactContainer').dialog("option", "position", { my:"top", at:"top+50", of: window }); 
    $('#contactContainer').html(''); 
    } 
}); 

$("#contactContainer").dialog('open'); 

这里是Fiddle。在这种小提琴,

  1. 单击任意文本框的(手段焦点。在这个例子中它是一个我们有值“测试在这里”)。

  2. 现在通过单击对话框的滚动条并将其向下/向上拖动并查看发生了什么来滚动对话框。它放松了我们点击的文本框的焦点。如果我按标签,它将焦点再次设置到第一个字段。这很奇怪。

如果我用鼠标滚动,焦点仍然在同一个字段上。这个是正常的。

坦率地说,我不知道为什么会发生这种情况。有人可以帮助我如何防止滚动时丢失焦点的对话框?我希望把焦点保留在同一个领域。

回答

5

固定。问题是tabindex

我让你fiddle工作。诀窍是去除tabindex只是对话框的初始化后,就可以这样做:

$(".ui-dialog.ui-widget").removeAttr("tabindex") 

如果你想这种行为是永久性的,你可以编辑jQuery的源代码。如果您到达对话框部分,您将看到一个名为_createWrapper的功能。在里面,你可以看到这样的事情:

.attr({ 

      // Setting tabIndex makes the div focusable 
      tabIndex: -1, 
      role: "dialog" 
     }) 

从那里取出tabindex属性,而这一切!

+0

这很有趣..“tabindex”有什么问题。你可以解释吗? –

+0

我记得正确的解释,因为几个月前我必须处理这个问题。但是滚动条被放置在'$(“。ui-dialog”)'padding上,所以,当你点击滚动条时就像点击容器一样,这会导致你失去焦点。删除tabindez会使元素不可聚焦,因此当您点击它时,不会失去对输入的关注。然后,在某些地方,我不记得JQuery UI有正确的处理程序,以正确的方式重新添加可聚焦属性。 –

+0

是的,你是对的!问题是'tabindex',但在我的情况下,我无法删除它,因为只有当我们添加'tabindex'时,默认的浏览器导航操作(空格键和shift +空格键)才能在弹出窗口中工作。如果我们在对话框中按下shift +空格键时删除了'tabindex',它将仅滚动背景屏幕而不是对话框 –

2

我想这可能会对你有所帮助。

$('#divWithTheScrollbar').scroll(function() { 
    $('#elementLosingFocus').focus(); 
}); 
+0

好主意,但我并不想用这个对所有对话框我有。需要知道为什么在JQuery对话框中发生这种情况。没有? –

0

从在网上看了看,似乎最有可行的选择是你添加了一个@pritishvaidya。

你必须认识到,当你点击页面上的任何东西时,触发焦点事件。这意味着如果您在让文本框处于焦点状态时单击滚动条,则会将该滚动条放在焦点上并失去文本框的焦点。

我建议你通过@pritishvaidya实现解决方案,但是在它的周围添加一些验证,你知道哪个控件最后被关注,然后在滚动条焦点丢失时强制重点关注。这会给客户带来最小的压力,并且可以让您在使用情况下取得进展。

快乐编码!

+0

你是对的'当你点击页面上的任何东西时,触发焦点事件。这意味着如果您在将文本框放在焦点上的同时单击滚动条,则会将该滚动条放在焦点上并失去文本框的焦点。但是,当我按下标签页时,这里重点是再次设置到第一个字段。这很奇怪。没有? –

0

试试这个;其工作(不需要添加ID或其他选择与inpus)

var focused; 
setInterval(function(){ 
     focused = $(':focus'); 
},500) 

$("#contactContainer").scroll(function(){ 
     //console.log(focused[0]); 
     $(focused).focus(); 
}) 
+0

这不是问题的理想解决方案 –

0

这可能是一个通用的解决方案,但它需要进行测试:

var lastFocus; 

$(document) 
    .on("focus", function(e) { lastFocus = e.target; }) 

$("#divWithTheScrollbar").scroll(function() { 
    if (lastFocus) lastFocus.focus(); 
}) 

它通常可以节省哪个元素有集中最后并在滚动div时再次设置它。 您需要对其进行扩展,以便有意识的blur事件仍然可以在滚动后不再次聚焦的情况下工作。

0

请尝试以下JavaScript更新。

https://jsfiddle.net/3q22xLhk/5/您可以检查小提琴

$("#contactContainer").dialog({ 
    closeOnEscape: false, 
    modal: true, 
    dialogClass: 'contactsFooter', 
    open: function(event, ui) { 
    $(".ui-dialog-titlebar-close").show(); 
    $('#dialog_footer').remove(); 
    $(".contactsFooter").append('<div class="" id="dialog_footer"><div class="dialog-footer-buttons"><button type="button" id ="close" class="button-style-2" onclick="$(\'#hasChangedForm\').val(\'\');" style="margin-left: 5px;">Cancel</button></div></div>'); 
    }, 
    autoOpen: false, 
    width: 300, 
    minHeight: 'auto', 
    maxHeight: 400, 
    position: { 
    my: 'top', 
    at: 'top+50' 
    }, 
    close: function() { 
    $('#contactContainer').dialog("option", "position", { 
     my: "top", 
     at: "top+50", 
     of: window 
    }); 
    $('#contactContainer').html(''); 
    } 
}); 
var scrolling = false; 
$("#contactContainer").dialog('open'); 
var lastFocusTextbox = null; 
$("#contactContainer input").focus(function() { 
    lastFocusTextbox = this; 
}); 

$("#contactContainer").scroll(function(e) { 
    scrolling = true; 
}); 


$("#contactContainer").mouseup(function() { 
    if (scrolling) { 
    if (lastFocusTextbox != null) { 
     $(lastFocusTextbox).focus(); 
    } 
    scrolling = false; 
    } 
});