WKWebView 禁用 长按弹出UIMenuController

本文介绍了如何在iOS应用中使用WKWebView禁用长按选择文本的功能,并提供了通过JavaScript注入CSS来实现这一目标的具体代码示例。同时,还分享了如何获取WKWebView中当前选中的内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

iOS8开始使用WKWebView,但实际使用过程中和UIWebView有许多区别。比如禁止在webview中长按弹出UIMenuController的操作:


  • UIWebView中
 - (BOOL)canPerformAction:(SEL)action withSender:(id)sender
{
    return NO;
}

  • WKWebView中,则需要通过js进行操作
// 禁止选择CSS
NSString *css = @"body{-webkit-user-select:none;-webkit-user-drag:none;}";

// CSS选中样式取消
NSMutableString *javascript = [NSMutableString string];
[javascript appendString:@"var style = document.createElement('style');"];
[javascript appendString:@"style.type = 'text/css';"];
[javascript appendFormat:@"var cssContent = document.createTextNode('%@');", css];
[javascript appendString:@"style.appendChild(cssContent);"];
[javascript appendString:@"document.body.appendChild(style);"];

// javascript注入
WKUserScript *noneSelectScript = [[WKUserScript alloc] initWithSource:javascript injectionTime:WKUserScriptInjectionTimeAtDocumentEnd forMainFrameOnly:YES];
WKUserContentController *userContentController = [[WKUserContentController alloc] init];
[userContentController addUserScript:noneSelectScript];
WKWebViewConfiguration *configuration = [[WKWebViewConfiguration alloc] init];
configuration.userContentController = userContentController;

// WKWebView 初始化
WKWebView *webView = [[WKWebView alloc] initWithFrame:frame configuration:configuration];

另外提一句,获取webView当前选中的内容方法:

NSString *highlighted = [_webView stringByEvaluatingJavaScriptFromString:@"window.getSelection().toString();"];

参考链接:
http://blog.youkuaiyun.com/qq_30513483/article/details/51959187

http://www.cnblogs.com/sunshine-anycall/p/3245940.html

https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/AddingCustomEditMenuItems/AddingCustomEditMenuItems.html

http://notnull.hateblo.jp/entry/2015/05/15/134643

http://www.itdadao.com/articles/c15a265474p0.html

http://supereasyapps.com/blog/2014/4/17/show-the-uimenucontroller-and-display-custom-edit-menus-for-uiviewcontroller-uitableviewcontroller-and-uicollectionview-on-ios-7

http://www.jianshu.com/p/ddd59867909a

