2

我试图弄清楚在 Mobile Safari、Android 浏览器和 Firefox for Android(“Fennec”)中看到的效果是错误还是预期行为。基本上,问题在于<input>元素可以在某些情况下接收键盘焦点,即使该<input>元素最初没有被用户点击。

这是一个可重现的测试用例:

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="viewport" content="width=device-width, user-scalable=no">
<style>
#screenCover {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    background-color: rgba(0, 0, 0, 0.3);
    z-index: 1;
}

#newItemInput {
    position: absolute;
    width: 200px;
    height: 20px;
}
</style>
</head>
<body>

<div id="screenCover"></div>
<input id="newItemInput" type="text">

<script type="text/javascript" language="JavaScript">
var screenCoverEl = document.getElementById("screenCover"),
    newItemInputEl = document.getElementById("newItemInput");

newItemInputEl.value = String(navigator.userAgent);

screenCoverEl.addEventListener("touchend", function (event) {
    // Move the <input> element in the way.
    newItemInputEl.style.top = (event.changedTouches[0].clientY - 10) + "px";
    newItemInputEl.style.left = (event.changedTouches[0].clientX - 10) + "px";

    // Hide the screen cover. Note that the screen cover was the original target of the tap.
    screenCoverEl.style.display = "none";
}, false);

newItemInputEl.addEventListener("click", function (event) {
    this.setSelectionRange(0, this.value.length);
}, false);
</script>
</body>
</html>

http://jsfiddle.net/f7TKc/2/

或直接在移动浏览器中:

http://fiddle.jshell.net/f7TKc/2/show/

在此示例中,屏幕封面位于文档顶部,但在 上touchend,屏幕封面被隐藏,并且<input>元素被移动到用户点击屏幕封面的位置。在 Mobile Safari、Android 浏览器和 Fennec 13.0b1 中,该<input>元素莫名其妙地获得了键盘焦点。

我无法在较新版本的 Fennec 中对此进行测试,因为它在模拟器中崩溃。

这是错误还是预期行为?

4

3 回答 3

1

是的,我认为这是一个错误,这可能在同一行: http ://code.google.com/p/android/issues/detail?id=6721如果是这样,那么该链接有一些解决方法其他人都试过了,你可以试试

于 2012-10-24T17:23:51.497 回答
0

触摸事件按以下顺序调用:touchstart、touchend、click。您需要知道您的触摸事件的 touchstart 是否发生在您的输入上。您可以隐式声明一个对象变量(这在 javascript 中是允许的)并将其初始化为 false。在 touchstart 事件中将其设置为 true。然后检查它在 touchend 和/或点击事件中的值。以下代码完全按预期工作。

    <script type="text/javascript" language="JavaScript">
    var screenCoverEl = document.getElementById("screenCover"),
    newItemInputEl = document.getElementById("newItemInput");

newItemInputEl.value = String(navigator.userAgent);


screenCoverEl.addEventListener("touchstart", function (event) {
    // Move the <input> element in the way.

    screenCoverEl.style.display = "none";

    newItemInputEl.style.top = (event.touches[0].clientY - 10) + "px";
    newItemInputEl.style.left = (event.touches[0].clientX - 10) + "px";

    // Hide the screen cover. Note that the screen cover was the original target of the tap.

}, false);

newItemInputEl.touchStartedHere = false; // remember if a touch event started on this input
newItemInputEl.addEventListener("touchstart", function (event) {

    this.touchStartedHere = true; //set true if did..

}, false);
newItemInputEl.addEventListener("click", function (event) {


    if(this.touchStartedHere){ // do what you want if touch started here
        this.setSelectionRange(0, this.value.length);  
    }else{  // prevent from receiving focus if touch didn't start here.
        this.blur();
    }
    this.touchStartedHere = false;  // reset to false to prepare for next touch event.

}, false);
</script>
于 2012-10-23T00:09:10.640 回答
0

我想这是预期的行为。

移动网络浏览器的开发人员需要为小显示器上设计不佳的网页做出特殊调整。

如果网页无法正确缩放,则 UI 元素很容易被另一层覆盖。

允许点击事件通过层向下传播将防止 UI 元素不可用。

我没有任何文件来支持这个理论。

- - - 编辑 - - - -

在玩弄了您的代码之后,我意识到屏幕覆盖已被删除,并且输入被移动到“touchstart”处的触摸位置。然后输入在“touchend”处获得焦点。

您可以通过在输入移动之前设置延迟来验证这一点。如果您的手指在输入之前已经移开,它将不会获得焦点。如果移动输入时您仍在触摸屏幕,它将获得焦点。

screenCoverEl.addEventListener("touchstart", function (event) {

screenCoverEl.style.display = "none";
setTimeout(function() {
        newItemInputEl.style.top = (event.touches[0].clientY - 10) + "px";
        newItemInputEl.style.left = (event.touches[0].clientX - 10) + "px";
    },250);


}, false);
于 2012-10-20T09:35:51.607 回答