在 Android 浏览器中,链接并不总是执行 onClick 导致焦点

Posted

技术标签:

【中文标题】在 Android 浏览器中,链接并不总是执行 onClick 导致焦点【英文标题】:In Android Browser link does not always execute onClick causing focus instead 【发布时间】:2011-01-12 06:43:45 【问题描述】:

我正在尝试为使用 HREF 的链接编写一个非常标准的 JS 行为 onClick 处理程序,我正面临一个奇怪的问题,这是由我认为是 android 上的焦点/触摸模式行为引起的。

有时当我单击链接时,它并没有执行操作,而是简单地被选中/聚焦,只有一个焦点矩形,甚至还有一个填充的焦点矩形(选择而不是仅仅聚焦?)。

现在的伪代码是

<a href="#" onClick="toggleDivBelowToShowHide(); return false;">go</a>

我试过做类似的事情:

<a href="#" onTouchStart="toggleDivBelowToShowHide(); return false;">go</a>

但有时我仍然会遇到同样令人讨厌的问题。

【问题讨论】:

澄清一些最新发现:我可以肯定地说,只有当项目具有焦点矩形并且我以某种特定方式单击它时,它才不起作用。在这种情况下,该项目然后被“选中”(短暂地完全变为蓝色)并且仅执行此操作而不执行操作。有没有类似“onSelect”的东西? 同理,当它聚焦时自动执行你的函数? 嗯,它似乎已经集中在这一点上......我希望用户能够点击该项目并展开它。它看起来像 +/- 扩展项。 整个链接都集中/选中了吗?或者可能只是链接文本的一部分? (只用“go”可能有点难以测试。)比如:如果我在上面你名字的右边稍微点击一下,然后向左拖动,我会逐个字母地选择你名字的文本。跨度> 我也有这个问题 - 有时 android 只是不想关注链接。但是,在我的应用程序中,如果我删除所有 preventDefault() 处理程序,则可以解决此问题...不幸的是,这会稍微破坏应用程序,但至少链接可以工作? 【参考方案1】:

尝试在 webview 上启用 javascript

在拥有 webview 的 Activity 中,试试这个...

WebView wv = (WebView) findViewById(R.id.webview);
wv.getSettings().setJavaScriptEnabled(true);

我遇到了同样的问题,但发现是因为我没有启用 Javascript。

【讨论】:

【参考方案2】:

尝试摆脱href 属性,看看是否有帮助。例如,当使用WebView 组件查看时,这有效:

<p><a onClick="whereami()">Update Location</a></p>

【讨论】:

对不起,这对我不起作用——仍然可以“选择”链接。我也尝试过 DIV——只要它们具有 onClick 属性,它们也是可选的。【参考方案3】:

我想知道它是否与 onclick 相关——我是否正确地假设不时点击 any 链接不会跟随它?对我来说,这似乎与您触摸屏幕的方式(或如何解释)有关,例如可能通过单击链接的 next 并拖动一点,而不是单击 on em> 链接?

(如果我的假设是正确的,那么这可能是硬件故障:也许您可以在另一台设备上尝试?或者如果屏幕没有很好地对齐,它可能只发生在链接的特定一侧,然后可能会有一些软件偏移量可以改变吗?)

【讨论】:

抱歉,我们这里有很多手机——这不是硬件问题。不知何故,您可以选择元素。 @Artem,但这对于普通链接永远不会发生? (没有任何onclick的链接?) 普通链接很难分辨,因为普通链接通常会离开页面,而这种行为需要多次点击才能被选中。我会继续测试这个。【参考方案4】:

尝试将此“驱动程序”插入您的页面代码中,并让我们知道它是否有效。 . .它似乎在我有同样问题的网站上工作:

