
文章目录和 onContextMenuShow 的差别核心参数说明流程图bindSelectionMenu 工作机制完整示例链接菜单 图片菜单分开绑定高级用法禁用长按手势和 SelectionMenuOptionsExt 配合加菜单出现/消失动画一个常见误区写在最后你有没有遇到这种需求长按网页里的链接弹出在新窗口打开/复制链接/收藏长按图片弹出保存/分享/设为壁纸这两种不同元素的长按菜单要分开定制。bindSelectionMenu正是为这个场景设计的。和 onContextMenuShow 的差别老实说刚接触这块 API 时我把这两个搞混过。区别如下onContextMenuShow全局的长按菜单拦截不区分元素类型一刀切替换bindSelectionMenu按元素类型分别绑定链接绑一套图片绑另一套互不干扰选哪个取决于你要不要区分对待不同元素。如果链接和图片的菜单不一样用bindSelectionMenu。核心参数说明// 方法签名.bindSelectionMenu(elementType:WebElementType,// 要绑定到哪种元素menuBuilder:CustomBuilder,// 菜单内容BuilderresponseType:WebResponseType,// 触发方式options?:SelectionMenuOptionsExt// 可选配置预览、回调等)WebElementTypeWebElementType.LINK→ 链接WebElementType.IMAGE→ 图片WebResponseTypeWebResponseType.LONG_PRESS→ 长按触发WebResponseType.RIGHT_CLICK→ 右键触发折叠屏/平板流程图bindSelectionMenu 工作机制完整示例链接菜单 图片菜单分开绑定import{webview}fromkit.ArkWeb;import{pasteboard}fromkit.BasicServicesKit;EntryComponentstruct WebBindSelectionMenuDemo{controller:webview.WebviewControllernewwebview.WebviewController();privateresult:WebContextMenuResult|undefinedundefined;// 当前长按的链接地址和图片地址StatelinkURL:string;StateimageURL:string|Resource|undefinedundefined;StatepreviewWidth:number300;StatepreviewHeight:number200;uiContext:UIContextthis.getUIContext();// 链接菜单 BuilderLinkMenuBuilder(){Menu(){MenuItem({content:复制链接}).onClick((){constdatapasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN,this.linkURL);pasteboard.getSystemPasteboard().setData(data);})MenuItem({content:在当前页打开}).onClick((){this.controller.loadUrl(this.linkURL);})}}// 图片菜单 BuilderImageMenuBuilder(){Menu(){MenuItem({content:复制图片}).onClick((){this.result?.copyImage();this.result?.closeContextMenu();})MenuItem({content:分享图片}).onClick((){console.info(分享图片,this.imageURL);this.result?.closeContextMenu();})}}build(){Column(){Web({src:$rawfile(index.html),controller:this.controller}).javaScriptAccess(true).fileAccess(true).onlineImageAccess(true).imageAccess(true).domStorageAccess(true)// 绑定链接元素的长按菜单.bindSelectionMenu(WebElementType.LINK,this.LinkMenuBuilder,WebResponseType.LONG_PRESS,{onAppear:(){console.info(链接菜单出现);},onDisappear:(){this.result?.closeContextMenu();}})// 绑定图片元素的长按菜单.bindSelectionMenu(WebElementType.IMAGE,this.ImageMenuBuilder,WebResponseType.LONG_PRESS,{onAppear:(){console.info(图片菜单出现);},onDisappear:(){this.result?.closeContextMenu();}})// 配合 onContextMenuShow 保存 result 和 URL.onContextMenuShow((event){if(event){this.resultevent.result;this.linkURLevent.param.getLinkUrl();this.previewWidththis.uiContext.px2vp(event.param.getPreviewWidth());this.previewHeightthis.uiContext.px2vp(event.param.getPreviewHeight());constsrcUrlevent.param.getSourceUrl();if(srcUrl.startsWith(resource://rawfile/)){this.imageURL$rawfile(srcUrl.substring(19));}else{this.imageURLsrcUrl;}returntrue;}returnfalse;})}}}高级用法禁用长按手势有时候你完全不想让用户长按选择文字可以用WebDisableLongPress的方案——通过 JavaScript 注入禁用import{webview}fromkit.ArkWeb;EntryComponentstruct WebDisableLongPressDemo{controller:webview.WebviewControllernewwebview.WebviewController();build(){Column(){Web({src:$rawfile(index.html),controller:this.controller}).onPageEnd((){// 页面加载完毕后注入 JS禁用长按选中this.controller.runJavaScript(document.body.style.userSelect none; document.body.style.webkitUserSelect none;);})}}}如果你想更细粒度只禁止某个区域把document.body换成对应的元素选择器即可。和SelectionMenuOptionsExt配合加菜单出现/消失动画.bindSelectionMenu(WebElementType.LINK,this.LinkMenuBuilder,WebResponseType.LONG_PRESS,{onAppear:(){// 菜单出现时可以做一些 UI 联动this.showOverlaytrue;},onDisappear:(){this.showOverlayfalse;this.result?.closeContextMenu();}})一个常见误区bindSelectionMenu和onContextMenuShow要配合使用不是二选一。bindSelectionMenu控制的是菜单内容onContextMenuShow里你需要返回 true同时可以在这里保存result和 URL 信息供菜单里的按钮使用如果onContextMenuShow返回false系统菜单会覆盖你的bindSelectionMenu。写在最后bindSelectionMenu在需要区分元素类型的场景下非常好用链接菜单和图片菜单各自独立代码也更清晰。配合下一篇的预览菜单PREVIEW_MENU食用效果更佳。