赞
踩
本示例介绍了给Webview页面中可点击元素(超链接/图片)绑定长按/鼠标右击时的自定义菜单的方案。
使用说明
长按Web页面中的图片或者链接元素,弹出自定义的Menu菜单,创建自定义的操作,如复制图片、使用浏览器打开链接、复制链接等。
Web({ src: $rawfile("index.html"), controller: this.controller })
.bindPopup(this.showMenu,
{
builder: this.MenuBuilder(),
enableArrow: false,
placement: Placement.LeftTop,
mask: false,
onStateChange: (e) => {
if (!e.isVisible) {
this.showMenu = false;
this.result!.closeContextMenu();
}
}
})
// TODO: 知识点: 长按或者鼠标右键触发该事件,当前只对图片、链接有效。
.onContextMenuShow((event) => {
if (event) {
this.result = event.result;
this.param = event.param;
logger.info(TAG, "x coord = " + event.param.x());
logger.info(TAG, "y coord = " + event.param.y());
logger.info(TAG, "link url = " + event.param.getLinkUrl())
this.linkUrl = event.param.getLinkUrl();
this.inputType = this.param.getInputFieldType();
}
logger.info(TAG, TAG, `x: ${this.offsetX}, y: ${this.offsetY}`);
this.showMenu = true;
return true;
})
Menu() { // 如果元素存在图片 if (this.param?.existsImageContents()) { MenuItem({ content: $r('app.string.copy_image'), }) .onClick(() => { this.result?.copyImage(); this.showMenu = false; }) } // 如果元素可剪切 if (this.param?.getEditStateFlags() === ContextMenuEditStateFlags.CAN_CUT) { MenuItem({ content: $r('app.string.cut'), }) .onClick(() => { this.result?.cut(); this.showMenu = false; }) } // 如果元素可拷贝 if (this.param?.getEditStateFlags() === ContextMenuEditStateFlags.CAN_PASTE) { MenuItem({ content: $r('app.string.copy'), }) .onClick(() => { this.result?.copy(); this.showMenu = false; }) } // 如果元素可粘贴 if (this.param?.getEditStateFlags() === ContextMenuEditStateFlags.CAN_PASTE) { MenuItem({ content: $r('app.string.paste'), }) .onClick(() => { this.result?.paste(); this.showMenu = false; }) } // 如果元素可全选 if (this.param?.getEditStateFlags() === ContextMenuEditStateFlags.CAN_PASTE) { MenuItem({ content: $r('app.string.select_all'), }) .onClick(() => { this.result?.selectAll(); this.showMenu = false; }) } // 如果元素为链接 if (this.linkUrl) { // 浏览器打开链接 MenuItem({ content: $r('app.string.open_link'), }) .onClick(() => { let wantInfo: Want = { action: 'ohos.want.action.viewData', entities: ['entity.system.browsable'], uri: this.linkUrl }; this.context.startAbility(wantInfo).then(() => { logger.info(TAG, 'startAbility succeed'); }).catch((err: BusinessError) => { logger.error(TAG, `startAbility failed, code is ${err.code}, message is ${err.message}`); return; }); this.showMenu = false; }) // 复制链接 MenuItem({ content: $r('app.string.copy_link'), }) .onClick(() => { let pasteData = pasteboard.createData('text/plain', this.linkUrl); pasteboard.getSystemPasteboard().setData(pasteData, (error) => { if (error) { logger.error(TAG, 'Failed to set PasteData. Cause: ' + error.message); return; } logger.info(TAG, 'Succeeded in setting PasteData.'); }); this.showMenu = false; }) } // 判断是否输入框 if (this.inputType != ContextMenuInputFieldType.None) { MenuItem({ content: $r('app.string.input_field'), }) .onClick(() => { this.showMenu = false; }) } }
因为不同元素触发的弹窗宽高尺寸不一样,还需要根据手指按压位置和弹窗尺寸选择弹窗显示的位置。
let offset: Position = { x: 0, y: 0};
if (this.pressPosX <= this.webWidth / 2) {
offset.x = -(this.webWidth / 2 - this.pressPosX) + popupWidth / 2 + FINGER_OFFSET_X;
} else {
offset.x = -(this.webWidth / 2 - this.pressPosX) - popupWidth / 2 - FINGER_OFFSET_X;
}
if (this.pressPosY <= this.webHeight / 2) {
offset.y = -(this.webHeight / 2 - this.pressPosY) + popupHeight / 2 + FINGER_OFFSET_Y;
} else {
offset.y = (this.pressPosY - this.webHeight / 2) - popupHeight / 2 - FINGER_OFFSET_Y;
}
logger.debug(TAG, `popup offset: ${offset.x}, ${offset.y}`);
return offset;
}
webcustompressmenu // HAR类型
├─mainpage
│ └─MainPage.ets // ArkTS页面
├─rawfile
│ └─index.html // HTML页面
为了能让大家更好的学习鸿蒙(HarmonyOS NEXT)开发技术,这边特意整理了《鸿蒙开发学习手册》(共计890页),希望对大家有所帮助:https://qr21.cn/FV7h05
https://qr21.cn/FV7h05
https://qr21.cn/FV7h05
https://qr21.cn/FV7h05
https://qr18.cn/F781PH
https://qr18.cn/F781PH
1.项目开发必备面试题
2.性能优化方向
3.架构方向
4.鸿蒙开发系统底层方向
5.鸿蒙音视频开发方向
6.鸿蒙车载开发方向
7.鸿蒙南向开发方向
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。