OpenLaszlo <html> интеграция тегов / iframe и вызовы JavaScript
Я пытаюсь вызвать одну функцию JavaScript, присутствующую в HTML-данных, которые я вставляю, но я всегда получаю сообщение об ошибке getLoaded не является методом. Я приложил фрагмент кода. Что случилось?
<canvas width="100%" height="100%" >
<simplelayout axis="y" spacing="2"/>
<button>Set HTML
<handler name="onclick">
<![CDATA[
if (canvas.main) {
canvas.main.setAttribute('html', '<html><head><style type="text/css">body {background-color: #ffffff;}</style><script>function getLoaded(){ return document.images.length;}</script></head><body><img id="imageTag" ></img></body></html>');
}
]]>
</handler>
</button>
<button>test
<handler name="onclick">
<![CDATA[
if (canvas.main) {
var del = new LzDelegate(this,'handlerFunc');
canvas.main.callJavascript('getLoaded',del);
}
]]>
</handler>
</button>
<method name="handlerFunc" args="retVal">
console.log("handlerFunc", retVal);
</method>
<html name="main" x = "50" y="50" width="600" height="400" >
<handler name="oninit">
this.bringToFront();
</handler>
</html>
</canvas>
1 ответ
Вот решение, которое работает как для среды выполнения SWF10, так и для DHTML. Я тестировал с IE 9, Firefox и Chrome.
Есть две проблемы с вашим кодом:
1) Фрагмент HTML, который вы назначаете атрибуту @html тега , не должен содержать полную структуру документа HTML. Вот JavaScript из библиотеки iframemanager.js (часть OpenLaszlo), который используется для назначения фрагмента HTML-кода iFrame:
,setHTML: function(id, html) {
// must be called after the iframe loads, or it will be overwritten
if (html) {
var win = lz.embed.iframemanager.getFrameWindow(id);
if (win) {
win.document.body.innerHTML = html;
}
}
}
Как видите, значение параметра html присваивается innerHTML элемента body. Поэтому достаточно включить только тело HTML-документа, который вы генерируете.
2) Если вы хотите добавить разделы JavaScript в iFrame, вы не можете встроить их в HTML-код, который хотите назначить документу, но должны создать элемент "script", как вы можете видеть в полном примере ниже. Если вы также хотите поддерживать среду выполнения SWF, самый эффективный способ - создать небольшую внешнюю функцию JavaScript с функцией-помощником, как показано ниже.
Для этого решения я создаю два файла. Файл LZX и внешний файл JavaScript с именем iFrameHelperFunction.js
,
Вот измененная версия вашего файла LZX:
<canvas width="100%" height="100%" >
<wrapperheaders>
<script type="text/javascript" src="iFrameHelperFunction.js"></script>
</wrapperheaders>
<simplelayout axis="y" spacing="2"/>
<button>Set HTML
<handler name="onclick">
<![CDATA[
if (canvas.main) {
// Create the HTML content; do not include <html><head><body> structure here,
// since setting the 'html' attribute of an OpenLaszlo <html> tag will set
// the innerHTML property of the iFrame's document.body.
var innerHTML = '<style type="text/css">body {background-color: #ff0000;}</style>'
+ '<img id="imageTag" src="https://www.google.com/images/srpr/logo3w.png"></img>',
jsCode = "function getLoaded() { alert('inside getLoaded()'); return 'getLoaded was called'; }";
canvas.main.setAttribute('html', innerHTML);
lz.Browser.callJS('addJavaScriptToFrame("' + canvas.main.iframeid + '", ' + jsCode + ')');
}
]]>
</handler>
</button>
<button>test
<handler name="onclick">
<![CDATA[
if (canvas.main) {
var del = new LzDelegate(canvas, 'handlerFunc');
canvas.main.callJavascript('getLoaded', del);
}
]]>
</handler>
</button>
<method name="handlerFunc" args="retVal">
Debug.info("handlerFunc", retVal);
</method>
<html name="main" x = "50" y="50" width="600" height="200" >
<handler name="oninit">
this.bringToFront();
</handler>
</html>
</canvas>
Сначала я добавляю свой собственный файл JavaScript на страницу:
<wrapperheaders>
<script type="text/javascript" src="iFrameHelperFunction.js"></script>
</wrapperheaders>
Затем устанавливается HTML-код для iFrame, аналогичный вашему коду. Но любой JavaScript, который добавляется на HTML-страницу iFrame, должен быть добавлен с помощью вспомогательной функции. addJavaScriptToFrame
определяется в iFrameHelperFunction.js
:
function addJavaScriptToFrame(frameId, jsCode) {
var iframeWin = lz.embed.iframemanager.getFrameWindow(frameId);
doc = iframeWin.document;
// Scripts can not be inlined in HTML snippets, but must be created through JavaScript
var scriptEl = doc.createElement('script');
// The JavaScript function or code you want to add
scriptEl.text = jsCode;
// Append the script to the head of the iFrame document
doc.firstChild.appendChild(scriptEl);
}
Вызов для добавления JavaScript в iFrame в файле LZX:
lz.Browser.callJS('addJavaScriptToFrame("' + canvas.main.iframeid + '", ' + jsCode + ')');
Нажмите кнопку "Установить HTML", чтобы установить содержимое фрейма, а затем нажмите кнопку "Тест", чтобы вызвать функцию getLoaded() внутри iFrame.