简体   繁体   English

动态加载的javascript第二次加载不起作用

[英]Dynamically loaded javascript doesn't work second time loaded

I am working on a webpage that uses a JQuery UI dialog (in modal mode) to display a form that is dynamically generated using Django. 我正在一个使用JQuery UI对话框(以模式模式)显示使用Django动态生成的表单的网页。 The basic flow is: 基本流程是:

  • the user clicks a button 用户单击一个按钮
  • jquery (using AJAX) issues a get request that returns the html for the form which is then used to fill the dialog jQuery(使用AJAX)发出get请求,该请求返回表单的html,然后将其用于填充对话框
    • The html contains a script tag that handles some UI on the form which loads fine and works as expected html包含一个script标记,用于处理表单上的某些UI,该UI可以正常加载并按预期工作
  • the user than fills out the form and clicks "Done" and the form is submitted. 然后,用户填写表单并单击“完成”,然后提交表单。

The issue comes in when the user makes an error on the form. 当用户在表单上出错时,就会出现此问题。 The server responds to the post request (that submits the form) with the original form (including the script) modified to show the errors. 服务器用修改后的原始表单(包括脚本)来响应发布请求(提交表单)以显示错误。 This second time the script is loaded it gets a " Uncaught ReferenceError: $ is not defined (anonymous function) " The script is exactly the same as before when it worked fine. 第二次加载脚本时,它会收到一个“ Uncaught ReferenceError:未定义$(匿名函数) ”脚本与以前完全一样,但可以正常工作。 To be clear throughout this entire process the page is never refreshed. 为了在整个过程中保持清晰,页面永远不会刷新。

Here is the gist of the javascript that takes care of the modal: 这是照顾模式的javascript的要旨:

var add_container = $("#add_container");

add_container.dialog({...})

function show_form(form,response_func) {
    add_container.html(form);
    add_container.dialog("open");
    $("#add_form").submit(function (event) {
        return submit_form($(this),response_func);
    });
}

function submit_form(form,response_func) {
    add_container.append('<p>Adding...</p>');
    //this is a trick to upload a file without reloading the page
    form.attr('target','upload_target');
    $('#upload_target').load(function() {
        var response = $('#upload_target').contents().find('body').html();
        add_container.dialog("close");

        resp_obj = $(response)
        if (resp_obj.is('form')) {
            //***this is what reloads the form when there is an error
            show_form(response,response_func);
        } else {
            response_func(resp_obj);
        }

    });
}

$('#add_link').click(add_link);
function add_link() {
    $.get('/add_link', function(data) {
        function add_response(response) {
            //handle successful submission
        }
        show_form(data,add_response);
    });
}

//...more stuff that is not important

This is the gist of the html returned from /add_link 这是从/ add_link返回的html的要点

<script type="text/javascript" src="/scripts/add_form.js" ></script>
<form id="add_form" enctype="multipart/form-data" action="/add_link/" method="post">
<!-- Dynamically generated form here !-->
</form>

The add_form.js is a pretty standard javascript file that uses jQuery. add_form.js是使用jQuery的非常标准的javascript文件。 Its starts with $(document).ready(function () {...} ) and the first $ is where the ReferenceError occurs 它以$(document).ready(function(){...})开头,第一个$是出现ReferenceError的位置

The form needs to be dynamically generated based on what is clicked so I can't just put everything statically on the page. 表单需要根据单击的内容动态生成,因此我不能仅将所有内容静态地放在页面上。 The script is not dynamically generated so it doesn't necessarily need to be dynamically loaded but I wasn't sure how to keep it in its own file, and also only have it run when the form is loaded. 该脚本不是动态生成的,因此不一定需要动态加载该脚本,但是我不确定如何将其保存在自己的文件中,并且还只能在加载表单时运行它。 I am open to suggestions of alternative ways to accomplish the same effect. 我乐于接受其他建议以达到相同效果的建议。

Your form action is pointing to a different relative path to the one containing the jQuery framework script, etc. 您的表单动作指向包含jQuery框架脚本等的相对路径的不同相对路径。

<script type="text/javascript" src="/scripts/add_form.js" ></script>
<!-- src="/scripts" -->

<form id="add_form" enctype="multipart/form-data" action="/add_link/" method="post">
<!-- action="/add_link" -->

To make sure it's loading the framework after the form submission, just use something like the developer tools on your browser and check the head tag for the jQuery script src. 要确保在表单提交后加载框架,只需在浏览器上使用类似开发人员工具的工具,然后检查jQuery脚本src的head标签即可。 Is it still there? 还在吗?

Thanks to MelanciaUK I realized that when I submitted my form to the iFrame the response was getting sent first to there where the script would run and error because the iFrame is treated as its own page and doesn't have access to jQuery loaded on the main page. 多亏了MelanciaUK,我意识到当我将表单提交给iFrame时,响应首先发送到了那里,脚本在那里运行并且出错,因为iFrame被视为自己的页面,并且无法访问主页面上加载的jQuery。页。

I decided to solve the problem by eliminating the dynamic loading of the add_form script and simply load it when the page loads just like all my other scripts. 我决定通过消除add_form脚本的动态加载来解决该问题,并像其他所有脚本一样在页面加载时简单地加载它。 I created a custom jQuery event (using .trigger ) in order to only have the script run when the add form is opened. 我创建了一个自定义jQuery事件(使用.trigger ),以便仅在打开添加表单时运行脚本。 This worked exactly the way I wanted it to. 完全按照我想要的方式工作。

Hope this helps anyone with a similar problem. 希望这对遇到类似问题的人有所帮助。 If you have any questions feel free to ask! 如果你有任何问题随时问!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM