在IE中,当表格获得焦点时,表格滚动条会向上跳。

7
问题:我有一个带有包装
overflow-y : auto属性的table,一旦table得到焦点,滚动条就会跳上去。我该如何防止这种情况发生?

我在IE9中遇到了这种行为,但在Chrome中没有。

请注意:我已经给表格添加了tabindex,以便它可以接收焦点。我通过单击表格并在程序上对其进行聚焦。

jsFiddle: http://jsfiddle.net/msdevs/r6TzS/4/

  1. 向下滚动表格
  2. 单击页面上的其他元素,使表格失去焦点
  3. 点击表格以将焦点放在它上面
  4. 滚动条跳上去了

HTML:

    <div>
        <table id="tabl" tabindex="1">
            <thead>
                <tr>
                    <th style="font-weight: bold">head</th>
                </tr>
            </thead>
            <tbody>
                <tr>
                    <td>first</td>
                </tr>
                <tr>
                    <td>SEC</td>
                </tr>
                <tr>
                    <td>dsadfawdfadfa</td>
                </tr>
                <tr>
                    <td>dsadfawdfadfa</td>
                </tr>
.
.
.
                 <tr>
                    <td>dsadfawdfadfa</td>
                </tr>
            </tbody>
        </table>
    </div>

CSS:

table {
    table-layout: fixed;
    font-family: arial;
    font-size: 11px;
    text-align: left;
    outline: none;
    width: 625px;
}
div {
    overflow-y: auto;
    overflow-x: hidden;
    height: 150px;
    width: 300px
}

JS:

$('table').focusin(function (e) {
    console.log("table got focus - scroller jumps up");
}).click(function () {
    $('table').focus();
});

1
如果我现在使用的是Windows机器,我会尝试创建一个onblur处理程序(我认为这与onfocus相反)。然后,我将获取表格的当前滚动位置。这样,当表格下次获得焦点时,您可以重新设置滚动位置。 - enhzflep
1
我现在想要你的极客T恤。 - Andrea Ligios
我在这里。问题在IE 11中仍然存在。 - Chris
5个回答

7

以下内容对我很有帮助 - 在包装器上保留当前滚动位置的记录,并在失去焦点后重新安装它。

http://jsfiddle.net/r6TzS/10/

$('#wrapper').scroll(function(){
    $(this).data( {posY: $(this).scrollTop()} )
})
.blur(function(){
    $(this).scrollTop( $(this).data("posY") );
})

在某些情况下,模糊事件没有被触发,所以我也向点击事件添加了相同的处理程序 - 就像@JSuar一样。 真是神奇。 谢谢你们两个。 - MichaelS

2
这个问题的被接受答案实际上不准确。主要问题是Internet Explorer对focus()的实现。在被接受的JSFiddle中,它从未调用focus(),因此原始问题从未发生。如果您从该示例中删除所有javascript,则滚动问题仍不会发生。您应该调用setActive()而不是focus(),它将元素设置为活动状态,但不会尝试将其滚动到视图中。 setActive()方法在此处描述 - http://help.dottoro.com/ljqmdirr.php。请注意,它仅受ie支持。
这是一个有效的示例 - http://jsfiddle.net/r6TzS/100/
$('table').focusin(function (e) {
    console.log("table got focus - scroller jumps up");
}).click(function () {
    $('table').setActive();
});

在IE 11中,我看到“对象不支持属性或方法'setActive'”在你的例子中。 - Alexander Komarov

1

更新:通过添加 mouseleavemouseenter,我成功地使滚动条在IE9和Chrome v24.0.1312.57上正常工作。

示例:http://jsfiddle.net/r6TzS/9/

var scrollPos = 0;
var ignoreScrollPos = 0;

$('div').mouseleave(function() {
    scrollPos = $('div').scrollTop(); 
    console.log("Scroll position set: " + scrollPos);        
    ignoreScrollPos = 0;
}).mouseenter(function() {
    ignoreScrollPos = 1;
});

$('table').focusin(function (e) {
    console.log("table got focus - scroller jumps up: " 
                + $('div').scrollTop()); 
}).click(function () {    
    if (!ignoreScrollPos) {
        console.log("Set position to: " + scrollPos);
        $('div').scrollTop(scrollPos);  
    }
});

这个解决方案可以防止IE9中滚动条跳动。不过,现在我发现它在Chrome中不能正常工作。无论如何,我认为分享这个解决方案会很有帮助。

0

在IE中,将焦点设置在<table/>标记上会通过将焦点设置到标记中的第一个元素来视觉重置表格。

这可以通过在<table/>click事件中显式地将焦点设置为最后一个元素来轻松演示。如果你仔细看,在点击时,表格实际上会非常快地滚动到顶部,然后再滚动到底部。

这是因为,仅仅点击table就会首先将focus设置为table(请注意,这是固有行为,而不是你的代码的结果),一旦完成,你定义的自定义处理程序接收事件并导致td:nth-last-child(1),即最后一个td被设置为焦点,从而将表格滚动到底部。

如果添加一个设置焦点的button,你会注意到差异。

现在这只是你问题中的 为什么 部分!如果我了解你的实际需求,我可以提供更合适的 如何修复 答案。


0
你尝试过在表格上应用scroll-y选项而不是DIV吗?或者你可以尝试使用"tbody"标签,并将所有TR放入其中。然后在此上应用scroll-y。我希望这对我的知识来说起作用。 如果不行,请告诉我,否则我会给你另一个解决方案 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接