news 2026/5/15 20:52:09

HarmonyOS ArkWeb 系列给 Web 里的链接和图片加专属长按菜单 bindSelectionMenu

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
HarmonyOS ArkWeb 系列给 Web 里的链接和图片加专属长按菜单 bindSelectionMenu

文章目录

      • 和 onContextMenuShow 的差别
      • 核心参数说明
      • 流程图:bindSelectionMenu 工作机制
      • 完整示例:链接菜单 + 图片菜单分开绑定
      • 高级用法:禁用长按手势
      • 和 `SelectionMenuOptionsExt` 配合:加菜单出现/消失动画
      • 一个常见误区
      • 写在最后

你有没有遇到这种需求:长按网页里的链接弹出"在新窗口打开/复制链接/收藏",长按图片弹出"保存/分享/设为壁纸"?这两种不同元素的长按菜单要分开定制。bindSelectionMenu正是为这个场景设计的。

和 onContextMenuShow 的差别

老实说刚接触这块 API 时我把这两个搞混过。区别如下:

  • onContextMenuShow:全局的长按菜单拦截,不区分元素类型,一刀切替换
  • bindSelectionMenu按元素类型分别绑定,链接绑一套,图片绑另一套,互不干扰

选哪个取决于你要不要区分对待不同元素。如果链接和图片的菜单不一样,用bindSelectionMenu

核心参数说明

// 方法签名.bindSelectionMenu(elementType:WebElementType,// 要绑定到哪种元素menuBuilder:CustomBuilder,// 菜单内容(@Builder)responseType:WebResponseType,// 触发方式options?:SelectionMenuOptionsExt// 可选配置(预览、回调等))

WebElementType

  • WebElementType.LINK→ 链接
  • WebElementType.IMAGE→ 图片

WebResponseType

  • WebResponseType.LONG_PRESS→ 长按触发
  • WebResponseType.RIGHT_CLICK→ 右键触发(折叠屏/平板)

流程图:bindSelectionMenu 工作机制

完整示例:链接菜单 + 图片菜单分开绑定

import{webview}from'@kit.ArkWeb';import{pasteboard}from'@kit.BasicServicesKit';@Entry@Componentstruct WebBindSelectionMenuDemo{controller:webview.WebviewController=newwebview.WebviewController();privateresult:WebContextMenuResult|undefined=undefined;// 当前长按的链接地址和图片地址@StatelinkURL:string='';@StateimageURL:string|Resource|undefined=undefined;@StatepreviewWidth:number=300;@StatepreviewHeight:number=200;uiContext:UIContext=this.getUIContext();// ========== 链接菜单 ==========@BuilderLinkMenuBuilder(){Menu(){MenuItem({content:'复制链接'}).onClick(()=>{constdata=pasteboard.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.result=event.result;this.linkURL=event.param.getLinkUrl();this.previewWidth=this.uiContext.px2vp(event.param.getPreviewWidth());this.previewHeight=this.uiContext.px2vp(event.param.getPreviewHeight());constsrcUrl=event.param.getSourceUrl();if(srcUrl.startsWith('resource://rawfile/')){this.imageURL=$rawfile(srcUrl.substring(19));}else{this.imageURL=srcUrl;}returntrue;}returnfalse;})}}}

高级用法:禁用长按手势

有时候你完全不想让用户长按选择文字,可以用WebDisableLongPress的方案——通过 JavaScript 注入禁用:

import{webview}from'@kit.ArkWeb';@Entry@Componentstruct WebDisableLongPressDemo{controller:webview.WebviewController=newwebview.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.showOverlay=true;},onDisappear:()=>{this.showOverlay=false;this.result?.closeContextMenu();}})

一个常见误区

bindSelectionMenuonContextMenuShow配合使用,不是二选一。

  • bindSelectionMenu控制的是菜单内容
  • onContextMenuShow里你需要返回 true,同时可以在这里保存result和 URL 信息,供菜单里的按钮使用

如果onContextMenuShow返回false,系统菜单会覆盖你的bindSelectionMenu

写在最后

bindSelectionMenu在需要区分元素类型的场景下非常好用,链接菜单和图片菜单各自独立,代码也更清晰。配合下一篇的预览菜单(PREVIEW_MENU)食用效果更佳。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/15 20:49:50

数据库系统原理 · 数据库安全性与完整性 · 自学总结

本章核心:数据库里存着关键数据,怎么防止坏人偷/改/删?怎么防止脏数据混进来?怎么在应用层把安全防线筑牢?一、数据库安全性1.1 是什么?数据库安全性 保护数据库,防止不合法的使用导致数据泄露…

作者头像 李华
网站建设 2026/5/15 20:48:48

Intel智能系统框架在零售物联网中的应用与优化

1. 智能零售的物联网革命零售行业正在经历一场由物联网技术驱动的深刻变革。走进任何一家现代化零售门店,你会发现POS终端、电子货架标签、数字标牌、智能购物车、安防摄像头等设备已经构成了一个复杂的生态系统。这些设备产生的数据流就像零售店的神经系统&#xf…

作者头像 李华
网站建设 2026/5/15 20:48:07

STM32 CubeMX HAL库驱动ADS1115:从配置到多通道数据采集实战

1. ADS1115与STM32的完美组合 在嵌入式系统开发中,高精度模拟信号采集是个常见需求。无论是监测电池电压、采集传感器信号,还是进行精密测量,ADS1115这款16位ADC芯片都是性价比极高的选择。它最高支持860SPS的采样率,内置可编程增…

作者头像 李华
网站建设 2026/5/15 20:47:21

从设计到部署:一款面向轻量化产线的6轴关节机器人实战解析

1. 为什么轻量化产线需要6轴关节机器人 在小型工件装配场景中,传统机械臂常遇到两个致命问题:一是庞大的机身挤占产线空间,二是固定轨迹动作难以适应多变的工件姿态。去年我参与改造的一条散热器装配线就遇到过这种情况——原有直角坐标机器人…

作者头像 李华