我将IE从版本10升级到11,发现我的ActiveX自定义事件无法正常工作。
原因是IE11不再支持attachEvent
,似乎我必须使用addEventListener
。例如,之前我使用过
obj.attachEvent("onSelected", method1);
现在,它是
obj.addEventListener("onSelected",method1,false);
更改代码后,无法触发方法1。我不知道如何将自定义事件(在ActiveX插件中实现)绑定到JS方法并使其在IE11上运行?
答案 0 :(得分:13)
我目前为IE 11找到的唯一方法是使用for...event
脚本块:
<script for="myActiveX" event="onSelected(param1, param2)">
method1(param1, param2);
</script>
<object id="myActiveX" ...></object>
这两个元素也可以使用JavaScript动态创建。您只需确保使用for
方法设置setAttribute
属性:
var handler = document.createElement("script");
handler.setAttribute("for", "myActiveX");
handler.event = "onSelected(param1, param2)";
handler.appendChild(document.createTextNode("method1(param1, param2);"));
document.body.appendChild(handler);
var activeX = document.createElement("object");
activeX.id = "myActiveX";
activeX.codebase = "foobar.cab";
activeX.classid = "CLSID:123456789-1234-1234-1234-123456789012";
document.body.appendChild(activeX);
较早的IE版本(IE 8及更早版本)不喜欢上述代码。对于这些旧版浏览器,您必须使用codebase
方法传递for
参数和createElement
参数:
var handler = document.createElement('<script for="myActiveX">');
...
var activeX = document.createElement('<object classid="CLSID:123456789-1234-1234-1234-123456789012">');
较新的浏览器在遇到此代码时会抛出异常,因此为了支持所有IE版本,您必须捕获此异常,然后使用其他方法。
答案 1 :(得分:2)
修改@Gerrit代码以适用于匿名函数,它也只是将attachEvent功能添加回IE 11(对于非ie浏览器的polyfill,虽然未经过测试),因此可以使用相同的代码。我很高兴找到了这个页面。我担心我必须在VBScript中执行此操作或模拟旧版本的IE。
行为似乎与IE5一直相同。
填充工具
if (!window.attachEvent) { window.attachEvent = Element.prototype.attachEvent = function (ename, efunction) { if (typeof efunction !== 'function') { throw new TypeError('Element.prototype.attachEvent - what is trying to be attached is not callable'); } // We got to append somewhere var _body = document.getElementsByTagName('body')[0]; // Get IE Version var msie = (function() { if (typeof document === "undefined") return false; var v = 3, div = document.createElement('div'), a = div.all || []; while (div.innerHTML = '<!--[if gt IE '+(++v)+']><br><![endif]-->', a[0]); var _detection = v > 4 ? v : /*@cc_on!@*/false; var _version = _detection === true ? 10 : (!(window.ActiveXObject) && "ActiveXObject" in window) === true ? 11 : _detection; return _version; }()); // Fix ActiveX not working if (msie == 11) { var _params = efunction.toString().match(/(\(.*\))\ *{/)[1]; var _funcName = efunction.toString().match(/^function\s?([^\s(]*)/)[1]; var _fixAnon = false; // Allow for anonymous functions if (_funcName == "") { _fixAnon = true; console.warn('Function name not found. Autogenerating'); _funcName = "autogenFunction" + Math.floor(Math.random()*9999).toString() var _handleFunctionality = "{ var privateFunc = " + efunction.toString() + "; privateFunc.apply(" + _funcName + ", arguments); }"; } // Only one script for|event can be used. Make sure there isn't one already var _query = 'script[for=' + this.id + '][event=' + ename + ']'; var _handle = document.querySelectorAll(_query); var _handleFunc = _funcName + _params + ';'; if (_fixAnon) { var _newFuncName = _funcName + _params; var _newFunction = "function " + _newFuncName + " " + _handleFunctionality; var _newHandle = document.createElement('script'); _newHandle.type = "text/javascript"; _newHandle.appendChild(document.createTextNode(_newFunction)); _body.appendChild(_newHandle); } // If script for|event exists, reuse it if (_handle.length != 0) { _handleFunc += _handle[0].textContent; _body.removeChild(_handle[0]); delete _handle[0]; } _handle = document.createElement('script'); _handle.setAttribute("for", this.id); _handle.event = ename; var _handleText = document.createTextNode(_handleFunc); _handle.appendChild(document.createTextNode(_handleFunc)); _body.appendChild(_handle); } var _event = ename.substr(0,2) == "on" ? ename.substr(2) : ename; // Polyfill for non ie browsers if (window.addEventListener) this.addEventListener(_event, efunction, false); } }
使用我的ActiveX对象的示例
<script type="text/javascript">
function MyObject_ObjectEvent() {
console.log('I am watching traditionally');
}
var _elem = document.getElementById('MyObject');
_elem.attachEvent('ObjectEvent', function () { console.log('I am watching anonymously') });
_elem.attachEvent('ObjectEvent', MyObject_ObjectEvent);
</script>
答案 2 :(得分:1)
根据kayahr的回答,我创建了一个在IE 11中进行事件注册的函数。 非常感谢你!它对我有用!
这是我的代码(不能作为_functionCallback参数使用匿名函数):
function AttachIE11Event(obj, _strEventId, _functionCallback) {
var nameFromToStringRegex = /^function\s?([^\s(]*)/;
var paramsFromToStringRegex = /\(\)|\(.+\)/;
var params = _functionCallback.toString().match(paramsFromToStringRegex)[0];
var functionName = _functionCallback.name || _functionCallback.toString().match(nameFromToStringRegex)[1];
var handler;
try {
handler = document.createElement("script");
handler.setAttribute("for", obj.id);
}
catch(ex) {
handler = document.createElement('<script for="' + obj.id + '">');
}
handler.event = _strEventId + params;
handler.appendChild(document.createTextNode(functionName + params + ";"));
document.body.appendChild(handler);
};
您必须使用浏览器嗅探,您的代码必须看起来像
if(BrowserDetect.browser == "IE" && BrowserDetect.version >= 11)
AttachIE11Event(obj, "onSelected", method1);
else if(obj.attachEvent)
obj.attachEvent("onSelected", method1);
else if(obj.addEventListener)
obj.addEventListener("onSelected", method1);
答案 3 :(得分:-6)
ActiveX已从IE10中的浏览器中删除。在HTML5世界中,这项技术已经陈旧且越来越不必要了。
你没有提到插件正在做什么?它现在可以用标准代码替换吗?