Chrome在使用position sticky/fixed时裁剪幽灵图像

3
我正在尝试使用HTML5拖放和position: fixed从位于屏幕左侧固定位置的菜单中拖动元素。下面的代码在Safari和Firefox中运行良好,但在Chrome中,在滚动后,从拖放API生成的“ghost”图像不可见。如果您恰当地滚动,可以拖动“ghost”图像的一部分,这表明它以某种奇怪的方式被裁剪。将left div的位置设置为absolute可以正常工作,但如果可能的话,我宁愿不使用JS计算定位。我确实为此创建了一个fiddle,但在Safari和Firefox中运行时存在其他一些非常奇怪的问题(尽管它在Chrome中显示了问题):https://jsfiddle.net/e4fvrr5y/ 这是我用来测试的完整代码:
<!doctype html>
<head>
    <style>
        body {
            display: flex;
        }
        .left {
            width: 200px;
            height: 200px;
            background-color: #0f0;
            position: fixed;
        }
        .right {
            margin-left: 200px;
            width: 200px;
            height: 3000px;
            background: linear-gradient(white, black);
        }

        .draggable {
            background-color: #00f;
            padding: 20px;
            color: #fff;
            cursor: pointer;
        }

    </style>
</head>
<body>
    <div class="left">
        <div class="draggable" draggable="true" ondragstart="drag(event)">Draggable element</div>
    </div>
    <div class="right">
    </div>

    <script>
        function drag(ev) {
            ev.dataTransfer.setData("text", "foo");
        }
    </script>
</body>
</html>

我在网上搜索到了Chromium的以下bug报告: 问题 605119 它似乎与位置相对有关。但是那已经有将近两年了,而且已经被报告修复,所以这个问题很可能已经被合并到Chrome中了。有其他人遇到这个问题吗?如果有,你们采取了什么步骤来解决它?

可能与此错误有关:https://bugs.chromium.org/p/chromium/issues/detail?id=798182 - Simon V.
是的,它看起来是相关的!你能找到任何解决方法吗?我尝试了一些东西,但没有得到很好的结果(除了使用第三方拖放,我宁愿不这样做)。 - Dr_Derp
我能够找到一个适用于我的特定情况的解决方法,但它不适用于你的情况(使用top/left定位替换CSS变换)。我建议你在Chromium问题跟踪器上打开一个新问题并提供复现步骤。 - Simon V.
如果我无法让Lorenzo的解决方案工作,我可能会这样做。 - Dr_Derp
今天在Chrome Canary中刚刚修复了一个bug。我可以确认它也解决了这个bug。我将在这里发布一个带有更多细节的答案。 - Simon V.
2个回答

2
这是一个出现在Chrome 63.0.3223.0版本中的漏洞(参见此问题)。
根据问题追踪器,在接下来的几周内,下一个稳定版本的Chrome(64.x)应该会修复这个问题。
请注意,修复程序已经在Chrome Canary中可用。
更新于25-01-2018:
Chrome 64已经发布。

好的,听起来很完美,希望这能澄清问题。谢谢提供信息! - Dr_Derp
作为一个(相对较晚的)后续,这在Chrome中已不再是一个问题。 - Dr_Derp

1

Chrome在拖动操作开始时要求被拖动的元素对浏览器可见。我曾经遇到过同样的问题,通过克隆可拖动元素并将其附加到主体上,并在固定容器中将其定位在可拖动元素上来解决此问题。接下来,我将克隆元素设置为元素dragImage。最后,在dragend上删除克隆。我正在使用jQuery,这是我的解决方法,希望能帮助到你:

var $clone = null;
document.addEventListener( 'dragstart',  function( ev ) {
    var $el = $( ev.target );
    $clone = $el.clone(); 
    $clone.css( {
        position: 'absolute',
        top: $el.offset().top,
        left: $el.offset().left,
        width: $el.width()
    } );
    $('body').append( $clone )
    ev.dataTransfer.setDragImage( $clone[ 0 ], 0, 0);
} );

document.addEventListener( 'dragend', function( ev ){
    $clone.remove();
    $clone = null;
} );   

好的,我会尝试一下,听起来有希望。我有点想到 Chrome 不能处理它的原因,但不太确定如何解决。会更新结果。 - Dr_Derp

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