How can I run a <script> tag that I just inserted dynamically from a BHO

时光怂恿深爱的人放手 提交于 2019-12-03 09:38:37

问题


I'm completely new to developing IE extensions with Browser Helper Objects.

I managed to create a BHO that successfully inserts a script tag that references a javascript file in the head of the HTML page (see code below).

But the script tag just sits there in the DOM and the external javascript file is not executed.

Is there any way to tell the browser to run the external javascript file?

Thanks!

Code Details: I call the following method on the OnDocumentComplete event:

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); 
                }
            }
        }
    }
}

}


回答1:


You should use execScript instead of appendChild. And the syntax of what you need to exec is very, very wierd. But it accomplishes what you want -- namely, an external JavaScript is added to the DOM. Call this during 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);

This will add <script type="text/javascript" id="bho_js" src="http://domain.com/script.js"></script> into the DOM HEAD.



来源:https://stackoverflow.com/questions/5817003/how-can-i-run-a-script-tag-that-i-just-inserted-dynamically-from-a-bho

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!