//Mouse & Touch -> Consistent Click / Mouse Commands -> Useful driver
(function() 
  var isTouch = false;
  var simulated_flag = 'handler_simulated';
  var touch_click_array = ;
  const clickMoveThreshold = 20; //Pixels

  function mouseHandler(event) 
    if (isTouch) 
      if (!event.hasOwnProperty(simulated_flag)) 
        //Unreliable mouse commands - In my opinion
        var fixed = new jQuery.Event(event);
        fixed.preventDefault();
        fixed.stopPropagation();
      
    
    else 
      //Mouse commands are consistent
      //TODO: generate corresponding touches
    
  

  function mouseFromTouch(type, touch) 
    var event = document.createEvent("MouseEvent");
    event.initMouseEvent(type, true, true, window, 1, touch.screenX, touch.screenY, touch.clientX, touch.clientY
      , false, false, false, false, 0, null);
    event[simulated_flag] = true;

    touch.target.dispatchEvent(event);
  ;

  function touchHandler(event) 
    var touches = event.changedTouches
      ,first = touches[0]
      ,type = ""
      ;

    if (!event.hasOwnProperty(simulated_flag)) 
      isTouch = true;

      //Simulate mouse commands
      switch (event.type) 
        case "touchstart":
          for (var i = 0; i < touches.length; i++) 
            var touch = touches[i];
            touch_click_array[touch.identifier] =  x: touch.screenX, y: touch.screenY ;
          
          mouseFromTouch("mousedown", first);
          break;

        case "touchmove":
          for (var i = 0; i < touches.length; i++) 
            var touch = touches[i];
            var id = touch.identifier;
            var data = touch_click_array[id];
            if (data !== undefined) 
              if (Math.abs(data.x - touch.screenX) + Math.abs(data.y - touch.screenY) > clickMoveThreshold) 
                delete touch_click_array[id];
              
            
          
          mouseFromTouch("mousemove", first);
          break;

        case "touchcancel":
          //Not sure what should happen here . . .
          break;

        case "touchend":
          mouseFromTouch("mouseup", first);
          for (var i = 0; i < touches.length; i++) 
            var touch = touches[i];
            if (touch_click_array.hasOwnProperty(touch.identifier)) 
              mouseFromTouch("click", touch);
              delete touch_click_array[touch.identifier];
            
          
          break;
      
    
  

  document.addEventListener("mousedown", mouseHandler, true);
  document.addEventListener("mousemove", mouseHandler, true);
  document.addEventListener("mouseup", mouseHandler, true);
  document.addEventListener("click", mouseHandler, true);

  document.addEventListener("touchstart", touchHandler, true);
  document.addEventListener("touchmove", touchHandler, true);
  document.addEventListener("touchcancel", touchHandler, true);
  document.addEventListener("touchend", touchHandler, true);

)();

现在它不是一个 100% 完整的脚本 - 多点触控可能会有点不稳定,如果您根据触控命令构建界面,它不会在此版本中生成这些。但是,它解决了我的链接点击问题。

Erm - ps - 它使用 jQuery。如果你需要一个非jQuery的版本,你大概可以把new jQuery.EventmouseHandler()函数中去掉(也就是说,使用原来的事件:var fixed = event;),相信大部分浏览器都可以。不过,我并不是一个 js 兼容性专家。

PPS - 使用 Android 1.6 测试

PPPS - 必须修改脚本以允许阈值 - 实际设备在按下期间触发移动事件时遇到了一些问题。可能不理想;如果有人想提出更好的方法,我很想听听......

【讨论】:

非常有趣的解决方案...通过简单地在文本周围制作一个更大的彩色矩形,我们在所有这些点击中获得了更多的运气...尽管当我们回来时我很想尝试您的解决方案到这个。 是的,它工作得很好 - 我必须在我的应用程序中编写触摸 -> 鼠标事件,以获得有关拖动操作的实时信息;我应该从鼠标 -> 触摸驱动程序开始,并且刚刚使用触摸代码编写了我的应用程序,并且可能会朝那个方向发展,但不幸的是我自己实际上并没有智能手机,所以我开始了用鼠标代码。【参考方案5】:

最近我遇到了完全相同的问题。我正在使用按钮上的onclick。有时它根本不执行javascript。对我有用的是 在 webview 中加载 url 之前启用 javascript

    // Enable javascript
    WebSettings webSettings = mWebView.getSettings();
    webSettings.setJavaScriptEnabled(true);

    // To bind javascript code to android
    mWebView.addJavascriptInterface(new JavaScriptInterface(this), "Android");

    mWebView.loadUrl(url);

【讨论】:

以上是关于在 Android 浏览器中,链接并不总是执行 onClick 导致焦点的主要内容,如果未能解决你的问题,请参考以下文章

Android 似乎并不总是执行我的功能

Android KeyStore - 密钥并不总是持久的

使用 Appium 时,Android 物理设备中的键盘并不总是隐藏

Android:在浏览器中打开一个 URL [重复]

android小部件-重启后并不总是注册待处理的意图

使用 android 获取 gps 位置 - 并不总是有效