2011-04-28 54 views
10

动态插入我完全没有使用浏览器帮助对象开发IE扩展。我怎样才能运行<script>标签,我刚从一个BHO

我设法创建了一个BHO,它成功地在HTML页面的头部插入了一个引用JavaScript文件的脚本标记(参见下面的代码)。

但脚本标签只是坐在那里的DOM和外部JavaScript文件是而不是执行。

有什么办法可以告诉浏览器运行外部javascript文件吗?

谢谢!

码详情: 我呼吁OnDocumentComplete事件下面的方法:

void CHelloWorldBHO::InsertScriptTag(IDispatch* pDispDoc) 
{ 
HRESULT hr = S_OK; 
// query for an HTML document. 
CComQIPtr<IHTMLDocument3> pDocument3 = pDispDoc; 
CComQIPtr<IHTMLDocument2> pDocument2 = pDispDoc; 
if (pDocument2 != NULL && pDocument3 != NULL) 
{ 
    // ********************** create our script tag Element (pHtmlElem) **************************** 
    IHTMLElement* pHtmlElem; 
    CComVariant vAlert="http://www.gnpcb.org/esv/share/js/?action=getDailyVerse"; // example referencing external JS code 
    CComVariant vJavascript="text/javascript"; 
    hr = pDocument2->createElement(_T("script"), &pHtmlElem); 
    if (SUCCEEDED(hr) && pHtmlElem != NULL) 
    { 
     hr = pHtmlElem->setAttribute(_T("type"), vJavascript); 
     hr = pHtmlElem->setAttribute(_T("src"), vAlert);    
    } 

    // ********************** insert Element (pHtmlElem) in HTML Head **************************** 
    // Get the head from the DOM. 
    static const CComBSTR sbstrHead(L"head"); 
    CComPtr<IHTMLElementCollection> objects; 
    hr = pDocument3->getElementsByTagName(sbstrHead, &objects); 
    if(SUCCEEDED(hr) && objects != NULL) 
    { 
     // Get the number of elements in the collection. 
     long nElements = 0; 
     hr = objects->get_length(&nElements); 
     if (hr == S_OK && nElements > 0) 
     { 
      CComVariant svarItemIndex(0); // we will get the first element 
      CComVariant svarEmpty; 
      CComPtr<IDispatch> spdispElement; 

      // Get the element out of the collection with index 0 (the first element, that is, the head) 
      hr = objects->item(svarItemIndex, svarEmpty, &spdispElement); 
      if (hr == S_OK && spdispElement != NULL) 
      { 
       CComQIPtr<IHTMLDOMNode, &IID_IHTMLDOMNode> spHeadNode = spdispElement; // query for DOM interfaces 
       CComQIPtr<IHTMLDOMNode, &IID_IHTMLDOMNode> spNodeNew; 
       spNodeNew = pHtmlElem; 

       if (spHeadNode) 
       { 
        spHeadNode->appendChild(spNodeNew, NULL); 
       } 
      } 
     } 
    } 
} 

}

回答

12

您应该使用execScript来提到appendChild。你需要执行的语法是非常非常非常奇怪。但它完成了你想要的 - 即将外部JavaScript添加到DOM。 OnDocumentComplete在调用此:

VARIANT vrt = {0}; 
CComQIPtr<IHTMLWindow2> win; 
spHTMLDoc->get_parentWindow(&win); 
CComBSTR bstrScript = L"var html_doc = document.getElementsByTagName('head')[0]; var _js = document.createElement('script'); _js.setAttribute('type', 'text/javascript'); _js.setAttribute('id', 'bho_js'); _js.setAttribute('src', 'http://domain.com/script.js'); if(!document.getElementById('bho_js')) html_doc.appendChild(_js);"; 
CComBSTR bstrLanguage = L"javascript"; 
HRESULT hrexec = win->execScript(bstrScript,bstrLanguage, &vrt); 

这将增加<script type="text/javascript" id="bho_js" src="http://domain.com/script.js"></script>到DOM HEAD。

+0

谢谢波特曼! 您的代码更加优雅和紧凑;) 我测试了它,它的确在DOM头中插入了脚本。 但是,我仍然有同样的问题:你的代码实际上并没有运行脚本引用的外部javascript [http://domain.com/script.js](http://domain.com/script.js)它插入。 有没有办法执行这个外部的JavaScript? – Mike 2011-05-04 08:39:14

+0

不确定“run”是什么意思。如果'domain.com/script.js'包含一行,'alert('foobar');',那么在每一页上你都应该看到一个警报。只需在页面上JavaScript就会“运行”。 – Portman 2011-05-04 14:25:08

+0

您的脚本*或页面本身*上的JavaScript错误可能会阻止脚本运行。打开IE开发人员工具(F12)并查看控制台以查看任何JavaScript错误。 – Portman 2011-05-04 14:27:20