<template>
<view class="uni-flex-item">
<web-view id="web-view" class="uni-flex-item" :style="webViewStyle" :src="src"
:webview-styles="webview_styles" :horizontalScrollBarAccess="horizontalScrollBarAccess" :verticalScrollBarAccess="verticalScrollBarAccess"
:bounces="bounces" :disable-user-select-menu="disableUserSelectMenu" @message="message" @error="error" @loading="loading"
@load="load" @download="download" @contentheightchange="contentheightchange" @touchstart="touchstart" @tap="tap">
</web-view>
<!-- #ifdef APP -->
<view class="uni-padding-wrap uni-common-mt">
<view class="uni-btn-v">
<input class="uni-input" confirmType="go" placeholder="输入网址跳转" @confirm="confirm" maxlength="-1" />
</view>
<view class="uni-row uni-btn-v">
<button class="uni-flex-item" type="primary" :disabled="!canGoBack" @click="back">后退</button>
<button class="margin-left-5 uni-flex-item" type="primary" :disabled="!canGoForward"
@click="forward">前进</button>
</view>
<view class="uni-row uni-btn-v">
<button class="uni-flex-item" type="primary" @click="reload">重新加载</button>
<button class="margin-left-5 uni-flex-item" type="primary" @click="stop">停止加载</button>
</view>
<view class="uni-row uni-btn-v">
<button class="uni-flex-item" type="primary" @click="nativeToWeb">原生和Web通信</button>
<!-- #ifdef APP-ANDROID || APP-IOS || APP-HARMONY -->
<button class="margin-left-5 uni-flex-item" type="primary" @click="getContentHeight">获取内容高度</button>
<!-- #endif -->
</view>
<view class="uni-row uni-btn-v">
<button class="uni-flex-item" type="primary" @click="loadData">加载页面内容</button>
<!-- 用于演示大尺寸平板中能用窄屏展示响应式内容 -->
<button id="half-screen-toggle" class="margin-left-5 uni-flex-item" type="primary" @click="setHalfScreen">宽窄屏切换</button>
</view>
<view class="uni-btn-v">
<navigator url="/pages/component/web-view/web-view-scroll">
<button type="primary">scroll-view嵌套web-view</button>
</navigator>
</view>
<!-- #ifdef APP-ANDROID || APP-HARMONY || APP-IOS -->
<view class="uni-row uni-btn-v">
<view class="uni-row uni-flex-item align-items-center">
<text>显示横向滚动条</text>
<switch :checked="true" @change="changeHorizontalScrollBarAccess"></switch>
</view>
<view class="uni-row uni-flex-item align-items-center">
<text>显示竖向滚动条</text>
<switch :checked="true" @change="changeVerticalScrollBarAccess"></switch>
</view>
</view>
<view class="uni-row uni-btn-v">
<view class="uni-row uni-flex-item align-items-center">
<text>开启bounces</text>
<switch :checked="true" @change="changeBounces"></switch>
<!-- #ifdef APP-ANDROID || APP-IOS-->
<text>禁用选择菜单</text>
<switch :checked="false" @change="changeDisableUserSelectMenu"></switch>
<!-- #endif -->
</view>
</view>
<!-- #endif -->
<!-- #ifdef APP-IOS -->
<view class="uni-row uni-btn-v" v-if="isProd() === false">
<view class="uni-row uni-flex-item align-items-center">
<text>前进、后退功能在Windows端需要打自定义基座,MAC端需要配置Xcode环境后进行真机运行或者打自定义基座</text>
</view>
</view>
<!-- #endif -->
</view>
<!-- #endif -->
<!-- #ifdef APP-ANDROID || APP-IOS -->
<view class="safe-area-inset-bottom"></view>
<!-- #endif -->
</view>
</template>
<script>
// #ifdef APP
import { canWebViewGoBack, canWebViewGoForward, hasNativeView } from '@/uni_modules/uts-get-native-view';
// #endif
let webviewElement = null as UniWebViewElement | null
export default {
data() {
return {
src: 'https://www.dcloud.io',
webview_styles: {
progress: {
color: '#FF3333'
}
},
halfWindowMode:false,
webviewContext: null as WebviewContext | null,
loadError: false,
horizontalScrollBarAccess: true,
verticalScrollBarAccess: true,
bounces: true,
disableUserSelectMenu: false,
canGoBack: false,
canGoForward: false,
// 自动化测试
autoTest: false,
eventLoading: null as UTSJSONObject | null,
eventLoad: null as UTSJSONObject | null,
eventError: null as UTSJSONObject | null,
eventContentHeightChange: null as UTSJSONObject | null,
pointerEvents: 'auto',
isTouchEnable: false,
loadingCount: 0
}
},
computed:{
fullScreen(){
return !this.halfWindowMode
},
webViewStyle(){
return {
width: this.halfWindowMode?'50%':'100%',
'pointer-events': this.pointerEvents
}
},
},
onReady() {
// #ifdef APP
// TODO web 实现createWebviewContext
// this.webviewContext = uni.createWebviewContext('web-view', this)
// NOTE 绑定到 this 上会被代理导致无法调用方法
webviewElement = uni.getElementById('web-view') as UniWebViewElement //推荐使用element,功能更丰富
// console.log('url: ',this.webviewElement?.getAttribute("src"));
// this.webviewElement?.setAttribute("src","https://ext.dcloud.net.cn/")
// #endif
},
onUnload() {
webviewElement = null;
},
methods: {
setHalfScreen(){
this.halfWindowMode = !this.halfWindowMode
},
getPackageName() : string {
let packageName : string = ""
// #ifdef APP-IOS
const res = uni.getAppBaseInfo();
packageName = res.bundleId
// #endif
return packageName
},
isProd() : boolean {
if (this.getPackageName() == 'io.dcloud.hellouniappx') {
return true
}
return false
},
back() {
webviewElement?.back();
},
forward() {
webviewElement?.forward();
},
reload() {
this.loadingCount = 0
webviewElement?.reload();
},
stop() {
webviewElement?.stop();
},
nativeToWeb() {
webviewElement?.evalJS("alert('hello uni-app x')");
},
// #ifdef APP-ANDROID || APP-IOS || APP-HARMONY
getContentHeight() : number {
const height = webviewElement?.getContentHeight() ?? 0;
console.log('contentHeight', height);
if (!this.autoTest) {
uni.showModal({
content: ' 当前内容高度: ' + height,
showCancel: false
});
}
return height;
},
loadData() {
webviewElement?.loadData({
data: '<p><a href="https://www.dcloud.io/hbuilderx.html">HBuilderX</a><br/><img src="/unidoc/zh/uni@2x.png"></img><h1>HBuilderX,轻巧、极速,极客编辑器</h1><p style="color:red;"><small>HBuilderX,轻巧、极速,极客编辑器 </small><big>HBuilderX,轻巧、极速,极客编辑器</big><strong>HBuilderX,轻巧、极速,极客编辑器</strong><i>HBuilderX,轻巧、极速,极客编辑器 </i><u>HBuilderX,轻巧、极速,极客编辑器</u><del>HBuilderX,轻巧、极速,极客编辑器</del></p><h2>uni-app x,终极跨平台方案</h2>、<p style="background-color: yellow;"><small>uni-app x,终极跨平台方案 </small><big>uni-app x,终极跨平台方案</big><strong>uni-appx,终极跨平台方案 </strong><i>uni-app x,终极跨平台方案 </i><u>uni-app x,终极跨平台方案 </u><del>uni-appx,终极跨平台方案</del></p><h3>uniCloud,js serverless云服务</h3><p style="text-decoration: line-through;"><small>uniCloud,js serverless云服务 </small><big>uniCloud,jsserverless云服务</big><strong>uniCloud,js serverless云服务 </strong><i>uniCloud,js serverless云服务 </i><u>uniCloud,jsserverless云服务</u><del>uniCloud,js serverless云服务</del></p><h4>uts,大一统语言</h4><p style="text-align: center;"><small>uts,大一统语言 </small><big>uts,大一统语言 </big><strong>uts,大一统语言</strong><i>uts,大一统语言</i><u>uts,大一统语言 </u><del>uts,大一统语言</del></p><h5>uniMPSdk,让你的App具备小程序能力</h5><h6>uni-admin,开源、现成的全端管理后台</h6><ul><li style="color: red; text-align: left;">uni-app x,终极跨平台方案</li><li style="color: green; text-align: center;">uni-app x,终极跨平台方案</li><li style="color: blue; text-align: right;">uni-app x,终极跨平台方案</li></ul><a href="https://uniapp.dcloud.net.cn">uni-app</a><br/><img src="/unidoc/zh/uni@2x.png"></img></p>',
baseURL: 'https://qiniu-web-assets.dcloud.net.cn'
});
},
// #endif
message(event : UniWebViewMessageEvent) {
console.log(JSON.stringify(event.detail));
},
error(event : UniWebViewErrorEvent) {
this.loadError = true
console.log(JSON.stringify(event.detail));
if (this.autoTest) {
this.eventError = {
"tagName": event.target?.tagName,
"type": event.type,
"errCode": event.detail.errCode,
"errMsg": event.detail.errMsg,
"url": event.detail.url,
"fullUrl": event.detail.fullUrl,
"src": event.detail.src
};
}
},
loading(event : UniWebViewLoadingEvent) {
this.loadingCount ++
console.log(JSON.stringify(event.detail));
if (this.autoTest) {
this.eventLoading = {
"tagName": event.target?.tagName,
"type": event.type,
"src": event.detail.src
};
}
},
load(event : UniWebViewLoadEvent) {
console.log(JSON.stringify(event.detail));
// #ifdef APP
this.canGoBack = canWebViewGoBack('web-view');
this.canGoForward = canWebViewGoForward('web-view');
// #endif
if (this.autoTest) {
this.eventLoad = {
"tagName": event.target?.tagName,
"type": event.type,
"src": event.detail.src,
"url": event.detail.url,
};
}
},
download(event : UniWebViewDownloadEvent) {
console.log(JSON.stringify(event.detail));
uni.showModal({
content: "下载链接: " + event.detail.url + "\n文件大小: " + event.detail.contentLength / 1024 + "KB",
showCancel: false
});
},
contentheightchange(event : UniWebViewContentHeightChangeEvent) {
console.log(JSON.stringify(event.detail));
this.eventContentHeightChange = {
"tagName": event.target?.tagName,
"type": event.type,
"isValidHeight": event.detail.height > 0
};
},
confirm(event : UniInputConfirmEvent) {
let url = event.detail.value;
if (!url.startsWith('https://') && !url.startsWith('http://')) {
url = 'https://' + url;
}
this.src = url;
},
changeHorizontalScrollBarAccess(event : UniSwitchChangeEvent) {
this.horizontalScrollBarAccess = event.detail.value;
},
changeVerticalScrollBarAccess(event : UniSwitchChangeEvent) {
this.verticalScrollBarAccess = event.detail.value;
},
changeBounces(event : UniSwitchChangeEvent) {
this.bounces = event.detail.value;
},
changeDisableUserSelectMenu(event : UniSwitchChangeEvent) {
this.disableUserSelectMenu = event.detail.value;
},
// 自动化测试
touchstart(event : UniTouchEvent) {
if (this.autoTest) {
this.isTouchEnable = event.touches[0].clientX > 0 && event.touches[0].clientY > 0;
}
},
tap(event : UniPointerEvent) {
if (this.autoTest) {
this.isTouchEnable = event.clientX > 0 && event.clientY > 0;
}
},
//自动化测试专用
checkNativeWebView() : boolean {
// #ifdef APP
return hasNativeView('web-view')
// #endif
// #ifdef WEB
return true
// #endif
},
checkLoadingCount() {
this.loadingCount = 0
webviewElement?.reload();
}
}
}
</script>
<style>
.margin-left-5 {
margin-left: 5px;
}
.align-items-center {
align-items: center;
}
.safe-area-inset-bottom {
height: var(--uni-safe-area-inset-bottom);
}
</style>