html5 view的层级,cocos creator - WebView内部页面的交互和层级问题

我们知道creator里的WebView,VideoPlayer等特殊组件有一个非常严重的问题,就是不管你怎么设置层级,这类组件始终处于最上层!其他UI组件会被遮挡。

我们打开浏览器运行,F12检测元素就可以清楚的看到他们的层级关系。

如下图:

通过上图我们可以清楚的看到,video(videoPlayer组件) 和 iframe(webView组件) 在 canvas(GameCanvas) 上层,而我们creator内置UI组件都是在GameCanvas层渲染的,所以不管我们怎么改UI层级都无效。

其实除了上述的办法,还有一个解决方案,就是我们可以通过自己写一个简单的html页面来中转!

大致思路:

首先我们自己用nginx搭建一个简单的html页面,在通过webView组件加载我们自己的web页面,然后在我们自己的页面加载一些需要的video或者其他网页,一些需要显示在Video组件上层的组件我们就可以通过html标签来实现了(需要一点web知识),然后和creator JS交互就可以了。

如何与 WebView 内部页面进行交互呢?:

可以参考一下

官方文档

个人感觉官方文档讲得不够全面。

我的实现如下:

首先我们先来看下官方的:

我们可以看到,Web平台上会出现跨域的问题,所以我们需要分别对web平台和移动平台做处理,

web平台:

在Web上我们可以通过window.postMessage 实现跨域消息传递:

cocos 发送消息到 web:

cocos JS:

this.webView._sgNode._renderCmd._iframe.contentWindow.postMessage(data, "*");

//如果因为版本原因 _sgNode 被舍弃了,可以换成以下

this.webView._impl._iframe.contentWindow.postMessage(data, "*");

这里需要注意的是:我们必须等webView加载完成之后才能发送。

html JS:

//接收来自cocos的消息

window.addEventListener('message', function (e) {

var data = e.data;//参数

console.log("-----------message--------------", data)

});

web 发送消息到 cocos:

html JS:

//browser 浏览器下,向cocos发送消息

parent.postMessage("------------hello!-----cocos---------", "*")

cocos JS:

if (cc.sys.isBrowser) {

//这里是浏览器环境下, 接收web传过来的消息

window.addEventListener('message', function (e) {

console.log("----cocos---",e.data);

})

}

演示如下:

以上是运行在浏览器环境下的交互

移动平台:

移动平台下就和官网的区别不大了。

首先需要初始化:

//初始化

init() {

// 这里是与内部页面约定的关键字,请不要使用大写字符,会导致 location 无法正确识别。

var scheme = "testkey";

//这里是移动端, 接收web传过来的消息

function jsCallback(target, url) {

// 这里的返回值是内部页面的 URL 数值,需要自行解析自己需要的数据。

var str = url.replace(scheme + '://', ''); // str === 'a=1&b=2'

// webview target

console.log("jsCallback-------str-------", str);

window.closeWebView(target, url);

}

this.webView.setJavascriptInterfaceScheme(scheme);

this.webView.setOnJSCallback(jsCallback);

//web

window.closeWebView = this.closeWebView.bind(this);

},

cocos 发送消息到 web:

cocos JS:

let data = {

id:123456

}

data = JSON.stringify(data); //注意这里需要把参数序列化

//调用web页面 定义的全局函数

this.webView.evaluateJS("setBackgroundColor(" + data + ")");

web 发送消息到 cocos :

html JS:

function onClick() {

console.log("-------web--------onClick----->>cocos JS-------------", window.isNative)

//android or ios

document.location = 'testkey://a=1&b=2'

}

demo完整代码:

cocos JS:

if (cc.sys.isBrowser) {

//这里是浏览器环境下, 接收web传过来的消息

window.addEventListener('message', function (e) {

console.log("----cocos---",e.data);

window.closeWebView(e);

})

}

