为什么调用focus()会破坏我的CSS转换?

bbs*_*nbb 10 javascript html5 css-transitions

这个 html文件显示了3面板布局.当我更改面板时,"左"属性上的css过渡给我一个很好的滑动效果.这一切都有效但是,当我更换面板时,我想将焦点放在新面板的输入上.任何人都可以告诉我为什么对focus()的调用打破了css转换,并让我在两个面板之间中途停留?它只发生在前进.如果我注释掉过渡,它就有效,如果我将调用延迟到具有超时的focus(),它就可以工作.

问题出现在Chrome,IE和Firefox中.

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <title>Sliding Bug</title>
    <style>
        #wrapper {
            width: 100%;
            height: auto;
            overflow: hidden;
        }

        #panelContainer {
            position: relative;
            transition: left 1000ms ease;
        }

        .panel {
            float: left;
        }
    </style>

</head>
<body>
    <div id="wrapper">
        <div id="panelContainer">
            <div id="panel0" class="panel" style="background-color: #888;">
                panel zero
                <input id="btn0" class="focussable" type="button" onclick="slide(1);" value="forward" />
            </div>
            <div id="panel1" class="panel" style="background-color: #AAA;">
                panel 1
                <input id="btn1" class="focussable" type="button" onclick="slide(2);" value="forward" />
                <input type="button" onclick="slide(0);" value="back" />
            </div>
            <div id="panel2" class="panel" style="background-color: #CCC;">
                panel 2
                <input id="btn2" class="focussable" type="button" onclick="slide(1);" value="back" />
            </div>
        </div>
    </div>
    <script>
        var panelContainer;
        var panels = new Array();
        var numPanels;
        var currentPanel = 0;

        window.addEventListener('load', init, false);
        function init() {
            setTimeout(function () { window.scrollTo(0, 1); }, 10); //hiding the browser address bar in iPhone/Android

            panelContainer = document.getElementById("panelContainer");
            panels = document.getElementsByClassName("panel");
            numPanels = panels.length;
            sizeResize();
        }
        function sizeResize() {
            panelContainer.style.width = (numPanels * window.innerWidth) + "px";
            panelContainer.style.height = window.innerHeight + "px";
            for (var i = 0; i < numPanels; i++) {
                panels[i].style.width = window.innerWidth + "px";
                panels[i].style.height = window.innerHeight + "px";
            }
            slide();
        }
        window.onresize = sizeResize;

        function slide(panel) {
            if (panel != undefined)
                currentPanel = panel;
            panelContainer.style.left = -(window.innerWidth * currentPanel) + "px";
            if (panel >= 0) {
                panels[panel].getElementsByTagName("input")[0].focus();//shows problem
                //window.setTimeout(function () { panels[panel].getElementsByTagName("input")[0].focus() }, 100);//no problem

            }
        }
    </script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

Kuz*_*eko 6

正如@ user1585345正确指出的那样,浏览器立即滚动到焦点元素,以将其带入当前视图,而不是px!

此处发生的事情如下:您更改了元素的相对位置,但是立即更改了焦点,因为在事件触发时看不到聚焦的元素,因此内容也会滚动(突然结束动画)。

您应该仅在动画完成时才明确地聚焦,以便浏览器识别出不需要滚动。

  • 这让我在三年后免于发疯。但这很痛苦,因为这意味着您必须使用超时,并希望您是否使用 CSS 过渡,或者切换到脚本动画,以便您知道它们何时完成。 (2认同)
  • false,有两个事件侦听器“ontransitionend”和“onanimationend”,您可以为其添加事件,然后触发 focus() 函数。 (2认同)