H5 웹 뷰 에서 소결 개발
당사 의 업무 측 에서 앱 을 개발 해 야 한다 고 요구 하 였 습 니 다.그러나 시간 제한 으로 인해 케이스 app 방식, 즉 네 이 티 브 app 에 웹 뷰 를 삽입 하여 전단 페이지 를 보 여 주 는 것 만 사용 할 수 있 습 니 다.본 고 는 주로 자 바스 크 립 트 와 원생 app 간 의 통신, 그리고 웹 뷰 를 내장 하여 개발 할 때 전단 면 에서 밟 을 수 있 는 구 덩이 를 기술 하고 자 한다.
기술 구조
전단: vue + vuex + vue - router + webpack 온 가족 통 개발 백 엔 드: Node (express 프레임 워 크) 간단 한 퍼 가기 인터페이스 에서 자바 - 진짜 백 엔 드 인터페이스 로.
js 와 원생 통신
jsBridge 기술 과 네 이 티 브 앱 통신 안 드 로 이 드 전송 문과 ios 전송 문 을 사용 합 니 다. 두 플랫폼 의 초기 화 방식 이 다 르 기 때문에 개발 과정 에서 각 플랫폼 에 대해 대응 하 는 작업 을 해 야 합 니 다.구체 적 인 방법
//android
function connectWebViewJavascriptBridge{
if (window.WebViewJavascriptBridge) {
//do your work here
} else {
document.addEventListener(
'WebViewJavascriptBridgeReady'
, function() {
//do your work here
},
false
);
}
}
//ios
setupWebViewJavascriptBridge(function(bridge) {
/* Initialize your app here */
bridge.registerHandler('JS Echo', function(data, responseCallback) {
console.log("JS Echo called with:", data)
responseCallback(data)
})
bridge.callHandler('ObjC Echo', {'key':'value'}, function responseCallback(responseData) {
console.log("JS received response:", responseData)
})
})
setupWebViewJavascriptBridge(function(bridge) {
/* Initialize your app here */
bridge.registerHandler('JS Echo', function(data, responseCallback) {
console.log("JS Echo called with:", data)
responseCallback(data) //
})
bridge.callHandler('ObjC Echo', {'key':'value'}, function responseCallback(responseData) {
console.log("JS received response:", responseData)
})
})
Tips:
//vue
mounted(){
window['handleServicePushMessage'] = (res) => {
vm.handleServicePushMessage(res)
};
bridge.registerHandler("servicePushMessage", function (data, responseCallback) {
handleServicePushMessage(data)
responseCallback(data) // App
})
}
// ios 12 ui
document.addEventListener('focusout', function (event) {
let curTarget = event.target || event.srcElement;
let isInput= ['input', 'textarea'];
//
let curTargetTagName= curTarget.tagName.toLowerCase();
if (isInput.includes(curTargetTagName)) {
//
// activeElement
setTimeout(function () {
let activeEle = document.activeElement;
let activeEleTagName= activeEle.tagName.toLowerCase();
if (!isInput.includes(activeEleTagName)) {
// console.log(document.activeElement.tagName);
// app webview
performMethod('scrollTotop', null);
}
}, 200);
}
}, true);
5. js 가 app 에 존재 하지 않 는 다 리 를 호출 할 때 이상 을 포착 할 수 없고 페이지 가 잘못 보고 되 지 않 습 니 다. 6. 네 비게 이 션 표시 줄 에 문 제 를 표시 합 니 다. 프로젝트 시간 이 촉박 하고 app 개발 자 들 이 개발 임 무 를 많이 수행 하지 않 기 때문에 경로 통 제 는 전단 에 두 고 처리 합 니 다.이때 네 비게 이 션 바 배터리 시간 표시 줄 의 적합 한 문제 가 있다.이 프로젝트 는 상단 에서 20PX 를 하향 조정 하여 처리 하고 배터리 시간 표시 줄 의 글꼴 색상 에 대한 제어 도 다 리 를 통 해 설정 합 니 다.또한 아이 폰 X 는 별도로 처리 하기에 적합 하 다.7. app 이 웹 페이지 를 불 러 올 때 js 가 원생 방법 다 리 를 즉시 호출 할 때 원생 방법 다리 가 등록 되 지 않 은 상황 이 발생 할 수 있 습 니 다.따라서 특수 한 상황 에 서 는 다리 조작 을 지연 시 켜 야 한다.
전체 코드
/* */
function (window) {
window.device = {};
var ua = navigator.userAgent;
var android = ua.match(/(Android);?[\s\/]+([\d.]+)?/);
var ipad = ua.match(/(iPad).*OS\s([\d_]+)/);
var ipod = ua.match(/(iPod)(.*OS\s([\d_]+))?/);
var iphone = !ipad && ua.match(/(iPhone\sOS)\s([\d_]+)/);
device.ios = device.android = device.iphone = device.ipad = device.androidChrome = false;
if (android) {
device.os = 'android';
device.osVersion = android[2];
device.android = true;
device.androidChrome = ua.toLowerCase().indexOf('chrome') >= 0
}
if (ipad || iphone || ipod) {
device.os = 'ios';
device.ios = true
}
}(window)
/* Android ,IOS , IOS */
(function () {
if (window.WebViewJavascriptBridge || device.ios) {
return false;
}
var messagingIframe;
var sendMessageQueue = [];
var receiveMessageQueue = [];
var messageHandlers = {};
var CUSTOM_PROTOCOL_SCHEME = 'yy';
var QUEUE_HAS_MESSAGE = '__QUEUE_MESSAGE__/';
var responseCallbacks = {};
var uniqueId = 1;
function _createQueueReadyIframe(doc) {
messagingIframe = doc.createElement('iframe');
messagingIframe.style.display = 'none';
doc.documentElement.appendChild(messagingIframe);
}
/*set default messageHandler*/
function init(messageHandler) {
if (WebViewJavascriptBridge._messageHandler) {
throw new Error('WebViewJavascriptBridge.init called twice');
}
WebViewJavascriptBridge._messageHandler = messageHandler;
var receivedMessages = receiveMessageQueue;
receiveMessageQueue = null;
for (var i = 0; i < receivedMessages.length; i++) {
_dispatchMessageFromNative(receivedMessages[i]);
}
}
function send(data, responseCallback) {
_doSend({data: data}, responseCallback);
}
function registerHandler(handlerName, handler) {
messageHandlers[handlerName] = handler;
}
function callHandler(handlerName, data, responseCallback) {
_doSend({handlerName: handlerName, data: data}, responseCallback);
}
/*sendMessage add message, native sendMessage*/
function _doSend(message, responseCallback) {
if (responseCallback) {
var callbackId = 'cb_' + (uniqueId++) + '_' + new Date().getTime();
responseCallbacks[callbackId] = responseCallback;
message.callbackId = callbackId;
}
sendMessageQueue.push(message);
messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE;
}
/* native , : sendMessageQueue native, android , url shouldOverrideUrlLoading */
function _fetchQueue() {
var messageQueueString = JSON.stringify(sendMessageQueue);
sendMessageQueue = [];
/*android can't read directly the return data, so we can reload iframe src to communicate with java*/
messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://return/_fetchQueue/' + encodeURIComponent(messageQueueString);
}
/* native ,*/
function _dispatchMessageFromNative(messageJSON) {
setTimeout(function () {
var message = JSON.parse(messageJSON);
var responseCallback;
/*java call finished, now need to call js callback function*/
if (message.responseId) {
responseCallback = responseCallbacks[message.responseId];
if (!responseCallback) {
return;
}
responseCallback(message.responseData);
delete responseCallbacks[message.responseId];
} else {/* */
if (message.callbackId) {
var callbackResponseId = message.callbackId;
responseCallback = function (responseData) {
_doSend({responseId: callbackResponseId, responseData: responseData});
};
}
var handler = WebViewJavascriptBridge._messageHandler;
if (message.handlerName) {
handler = messageHandlers[message.handlerName];
}
/* handler*/
try {
handler(message.data, responseCallback);
} catch (exception) {
if (typeof console != 'undefined') {
console.log("WebViewJavascriptBridge: WARNING: javascript handler threw.", message, exception);
}
}
}
});
}
/* native ,receiveMessageQueue null, */
function _handleMessageFromNative(messageJSON) {
if (receiveMessageQueue && receiveMessageQueue.length > 0) {
receiveMessageQueue.push(messageJSON);
} else {
_dispatchMessageFromNative(messageJSON);
}
}
var WebViewJavascriptBridge = window.WebViewJavascriptBridge = {
init: init,
send: send,
registerHandler: registerHandler,
callHandler: callHandler,
_fetchQueue: _fetchQueue,
_handleMessageFromNative: _handleMessageFromNative
};
var doc = document;
_createQueueReadyIframe(doc);
var readyEvent = doc.createEvent('Events');
readyEvent.initEvent('WebViewJavascriptBridgeReady');
readyEvent.bridge = WebViewJavascriptBridge;
doc.dispatchEvent(readyEvent);
})();
/*Android */
function connectWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
callback(WebViewJavascriptBridge)
} else {
document.addEventListener('WebViewJavascriptBridgeReady', function () {
callback(WebViewJavascriptBridge)
}, false);
}
}
/*IOS */
function setupWebViewJavascriptBridge(callback) {
if (window.WebViewJavascriptBridge) {
return callback(WebViewJavascriptBridge)
} else {
}
if (window.WVJBCallbacks) {
return window.WVJBCallbacks.push(callback)
}
window.WVJBCallbacks = [callback];
var WVJBIframe = document.createElement('iframe');
WVJBIframe.style.display = 'none';
WVJBIframe.src = 'wvjbscheme://__BRIDGE_LOADED__';
document.documentElement.appendChild(WVJBIframe);
setTimeout(function () {
document.documentElement.removeChild(WVJBIframe)
}, 0)
}
if(device.ios){
setupWebViewJavascriptBridge(function(bridge){
/* */
window.BRIDGE= brige;
})
}
if(device.android){
connectWebViewJavascriptBridge(function(bridge){
/* */
window.BRIDGE= brige;
})
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.