【问题标题】:Google chrome scroll overflow bug谷歌浏览器滚动溢出错误
【发布时间】:2014-06-27 07:32:59
【问题描述】:

这是一个奇怪的错误,很难弄清楚。

我们创建了一个地图应用程序,弹出窗口中有一个select 元素。它设置了size 属性。 select 元素的父元素具有overflow:auto 样式。当出现滚动时,尝试在选择元素上选择某些内容会使正文向下滚动。但是 body 有 overflow:hidden 风格,它会杀了我们。

这是我创建的两个小提琴:

http://jsfiddle.net/e6BK3/1/

http://jsfiddle.net/e6BK3/8/

当它不专注于谷歌浏览器时,尝试在选择元素上选择第一个选项。然后看到它滚动所有可用的父元素滚动。

谷歌浏览器版本:34.0.1847.131

【问题讨论】:

  • 你可以应用overflow:scroll;当鼠标悬停在元素上时,否则溢出:隐藏;
  • 溢出:隐藏或溢出:滚动都没有关系。这两个值都有两个小提琴。但结果是一样的。
  • 我不确定您将什么行为归类为错误。父元素太小,无法包含整个 select 元素。如果 Chrome 不滚动父元素,则只有一半的选项可见。您想阻止 Chrome 尝试显示整个 select 元素吗?
  • 不,我希望谷歌浏览器阻止滚动所有父元素。如果您仔细查看 fiddles,它会滚动所有父元素。隐藏溢出属性时,它的行为确实相同。
  • 当它滚动时,它选择的选项与我尝试选择的选项不同

标签: html google-chrome select scroll overflow


【解决方案1】:

如果你想在谷歌浏览器中实现this,你所要做的就是:

  • 在您的项目中加载 jQuery(可能您已经这样做了)
  • 将此代码放入您的 CSS 中

CSS:

select:focus {
    outline: 0;
}

将此代码放入您的 javascript:

$('.innder-div').on('scroll', function() {
    $(this).scrollTop(0);     
})

$('.root').on('scroll', function() {
    $(this).scrollTop(0);     
})

$('select').on('mouseover', function(){
    $(this).focus();
})

Jsfiddle here

更新:另一种解决方案是在左键单击选择框之前使用中键(滚轮按钮),一切都会正常工作。所以解决方案是使用javascript检测第一次点击,并在它之前触发中键点击,之后才点击鼠标左键。

【讨论】:

  • 使用您的解决方案,用户根本无法滚动(我的意思是“故意”),并且大多数选择框肯定是隐藏的。 :(
  • 其实我希望解决方案能像你的一样短,但它完全阻止了滚动。
  • 我在我的状态中滚动可见和隐藏元素作为父级。我赞成您的回答,是的,它解决了溢出:隐藏状态。再次感谢您的回答,真的很短。
【解决方案2】:

我想我做到了! :)

重点是防止option标签mousedown事件上的任何其他传播,并手动管理select框的焦点。

jsFiddle

我尽量说清楚:

$('option')
.on('mousedown', function(e){
    // Prevent any other propagations
    e.stopImmediatePropagation();

    // Focus on the select DOM element
    // but saving the scrollTop of each parent before
    $(this)
    .parents()
    .filter(function(){
        // filter only those which have a scroll visible
        return $(this)[0].scrollHeight > $(this)[0].clientHeight;
    })
    .each(function(_,elt){
        // and for each, save the scroll value in data set
        $(elt).data('saveScroll', $(elt).scrollTop());
    })

    // Then trigger the focus option of the select DOM element
    // And finally the custom 'scrollback' event
    $(this).parent('select')
    .trigger('focus')
    .trigger('scrollback');

});

$('select')
// This customized event is for getting back the value of the scroll of all parents
// only if this value exists
.on('scrollback'
    , function(e){
        $(this)
        .parents()
        .filter(function(){
            // filter only those which have this data in data-set
            return 0 === $(this).data('saveScroll') || ~~$(this).data('saveScroll');
        })
        .each(function(_,elt){
            // and for each, putting back the right scroll value
            $(elt).scrollTop($(elt).data('saveScroll'));
            $(elt).removeData('saveScroll');
        })
    });

这可能并不完美,因为它是一个 hack。

至少它甚至可以与multiple-typed select 一起使用。而且它是跨浏览器兼容的。

【讨论】:

  • 感谢您的回答,它适用于除正文以外的所有元素。正文在溢出时仍然滚动:隐藏样式。对此有任何想法吗?我会接受你的回答,但等待是否有其他人来。
  • 如果您在选择之外单击,为什么选择仍然保持焦点?
  • @paulalexandru:因为它没有;)
  • 其实我解决了我的问题。我用了你的代码。但是对于body元素,我发现该元素导致body溢出,并将其'display'更改为'none',而不是返回'block'。它导致 body 元素滚动到顶部。说起来很复杂:)感谢您的回答。
  • @HalilIbrahim:有时,更简单的事情最难实现。这就是为什么它很有趣!很好,如果你的 pb 解决了。不要忘记“检查”我!
猜你喜欢
  • 2014-06-21
  • 1970-01-01
  • 1970-01-01
  • 2013-01-27
  • 1970-01-01
  • 2021-11-08
  • 2014-09-16
  • 1970-01-01
  • 2022-10-31
相关资源
最近更新 更多