cc.Class({

extends: cc.Component,

properties: {

webView: cc.WebView,

debugText: cc.Label

},

start() {

this.setDebugText("start.....")

this.webView.url = "web ip 地址"; // 如: "http://127.0.0.1:8190/web/"

this.init();

},

init() {

// 这里是与内部页面约定的关键字,请不要使用大写字符,会导致 location 无法正确识别。

var scheme = "testkey";

//这里是移动端, 接收web传过来的消息

function jsCallback(target, url) {

// 这里的返回值是内部页面的 URL 数值,需要自行解析自己需要的数据。

var str = url.replace(scheme + '://', ''); // str === 'a=1&b=2'

// webview target

console.log("jsCallback-------str-------", str);

window.closeWebView(target, url);

}

this.webView.setJavascriptInterfaceScheme(scheme);

this.webView.setOnJSCallback(jsCallback);

//web

window.closeWebView = this.closeWebView.bind(this);

},

setDebugText(str) {

this.debugText.string = str

},

//绑定按钮

cocosToWeb() {

let data = {

width: this.webView.node.width,

height: this.webView.node.height,

isNative: cc.sys.isNative,

color:"#FF9800"

}

let text;

console.log("------cocos------data-----------", data)

//浏览器

if (cc.sys.isBrowser) {

console.log("-----cocos------Browser---------");

text = "-----cocos------Browser---------";

this.webView._sgNode._renderCmd._iframe.contentWindow.postMessage(data, "*");

//如果因为版本原因 _sgNode 被舍弃了,可以换成以下

//this.webView._impl._iframe.contentWindow.postMessage(data, "*");

}

//移动端

else if (cc.sys.isNative)

{

console.log("-----cocos------Native---------");

text = "-----cocos------Native---------";

data = JSON.stringify(data);

//setBackgroundColor 是 web 全局函数, data 参数

this.webView.evaluateJS("setBackgroundColor(" + data + ")");

}

this.webView.node.active = true;

this.setDebugText(text)

},

//关闭WebView

closeWebView(e, url) {

this.webView.node.active = false;

this.setDebugText("--------cocos-----close----webView-------" + url);

},

//事件

onWebFinishLoad: function (sender, event) {

if (event === cc.WebView.EventType.LOADED) {

this.setDebugText("----webView---loaded---finish!!----")

this.cocosToWeb()

} else if (event === cc.WebView.EventType.LOADING) {

this.setDebugText("----webView---loading----")

} else if (event === cc.WebView.EventType.ERROR) {

this.setDebugText("----webView---load---error----")

}

},

});

Html:

cocos web

body {

margin: 0;

padding: 0;

background: rgb(94, 94, 94);

}

div {

width: 100%;

height: 50px;

position: absolute;

margin: auto;

left: 0;

right: 0;

bottom: 0;

text-align: center;

font-size: 30px;

}

iframe{

width: 50%;

height: 80%;

position: absolute;

margin: auto;

left: 0;

right: 0;

top: 0;

text-align: center;

font-size: 30px;

}

button {

position: absolute;

width: 200px;

height: 30px;

background: red;

top: 2px;

right: 20%;

border: 0;

}

触发cocos 关闭webView

let iframeWeb = document.getElementById("iframeID");

// ---------------browser-------need--------

window.addEventListener('message', function (e) {

var data = e.data; //e.data 里面有自己所传的所有参数 可以根据参数做自己的判断

console.log("--------------this is web message--------------", data)

setBackgroundColor(data);

});

// ---------------browser---------------

function setBackgroundColor(data) {

console.log("-------web--------data-------" + data)

window.isNative = data.isNative;

document.getElementsByTagName("body")[0].style.background = data.color;

document.getElementById("text").innerHTML = "this is cocos send msg color :" + data.color;

document.getElementById("iframeID").innerHTML = "this is cocos send msg color :" + data.color;

// setIframeSize(data)

}

function setIframeSize(data){

if (data.isNative) { //----------mobile---------

let cocosIframe = window.parent.document.documentElement;

console.log("-----mobile--web-------size------" + cocosIframe.clientWidth + "---" + cocosIframe.clientHeight);

iframeWeb.style.width = cocosIframe.clientWidth + "px";

iframeWeb.style.height = cocosIframe.clientHeight + "px";

}else{//----------browser---------

console.log("----browser---web-------size------" + data.width + "---" + data.height);

iframeWeb.style.width = data.width + "px";

iframeWeb.style.height = data.height + "px";

}

}

function onClick(param) {

console.log("-------web--------onClick----->>cocos JS-------------", window.isNative)

if (window.isNative) {

//android or ios

document.location = 'testkey://a=1&b=2'

} else {

//browser 浏览器下,向cocos发送消息

parent.postMessage("------------hello!-----cocos---------", "*")

}

}

end!

你可能感兴趣的:(html5,view的层级)