Как я могу запустить тег <script>, который я только что динамически вставил из BHO
Я совершенно новичок в разработке расширений IE с помощью Browser Helper Objects.
Мне удалось создать BHO, который успешно вставляет тег сценария, который ссылается на файл javascript в заголовке HTML-страницы (см. Код ниже).
Но тег сценария просто сидит в 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);
}
}
}
}
}
}
1 ответ
Вы должны использовать 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>
в ГОЛОВУ ДОМА.