2011-04-28 8 views
10

Soy completamente nuevo en el desarrollo de extensiones de IE con objetos de ayuda del navegador.¿Cómo puedo ejecutar una etiqueta <script> que acabo de insertar dinámicamente desde un BHO

Logré crear un BHO que inserte con éxito una etiqueta de script que haga referencia a un archivo javascript en el encabezado de la página HTML (consulte el código a continuación).

Pero la etiqueta de secuencia de comandos simplemente se sienta allí en el DOM y el archivo externo de JavaScript es no ejecutado.

¿Hay alguna manera de decirle al navegador que ejecute el archivo javascript externo?

Gracias!

Código Detalles: llamo el siguiente método en el caso 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); 
       } 
      } 
     } 
    } 
} 

}

Respuesta

12

Debe utilizar execScript en lugar de appendChild. Y la sintaxis de lo que necesita para ejecutar es muy, muy extraño. Pero logra lo que desea, es decir, se agrega un JavaScript externo al DOM. Llamar a esto durante 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); 

Esto añadirá <script type="text/javascript" id="bho_js" src="http://domain.com/script.js"></script> en la cabeza del DOM.

+0

Gracias Portman! Su código es mucho más elegante y compacto;) Lo he probado y de hecho inserta la secuencia de comandos en el DOM Head. Sin embargo, todavía tengo el mismo problema: su código realmente no ejecuta el javascript externo [http://domain.com/script.js](http://domain.com/script.js) al que hace referencia el script que se inserta. ¿Hay alguna manera de ejecutar este javascript externo? – Mike

+0

No estoy seguro de lo que quiere decir con "ejecutar". Si 'domain.com/script.js' contiene una sola línea,' alert ('foobar'); ', entonces en cada página debería ver una alerta. El JavaScript se "ejecutará" solo por estar en la página. – Portman

+0

Es posible que los errores de JavaScript, ya sea en el script * o en la página en sí *, impidan que se ejecute el script. Abra las herramientas de desarrollador de IE (F12) y mire la consola para ver los errores de JavaScript. – Portman

Cuestiones relacionadas