<think>好的,我现在要解决的问题是如何在H5网页中禁用按图片时弹出的默认菜单。用户提到他们想通过代码实现这一点,所以我要先回忆一下相关的技术点。 首先,我记得在HTML中,图片元素是使用<img>标签的。当用户按图片时,特别是在移动端,通常会触发系统的默认菜单,比如保存图片或者识别二维码。要禁用这个行为,可能需要用到CSS或JavaScript的方法。 然后,我想到CSS中的pointer-events属性。这个属性可以控制元素是否响应鼠标或触摸事件。如果设置为none,可能会阻止默认的触摸行为。比如,引用[4]中提到,给外层容器设置pointer-events: none;可以禁用触摸和点击事件。不过需要注意的是,这样做可能会影响子元素的交互,如果图片需要点击事件的话,可能需要单独处理。 另外,JavaScript方面,可以监听contextmenu事件,这是右键菜单事件,通常在桌面端右键点击时触发,但在移动端按也可能触发。通过preventDefault()方法可以阻止默认的上下文菜单。不过不确定在移动端是否有效,可能需要测试。 还有一种方法是使用user-select属性设置为none,防止用户选择文本,但这对图片菜单可能无效。不过结合-webkit-touch-callout: none;可能会有帮助,这个属性专门针对iOS的触摸反馈,比如按链接或图片时的弹出菜单。引用[4]中的例子虽然没有直接提到图片,但可能适用。 接下来,可能需要综合使用这些方法。比如,在CSS中对图片应用: img { -webkit-touch-callout: none; user-select: none; pointer-events: none; } 但pointer-events设为none的话,图片就无法点击了。如果图片需要交互,比如点击跳转,就不能这样用。这时候可能需要在外层容器设置pointer-events: none,然后在内部的图片或其他需要交互的元素上重新启用pointer-events: auto。不过引用[4]中的例子是给外层容器设置pointer-events: none,然后内部元素可能需要单独处理。 另外,引用[5]中提到iOS的一些日期格式问题,这可能和问题无关,但需要注意不同浏览器的兼容性。比如,-webkit-touch-callout在安卓上可能无效,所以可能需要针对不同系统处理。 或者,使用JavaScript监听touchstart或touchend事件,阻止默认行为。比如: document.addEventListener('touchstart', function(e) { if (e.target.tagName === 'IMG') { e.preventDefault(); } }, { passive: false }); 不过要注意,passive: false可能会影响滚动性能,需要谨慎使用。 总结可能的解决方案: 1. CSS方法:使用-webkit-touch-callout: none;和user-select: none;,可能加上pointer-events: none;(但影响交互)。 2. JavaScript方法:阻止contextmenu事件或touch事件的默认行为。 需要测试不同平台的效果,特别是iOS和安卓。根据引用[3],iOS按二维码时有不同行为,可能需要特别处理。引用[4]中的pointer-events方法可能有效,但需要权衡交互需求。 因此,最终的解决方案可能结合CSS和JavaScript,具体步骤可能是: - 添加CSS样式阻止默认触摸反馈。 - 使用JavaScript阻止上下文菜单事件。</think>要在H5网页中禁用按图片时弹出的默认菜单,可通过以下方法实现: --- ### 方法一:纯CSS解决方案 ```css img { /* 禁用iOS按菜单 */ -webkit-touch-callout: none; /* 禁用文本选择(辅助作用) */ user-select: none; -moz-user-select: none; -ms-user-select: none; -webkit-user-select: none; } ``` **说明** - `-webkit-touch-callout: none` 直接阻止iOS系统对图片的按菜单[^4]。 - `user-select` 系列属性用于禁止用户选中图片周围文本(间接减少菜单触发概率)。 --- ### 方法二:JavaScript事件拦截 ```javascript // 阻止右键菜单(桌面端) document.addEventListener('contextmenu', (e) => { if (e.target.tagName === 'IMG') { e.preventDefault(); } }); // 阻止按菜单(移动端) document.addEventListener('touchstart', (e) => { if (e.target.tagName === 'IMG') { e.preventDefault(); } }, { passive: false }); ``` **说明** - `contextmenu` 事件拦截右键菜单[^2]。 - `touchstart` 事件拦截移动端按行为,需设置 `passive: false` 以允许 `preventDefault`[^5]。 --- ### 方法三:指针事件控制(慎用) ```html <div class="img-container"> <img src="image.jpg" /> </div> <style> .img-container { /* 禁用容器内所有元素的触摸事件 */ pointer-events: none; } .img-container img { /* 单独启用图片的触摸事件(若需点击功能) */ pointer-events: auto; } </style> ``` **说明** - 外层容器设置 `pointer-events: none` 禁用所有交互,再通过 `pointer-events: auto` 恢复图片的点击事件。 - 此方法可能影响复杂交互场景,需谨慎使用。 --- ### 兼容性说明 | 方法 | iOS支持 | 安卓支持 | 桌面端支持 | |----------|-------|-------|--------| | CSS方案 | ✅ | ⚠️部分 | ❌ | | JS事件拦截 | ✅ | ✅ | ✅ | | 指针事件控制 | ✅ | ✅ | ✅ | --- ### 相关问题 1. 如何仅允许特定图片触发按菜单? 2. 禁用菜单后如何实现自定义功能? 3. 为什么安卓系统上部分浏览器仍会显示下载选项? --- 通过上述方法,可有效禁用默认菜单。若需保留点击功能,推荐**方法二**;若无需交互,**方法一**更简洁[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值