使用ajax更新js函数定义,如何重新定义函数/ eval?

时间:2013-01-27 23:06:07

标签: javascript jquery twig

我有一个幻灯片Web应用程序,对于某些幻灯片,包括从服务器端与该幻灯片一起呈现的beforeSlideshowAction,javascript与该幻灯片的内容一起呈现,因为它是生成此内容的幻灯片模板的一部分。

但是,下面的javascript函数不会与我的内容一起更新。例如,如果我要加载幻灯片,那么在这两张幻灯片上切换位置(在幻灯片运行完整周期后,将通过ajax更新),如下所示,beforeSlideshowAction_slide1()将呈现为beforeSlideshowAction_slide2( ),但是在调用时,只会存在一个名为beforeSlideshowAction_slide1()的函数,我假设所有的javascript函数都是在页面初始加载时注册的。

我记得通过在包含更新函数的脚本块上调用eval来另一次解决类似的问题,对我的问题是否有一个不那么狡猾的解决方案?

{# comment: from here the document will be updated by Ajax #}
<div id="slideshowbody">

    {# comment: ordernumber is now 1 #}
    <div id="slide{{ ordernumber }}">

        //some content goes here

        <script>
        function beforeSlideshowAction_slide{{ ordernumber }}() {

            //assign appropriate value to videoContent for current slide
            videoContent[{{ ordernumber }}]='video={{ data0 }}&height={{ data1 }}&width={{ data2 }}&codec={{ data3 }}&fullscreen={{ data5 }}';

        }
        </script>

    </div>


    {# comment: ordernumber is now 2 #}
    <div id="slide{{ ordernumber }}">

        //some content goes here

        //slide 2 doesn't have a function for a "beforeSlideshowAction"

    </div>

</div>

不要担心我可能正在调用一个不存在的函数,我在try / catch块中执行它,我已经设置它以便为try / catch中的每个幻灯片调用beforeSlideshowFunction,在幻灯片模板中我只是在那里定义一个函数,如果我想要一个,如果不是我只是跳过它。

1 个答案:

答案 0 :(得分:0)

以下是我最终解决问题的方法

<script id="beforeSlideshowAction{{ ordernumber }}_script" type='text/javascript'>

//define the function for later use (page updates)
window.beforeSlideshowAction_slide{{ ordernumber }} = function() {  

    console.log('runnin beforeSlideshowAction for slide {{ ordernumber }}');

    //assign appropriate value to videoContent for current slide
    videoContent[{{ ordernumber }}]='video={{ data0 }}&height={{ data1 }}&width={{ data2 }}&codec={{ data3 }}&fullscreen={{ data5 }}';

}

//run
var x = window['beforeSlideshowAction_slide{{ ordernumber }}'];
x();

</script>

...以及稍后,当ajax更改了这个,而slide1函数可能改为slide3-function ...

            //replace the innerHTML of body with the new stuff
            document.getElementById('slideshow_body').innerHTML=newContent;


            //update the videoContents and run other beforeSlideshow-actions
            for (var i=1;i<(pauseTimes.length+1);i++)
            { 

                try {
                    console.log('slide '+i+' action...');

                    //set previous version of beforeSlideshowAction i to null
                    window['beforeSlideshowAction_slide'+i] = null;

                    //define it anew (will this run it too?)
                    ie_compatible_eval( document.getElementById('beforeSlideshowAction'+i+'_script').innerHTML )

                }
                catch(e) {
                    console.log('slide '+i+' none');
                    //do nothing since we will not have a function named that for every slide, error is expected
                }

            }