解决webkit浏览器中js方法中使用window.event提示未定义的问题

本文详细探讨了浏览器兼容性问题,特别是IE与WebKit内核浏览器中event对象的处理差异。通过示例说明了如何在不同浏览器环境下正确捕获和使用event对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这实际上是一个浏览器兼容性问题,根源百度中一大堆,简要说就是ie中event对象是全局变量,所以哪里都能使用到,但是webkit内核的浏览器中却不存在这个全局变量event,而是以一个隐式的局部变量的形式传入(后文会详说).

function myfunc(param){
    alert(window.event);
}    

//ie中
<input type="button" onclick="myfunc('testie')" >    //一切正常

//webkit浏览器,如chrome,firefox之类的
<input type="button" onclick="myfunc('testwebkit')" >   //会提示undefined

然后这里解释一下webkit内核的浏览器是如何隐式传入的event对象.

还是上面那个例子,在webkit浏览器中,onclick="myfunc('testwebkit')" 这句实际上相当于这样的:

onclick(event){
   myfunc('testwebkit');
}

换句话说onclick方法的0号参数实际上就是那个隐式传进来的event对象.

然后我们再来看一下js方法中的一种调用:arguments.callee.caller,其中arguments为方法的参数集合,callee为当前参数所在的方法,caller就为调用此方法的方法(或者说调用者).

然后就有如下的对应关系:

function myfunc(param){
    alert(arguments.callee);   //myfunc()
    alert(arguments.callee.caller);  //onclick()
    alert(arguments.callee.caller.arguments[0]);  //event
}    

//webkit浏览器,如chrome,firefox之类的
<input type="button" onclick="myfunc('testwebkit')" >   

这里特别说一句,arguments.callee.caller是可以继续往上追寻调用者的,比如arguments.callee.caller.arguments.callee.caller就是又向上追寻了一级.为何会特别说这个,因为有些时候会遇到自定义标签之类的情况,这种情况中如果有封装和js相关的方法,可能会存在如下这种情况:

onclick(event){
  tagCommand(){     //某些情况下的多层嵌套
      myfunc('testwebkit');
  }
}

此时如果还想在myfunc方法中获取到event对象,就需要连往上追寻2级,使用arguments.callee.caller.arguments.callee.caller.arguments[0]来获取了..

 

转载于:https://www.cnblogs.com/chyu/p/5061676.html

