【问题标题】:ActiveX custom event cannot work on IE11ActiveX 自定义事件无法在 IE11 上运行
【发布时间】:2014-10-18 00:40:43
【问题描述】:

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

原因是IE11不再支持attachEvent,看来我必须使用addEventListener。比如我之前用过的

obj.attachEvent("onSelected", method1); 

现在是

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

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

【问题讨论】:

  • 我似乎记得当它从 IE10 中删除时,它在兼容模式下保持可用。我不确定 IE11 是否相同。你想在什么模式下运行你的页面?你试过兼容模式吗?
  • 我认为您的意思是从“onSelected”中删除“on”,但我仍然无法在 IE11 中获取我的 ActiveX 事件。

标签: internet-explorer activex internet-explorer-11


【解决方案1】:

到目前为止,我发现 IE 11 的唯一方法是使用 for...event 脚本块:

<script for="myActiveX" event="onSelected(param1, param2)">
  method1(param1, param2);
</script>
<object id="myActiveX" ...></object>

这两个元素也可以使用 JavaScript 动态创建。您只需确保使用setAttribute 方法设置for 属性:

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 和更早版本)不喜欢上面的代码。对于这些较旧的浏览器,您必须使用 createElement 方法传递 codebase 参数和 for 参数:

var handler = document.createElement('<script for="myActiveX">');
...
var activeX = document.createElement('<object classid="CLSID:123456789-1234-1234-1234-123456789012">');

较新的浏览器在遇到此代码时会抛出异常,因此要支持所有 IE 版本,您必须捕获此异常,然后使用其他方法。

【讨论】:

    【解决方案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 = '', 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>
    

    【讨论】:

      【解决方案3】:

      根据 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);
      

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 在 IE 浏览器的“METRO”模式下(而不是在桌面模式下)阻止使用 ActiveX 控件(Flash 除外)。
        猜你喜欢
        • 1970-01-01
        • 2016-04-24
        • 2021-04-22
        • 1970-01-01
        • 2019-12-13
        • 1970-01-01
        • 1970-01-01
        • 2015-07-21
        • 1970-01-01
        相关资源
        最近更新 更多