css
// 在页面开始加载时就注入的 JS(禁用右键和长按)
private void injectDisableContextMenuJS(WebView view) {
String earlyJs = "javascript:(function(){" +
// 只禁用右键菜单和长按调用系统菜单
"document.oncontextmenu = function(){return false;};" +
// 不禁用选择,但要阻止系统默认行为
"document.oncopy = function(e){" +
" e.preventDefault();" +
" return false;" +
"};" +
"document.oncut = function(e){" +
" e.preventDefault();" +
" return false;" +
"};" +
// 临时禁用 touch callout(长按菜单)
"document.body.style.webkitTouchCallout = 'none';" +
"})();";
view.evaluateJavascript(earlyJs, null);
}
css
// 注入JS,监听selectionchange事件,把选中文本传给Java层
private void injectSelectionJS() {
// 关闭 X5 的长按菜单
if (mWebView.getX5WebViewExtension() != null) {
mWebView.getX5WebViewExtension().setLongPressTextExtensionMenu(1);
}
Strin js = "javascript:(function(){" +
// 1. 禁用右键/长按菜单
"document.oncontextmenu = function(){return false;};" +
// 2. 禁止默认选中启动行为,阻止原生操作栏弹出
// "document.onselectstart = function(){return false;};" +
// 3. 禁止默认复制剪切行为
"document.oncopy = function(){return false;};" +
"document.oncut = function(){return false;};" +
"document.onpaste = function(){return false;};" +
// 4. 自定义选中文本背景色 + 禁用系统选中呼出菜单
"var style = document.createElement('style');" +
"style.innerHTML = " +
"'*{" +
"-webkit-touch-callout:none !important;" + // 禁用系统长按菜单
"-webkit-user-select:text !important;" + // 允许文字选中
"user-select:text !important;" +
"}" +
"::selection{background:#FFE082 !important; color:#000000 !important;}" + // 选中背景色
"::-moz-selection{background:#FFE082 !important; color:#000000 !important;}'; " +
"document.head.appendChild(style);" +
// 5. 自己监听选中变化,给安卓传值
"document.onselectionchange = function(){" +
"var sel = window.getSelection();" +
"var text = sel.toString().trim();" +
"if(text.length > 0){" +
"var rect = sel.getRangeAt(0).getBoundingClientRect();" +
"window.copyAndroid.copyToClipboard(text,rect.left, rect.top, rect.right, rect.bottom);" +
"}else{" +
"window.copyAndroid.copyToClipboard(text,0,0,0,0);" +
"}" +
"};" +
"})();";
mWebView.evaluateJavascript(js, null);
}
onPageStarted 方法里面执行 injectDisableContextMenuJS这个方法。在onPageFinished 方法里面执行injectSelectionJS 方法。 Android 注入copyToClipboard方法 获取内容 跟位置。
java
其中 copyAndroid指的是
mWebView.addJavascriptInterface(new WebViewInterfaceImpl(mContext), "copyAndroid");
Android 端注入copyToClipboard接收方法 获取相关位置坐标实现自定义视图
css
@JavascriptInterface
@Override
public void copyToClipboard(String text,float left,float top,float right,float bottom) {
}