//notation: js file can only use this kind of comments //since comments will cause error when use in webview.loadurl, //comments will be remove by java use regexp (function() { if (window.WebViewJavascriptBridge && window.WebViewJavascriptBridge.inited) { return; } var receiveMessageQueue = []; var messageHandlers = {}; var sendMessageQueue = []; var responseCallbacks = {}; var persistentCallbacks = {}; var uniqueId = 1; var lastCallTime = 0; var stoId = null; var FETCH_QUEUE_INTERVAL = 20; var messagingIframe; var CUSTOM_PROTOCOL_SCHEME = "yy"; var QUEUE_HAS_MESSAGE = "__QUEUE_MESSAGE__"; // 创建消息index队列iframe function _createQueueReadyIframe() { messagingIframe = document.createElement('iframe'); messagingIframe.style.display = 'none'; messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE; document.documentElement.appendChild(messagingIframe); } //创建消息体队列iframe function _createQueueReadyIframe4biz() { bizMessagingIframe = document.createElement('iframe'); bizMessagingIframe.style.display = 'none'; document.documentElement.appendChild(bizMessagingIframe); } //set default messageHandler 初始化默认的消息线程 function init(messageHandler) { console.log(222222222222222); if (WebViewJavascriptBridge._messageHandler) { throw new Error('WebViewJavascriptBridge.init called twice'); } _createQueueReadyIframe(); _createQueueReadyIframe4biz(); WebViewJavascriptBridge._messageHandler = messageHandler; var receivedMessages = receiveMessageQueue; receiveMessageQueue = null; for (var i = 0; i < receivedMessages.length; i++) { _dispatchMessageFromNative(receivedMessages[i]); } WebViewJavascriptBridge.inited = true; } // 发送 function send(data, responseCallback) { _doSend('send', data, responseCallback); } // 注册线程 往数组里面添加值 function registerHandler(handlerName, handler) { messageHandlers[handlerName] = handler; } function removeHandler(handlerName, handler) { delete messageHandlers[handlerName]; } // Register a persistent callback that won't be deleted after first use function registerPersistentCallback(callbackId, callback) { persistentCallbacks[callbackId] = callback; responseCallbacks[callbackId] = callback; } // Remove a persistent callback function removePersistentCallback(callbackId) { delete persistentCallbacks[callbackId]; delete responseCallbacks[callbackId]; } // 调用线程 function callHandler(handlerName, data, responseCallback, persistent) { // 如果方法不需要参数,只有回调函数,简化JS中的调用 console.log(11111111111); if (arguments.length == 2 && typeof data == 'function') { responseCallback = data; data = null; } _doSend(handlerName, data, responseCallback, persistent); } // Call handler with persistent callback that can be reused function callHandlerPersistent(handlerName, data, responseCallback) { if (arguments.length == 2 && typeof data == 'function') { responseCallback = data; data = null; } _doSend(handlerName, data, responseCallback, true); } //sendMessage add message, 触发native处理 sendMessage function _doSend(handlerName, message, responseCallback, persistent) { var callbackId; console.log(1); if(typeof responseCallback === 'string'){ console.log(2); callbackId = responseCallback; } else if (responseCallback) { console.log(3); callbackId = 'cb_' + (uniqueId++) + '_' + new Date().getTime(); responseCallbacks[callbackId] = responseCallback; if (persistent) { persistentCallbacks[callbackId] = responseCallback; } message.callbackId = callbackId; }else{ console.log(4); callbackId = ''; } try { console.log(5); var fn = eval('WebViewJavascriptBridge.' + handlerName); } catch(e) { console.log(e); } if (typeof fn === 'function'){ console.log(6); var responseData = fn.call(WebViewJavascriptBridge, JSON.stringify(message), callbackId); if(responseData){ console.log(7); responseCallback = responseCallbacks[callbackId]; if (!responseCallback) { console.log(8); return; } responseCallback(responseData); // Only delete if it's not a persistent callback if (!persistentCallbacks[callbackId]) { console.log(9); delete responseCallbacks[callbackId]; } } } sendMessageQueue.push(message); messagingIframe.src = CUSTOM_PROTOCOL_SCHEME + '://' + QUEUE_HAS_MESSAGE; } // 提供给native调用,该函数作用:获取sendMessageQueue返回给native,由于android不能直接获取返回的内容,所以使用url shouldOverrideUrlLoading 的方式返回内容 function _fetchQueue() { // 空数组直接返回 if (sendMessageQueue.length === 0) { return; } // _fetchQueue 的调用间隔过短,延迟调用 if (new Date().getTime() - lastCallTime < FETCH_QUEUE_INTERVAL) { if (!stoId) { stoId = setTimeout(_fetchQueue, FETCH_QUEUE_INTERVAL); } return; } lastCallTime = new Date().getTime(); stoId = null; var messageQueueString = JSON.stringify(sendMessageQueue); sendMessageQueue = []; //android can't read directly the return data, so we can reload iframe src to communicate with java bizMessagingIframe.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); // Only delete if it's not a persistent callback if (!persistentCallbacks[message.responseId]) { delete responseCallbacks[message.responseId]; } } else { //直接发送 if (message.callbackId) { var callbackResponseId = message.callbackId; responseCallback = function(responseData) { _doSend('response', responseData, callbackResponseId); }; } 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.push(messageJSON); } _dispatchMessageFromNative(messageJSON); } WebViewJavascriptBridge.init = init; WebViewJavascriptBridge.doSend = send; WebViewJavascriptBridge.registerHandler = registerHandler; WebViewJavascriptBridge.removeHandler = removeHandler; WebViewJavascriptBridge.callHandler = callHandler; WebViewJavascriptBridge.callHandlerPersistent = callHandlerPersistent; WebViewJavascriptBridge.registerPersistentCallback = registerPersistentCallback; WebViewJavascriptBridge.removePersistentCallback = removePersistentCallback; WebViewJavascriptBridge._handleMessageFromNative = _handleMessageFromNative; WebViewJavascriptBridge._fetchQueue = _fetchQueue; var readyEvent = document.createEvent('Events'); var jobs = window.WVJBCallbacks || []; readyEvent.initEvent('WebViewJavascriptBridgeReady'); readyEvent.bridge = WebViewJavascriptBridge; window.WVJBCallbacks = []; jobs.forEach(function (job) { job(WebViewJavascriptBridge) }); document.dispatchEvent(readyEvent); })(); public static void webViewLoadLocalJs(WebView view, String path){ String jsContent = assetFile2Str(view.getContext(), path); view.loadUrl("javascript:" + jsContent); } public static String assetFile2Str(Context c, String urlStr){ InputStream in = null; try{ in = c.getAssets().open(urlStr); BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in)); String line = null; StringBuilder sb = new StringBuilder(); do { line = bufferedReader.readLine(); if (line != null && !line.matches("^\\s*\\/\\/.*")) { sb.append(line); } } while (line != null); bufferedReader.close(); in.close(); return sb.toString(); } catch (Exception e) { e.printStackTrace(); } finally { if(in != null) { try { in.close(); } catch (IOException e) { } } } return null; }注入.js文件报 Uncaught ReferenceError: WebViewJavascriptBridge is not defined -- From line 1 of 发现错误: Uncaught ReferenceError: WebViewJavascriptBridge is not defined https://pv-mall.wuyang-honda.com/h5/#/ 1 6553 ReferenceError: WebViewJavascriptBridge is not defined -- From line 79 of https://pv-mall.wuyang-honda.com/h5/assets/index-EaCfmwlF.js Uncaught ReferenceError: WebViewJavascriptBridge is not defined -- From line 1 of https://pv-mall.wuyang-honda.com/h5/#/ [system] Location: https://pv-mall.wuyang-honda.com/h5/#/ -- From line 10 of https://pv-mall.wuyang-honda.com/h5/assets/vconsole.min-QVp8m_0m.js [system] Client: Android 12 -- From line 10 of https://pv-mall.wuyang-honda.com/h5/assets/vconsole.min-QVp8m_0m.js [system] UA: Mozilla/5.0 (Linux; Android 12; ALN-AL00 Build/HUAWEIALN-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/114.0.5735.196 Mobile Safari/537.36 Honda_ANDROIDAPP -- From line 10 of https://pv-mall.wuyang-honda.com/h5/assets/vconsole.min-QVp8m_0m.js
最新发布
07-04
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值