【问题标题】:Disabling the context menu on long taps on Android在 Android 上长按时禁用上下文菜单
【发布时间】:2011-03-25 17:29:51
【问题描述】:

我想禁用在我的网络应用程序中长按(触摸并按住)图像后出现的上下文菜单。我已经看到了不同想法的帖子,但它们似乎都不适合我。

有没有办法通过 HTML/CSS/Javascript 在 Android 上执行此操作?

【问题讨论】:

    标签: javascript android mobile-webkit


    【解决方案1】:

    上下文菜单有自己的事件。你只需要抓住它并阻止它传播。

    window.oncontextmenu = function(event) {
         event.preventDefault();
         event.stopPropagation();
         return false;
    };
    

    【讨论】:

    • 有效!但现在我只想在锚元素上阻止上下文菜单。我有过滤器工作(当 [a] 时返回 false,否则返回 true)但返回 true 不显示对话框。所以..你如何告诉浏览器它应该显示?
    • 我不会在函数中放置过滤器。将函数仅附加到要禁用其上下文菜单的元素会更好、更简洁。
    • 在 Cordova Windows 上使用 Win10/UWP/MS Edge WebView :)
    • 如何在 React 类组件中使用它?
    【解决方案2】:

    这应该适用于 1.6 或更高版本(如果我没记错的话)。我认为 1.5 或更早版本没有解决方法。

    <!DOCTYPE html>
    <html>
    <head>
      <script>
        function absorbEvent_(event) {
          var e = event || window.event;
          e.preventDefault && e.preventDefault();
          e.stopPropagation && e.stopPropagation();
          e.cancelBubble = true;
          e.returnValue = false;
          return false;
        }
    
        function preventLongPressMenu(node) {
          node.ontouchstart = absorbEvent_;
          node.ontouchmove = absorbEvent_;
          node.ontouchend = absorbEvent_;
          node.ontouchcancel = absorbEvent_;
        }
    
        function init() {
          preventLongPressMenu(document.getElementById('theimage'));
        }
      </script>
    </head>
    <body onload="init()">
      <img id="theimage" src="http://www.google.com/logos/arthurboyd2010-hp.jpg" width="400">
    </body>
    </html>
    

    【讨论】:

    • 自 8 月 8 日以来没有看到任何 OP,所以我决定自己使用 SDK 进行测试。我测试了 1.5、1.6 和 2.2,它们在所有版本上都运行良好,所以我很高兴现在就奖励赏金而无需等待 OP 确认。 +1 也是一个很好的答案。
    • @Andy:听起来是个好主意。我已经接受了 Roman 的回答,并将尝试进行更广泛的测试。如果它看起来像一个设备错误,那就这样吧。如果没有,我将发布另一个更具体的问题。再次感谢对 stackoverflow 新人的热烈欢迎!
    • 此解决方案禁用所有触摸事件。这可能会受到限制!
    • 这真的是正确答案吗?似乎img.addEventListener('contetxmenu', function(e) { e.preventDefault(); return false; }, false); 应该工作不?上述解决方案将阻止所有输入。
    • 你经常看到这种事情,但如果可以的话,你真的很想避免干扰事件的传播。给定事件对于“您的”组件以及页面上的其他组件可能很重要。例如,下拉菜单外的点击可能是滚动下拉列表的队列,以及与点击直接对应的任何操作。找到一种不会完全破坏您页面上的事件处理的方法。
    【解决方案3】:

    对我来说,吸收所有事件不是一个选项,因为我想禁用长按下载,同时仍然允许用户缩放和平移图像。我只能通过在图像顶部分层“屏蔽”div 来使用 css 和 html 解决这个问题,如下所示:

    <div class="img-container">
      <div class="shield"></div>
      <img src="path.jpg">
    </div>
    
    img {
        max-width: 100%;
    }
    
    .shield {
        position: absolute;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 1;
    }
    

    希望这对某人有所帮助!

    【讨论】:

    • 您可能需要在父容器中添加position:relative,以防止父容器接管所有空间。如果父级是 td 并有一个 ontouchstart 或其他与之链接的交互事件处理程序,这将特别棘手,因为您不会在视觉上看到 td 占用了所有区域。
    【解决方案4】:

    可以做到using CSS:

    img {
      pointer-events: none;
    }
    

    【讨论】:

    • 这不仅会禁用长按,还会禁用例如正常的水龙头,所以并不总是一个选项。
    【解决方案5】:

    我使用了 Nurik 的完整示例,但该元素(我页面中的输入图像)也被禁用了点击。

    我把原来的行改成这样:

    原行:

    node.ontouchstart = absorbEvent_;
    

    我的改变:

    node.ontouchstart = node.onclick;
    

    使用此方法,我禁用了 logpress 上的弹出保存图像菜单,但保留了点击事件。

    我正在使用 Dolphin HD 浏览器和 Android 2.2 的 7 英寸平板电脑上进行测试,并且运行良好!

    【讨论】:

      【解决方案6】:

      它将禁用复制,但不会禁用选择。

      document.oncontextmenu = function() {return false;};
      

      在 webView 中工作。

      【讨论】:

      • 拯救了我的一天。谢谢!
      【解决方案7】:

      将此 CSS 代码用于移动设备

      -webkit-touch-callout: none;
      -webkit-user-select: none; /* Disable selection/copy in UIWebView */
      

      【讨论】:

      • 这不适用于请求的浏览器,chrome。
      【解决方案8】:
      pointer-events: none; // for Android
      
      -webkit-touch-callout: none; // for iOS
      
      -webkit-user-select: none; 
      
      -khtml-user-select: none; 
      
      -moz-user-select: none; 
      
      -ms-user-select: none; 
      
      user-select: none;
      

      【讨论】:

      • 请添加一些描述来解释答案。
      • pointer-events: none; 本质上是 CSS 元素的 return false,所以它使我的按钮在这种情况下不起作用。
      【解决方案9】:

      我也遇到过类似的问题。我已经从这个线程和另一个 safari 线程尝试了几个解决方案来解决同样的问题 (Preventing default context menu on longpress / longclick in mobile Safari (iPad / iPhone)) 。不好的是我不能使用 onTouchStart、onTouchEnd 等...

      仅阻止来自 onContextMenu 的事件。来自 React 16.5.2 的片段。 仅在 chrome 中测试。

          <img {...props} onContextMenu={event => event.preventDefault()}
          onTouchStart={touchStart}
          onTouchEnd={touchEnd} />

      希望它可以帮助某人。干杯!


      【讨论】:

        【解决方案10】:
        <a id="moo" href=''> </a>
        
        <script type="text/javascript">
            var moo = document.getElementById('moo');
        
            function handler(event) {
                event = event || context_menu.event;
        
                if (event.stopPropagation)
                    event.stopPropagation();
        
                event.cancelBubble = true;
                return false;
            }
        
            moo.innerHTML = 'right-click here';
        
            moo.onclick = handler;
            moo.onmousedown = handler;
            moo.onmouseup = handler;
        </script>
        

        捕获 onContextMenu 事件,并在事件处理程序中返回 false。

        在某些浏览器中,您还可以捕获单击事件并使用 event.button 检查哪个鼠标按钮触发了该事件。

        【讨论】:

        • 抱歉,这两种方法都不适用于 Android。 oncontextmenu 事件永远不会触发,当用户按住元素时,click 事件也不会触发。
        【解决方案11】:

        刚刚遇到类似的问题。上述建议在 Andoid 浏览器中对我不起作用,但我发现将有问题的图像显示为 CSS 背景图像而不是嵌入图像可以解决问题。

        【讨论】:

          【解决方案12】:

          通过原始 javascript,上下文菜单不会调用任何事件。也许在 Java 世界中有些东西......实际上在 Android webkit 中存在一些关于 javascript 事件的问题(例如焦点无法正常工作)。

          【讨论】:

          • 是的,我同意。由于我已经开发了一个将在浏览器中使用的 JavaScript 库,因此使用 java 对我来说不是一个选项。
          猜你喜欢
          • 1970-01-01
          • 2014-05-04
          • 2022-11-13
          • 2015-03-10
          • 1970-01-01
          • 1970-01-01
          • 2016-08-08
          • 1970-01-01
          • 2015-04-21
          相关资源
          最近更新 更多