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에 따라 라이센스가 부여됩니다.