12

我将我的 IE 从版本 10 升级到 11,发现我的 ActiveX 自定义事件无法工作。

原因是 IE11 不支持attachEvent了,看来只能用addEventListener. 例如以前我用过

obj.attachEvent("onSelected", method1); 

现在,它是

obj.addEventListener("onSelected",method1,false); 

改代码后,method1无法触发。我不知道如何将在 ActiveX 插件中实现的自定义事件绑定到 JS 方法并使其在 IE11 上运行?

4

4 回答 4

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 版本,您必须捕获此异常,然后使用其他方法。

于 2013-11-13T13:45:01.860 回答
2

修改 @Gerrit 代码以适用于匿名函数,它还简单地将 attachEvent 功能添加回 IE 11(以及用于非 ie 浏览器的 polyfill,尽管未经测试),因此可以使用相同的代码。我很高兴找到这个页面。我担心我必须在 VBScript 中执行此操作或模拟旧版本的 IE。

回到 IE5,行为似乎一直相同。

填充物

如果(!window.attachEvent){
  window.attachEvent = Element.prototype.attachEvent = function (ename, efunction) {
    if (typeof efunction !== 'function') {
      throw new TypeError('Element.prototype.attachEvent - 试图附加的东西是不可调用的');
    }

    // 我们必须在某处追加
    var _body = document.getElementsByTagName('body')[0];

    // 获取 IE 版本
    var msie =(函数(){
        if (typeof document === "undefined") 返回 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 === 真?10 : (!(window.ActiveXObject) && "ActiveXObject" in window) === true ? 11:_检测;

        返回_版本;

    }());

    // 修复 ActiveX 不工作
    如果(msie == 11){
      var _params = efunction.toString().match(/(\(.*\))\ *{/)[1];
      var _funcName = efunction.toString().match(/^function\s?([^\s(]*)/)[1];
      var _fixAnon = 假;

      // 允许匿名函数
      如果(_funcName ==“”){
        _fixAnon = true;
        console.warn('未找到函数名。自动生成');
        _funcName = "autogenFunction" + Math.floor(Math.random()*9999).toString()
        var _handleFunctionality = "{ var privateFunc = " + efunction.toString() + "; privateFunc.apply(" + _funcName + ", arguments); }";
      }

      // for|event 只能使用一个脚本。确保没有一个
      var _query = 'script[for=' + this.id + '][event=' + ename + ']';
      var _handle = document.querySelectorAll(_query);
      var _handleFunc = _funcName + _params + ';';

      如果(_fixAnon){
        var _newFuncName = _funcName + _params;
        var _newFunction = "函数 " + _newFuncName + " " + _handleFunctionality;
        var _newHandle = document.createElement('script');
        _newHandle.type = "文本/javascript";
        _newHandle.appendChild(document.createTextNode(_newFunction));
        _body.appendChild(_newHandle);
      }

      // 如果脚本 for|event 存在,重用它
      如果 (_handle.length != 0) {
        _handleFunc += _handle[0].textContent;
        _body.removeChild(_handle[0]);
        删除_handle[0];
      }
      _handle = document.createElement('script');
      _handle.setAttribute("for", this.id);
      _handle.event = 名称;
      var _handleText = document.createTextNode(_handleFunc);
      _handle.appendChild(document.createTextNode(_handleFunc));
      _body.appendChild(_handle);
    }
    var _event = ename.substr(0,2) == "on" ? ename.substr(2) : ename;

    // 非 ie 浏览器的 Polyfill
    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>
于 2014-10-17T16:40:43.807 回答
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);
于 2013-11-26T10:21:56.980 回答
-6

ActiveX 已从 IE10 的浏览器中删除。在 HTML5 世界中,该技术已经过时并且越来越没有必要。

你没有提到插件在做什么?现在可以用标准代码代替吗?

于 2013-07-29T11:14:15.840 回答