【问题标题】:Update script to new element injected into DOM将脚本更新为注入 DOM 的新元素
【发布时间】:2016-11-27 16:43:18
【问题描述】:

我有一个带有子列表的列表和一个

我使用 ajax 获取新数据,然后删除列表,并将新元素(具有新数据的相同列表)注入 DOM。

<script type="text/javascript">
    $('#selectSemestres').change(function(obj){        
        var anoSemestre = $(this).val();        
        $.ajax({
            type: 'GET',
            url: '{{ route('professor') }}',
            data: {anoSemestre: anoSemestre},
            success: function(data){
                var lista = $(data).find('#list-professores'); //Get only the new professor list and thier disciplines
                $('#list-professores').remove(); //Remove old list
                $('#professores').append(lista); //Append the new list where the old list was before.
                load_js();
                $('.prof-disciplinas').sortable({
                    connectWith: '.prof-disciplinas'});
            }
        });
    });
</script>  

问题是:当您向 dom 插入新元素时,您需要“重新加载”您的 javascript,以便它能够识别新元素。这就是我使用load_js() 方法所做的。

function load_js()
{
   var head= document.getElementsByTagName('head')[0];
   var script= document.createElement('script');
    script.type = 'text/javascript'; 
    script.src  = 'js/script.js';
   head.appendChild(script);
}

但是我在同一个 .php 文件中有另一个 &lt;script &gt; ... &lt;/script&gt; 我需要重新加载它,以便它可以与这个新列表一起使用:

我需要重新加载脚本并在新列表中使用 Drag&Drop

<script type="text/javascript">
    $(function(){
        var oldTeacherId;
        $('.prof-disciplinas').sortable({
            connectWith: '.prof-disciplinas',

            start: function (event, ui){
                oldTeacherId = ui.item.parent().prev().prev().attr('data-id');
            },
            stop: function (event, ui){

                $.ajax({
                    type: "POST",
                    url: '{{ URL::to("/professor") }}',
                    data: { 
                        disciplina: ui.item.attr('data-id'),
                        professor: ui.item.parent().prev().prev().attr('data-id'),
                        old: oldTeacherId 
                    },
                    success: function(data){
                        swal("Good job!", "You clicked the button!", "success"); 
                        //Atualizar tabela aqui
                        var evento = $('#calendario').fullCalendar('clientEvents', function(event){

                            return event.id == $(ui.item).attr('data-id');
                        });
                        evento[0].backgroundColor = '' + getCor( ui.item.parent().prev().prev().attr('data-id'));
                        $('#calendario').fullCalendar('updateEvent', evento[0]);
                    },
                    error: function(){

                    }

            });
        }
    });
    });
</script>  

这种拖放效果在 ajax 之后不起作用。
我怎样才能重新加载那段脚本?让它识别并使用新插入的列表?

【问题讨论】:

    标签: javascript jquery ajax dom


    【解决方案1】:

    在 JavaScript 中实现目标是完全错误的方式。

    让我们从第一个例子开始:

    $('#selectSemestres').change(function(obj){...})
    

    可以替换为:

    $('body').on('change', '#selectSemestres', function(obj){...})
    

    http://api.jquery.com/on/

    至于您的第二段代码,您可以将其提取到一个单独的函数中,并在每次需要重新加载数据时调用它:

    var oldTeacherId;
    function reloadTeachers() {
      $('.prof-disciplinas').sortable({
        connectWith: '.prof-disciplinas',
    
        start: function(event, ui) {
          oldTeacherId = ui.item.parent().prev().prev().attr('data-id');
        },
        stop: function(event, ui) {
    
          $.ajax({
            type: "POST",
            url: '{{ URL::to("/professor") }}',
            data: {
              disciplina: ui.item.attr('data-id'),
              professor: ui.item.parent().prev().prev().attr('data-id'),
              old: oldTeacherId
            },
            success: function(data) {
              swal("Good job!", "You clicked the button!", "success");
              //Atualizar tabela aqui
              var evento = $('#calendario').fullCalendar('clientEvents', function(event) {
    
                return event.id == $(ui.item).attr('data-id');
              });
              evento[0].backgroundColor = '' + getCor(ui.item.parent().prev().prev().attr('data-id'));
              $('#calendario').fullCalendar('updateEvent', evento[0]);
            },
            error: function() {
    
            }
    
          });
        }
      });
    }
    
    $(function() {
      reloadTeachers(oldTeacherId);
    });

    注意使用全局变量是不好的做法,oldTeacherId 应该封装在最终解决方案中。

    【讨论】:

    • 第二段代码是拖放效果。如果我给它一个function name(),它不会随着页面加载而自动加载。我怎样才能做到这一点?我需要使用 pageLoad 加载它,并在 ajax 发生时重新加载它。另外,我不明白为什么第一部分是错误的,请您解释一下吗?
    • 请再次检查我的示例。我不只是给匿名函数命名。我从中调用新函数。将函数传递给 $() 将在加载时执行它。然后,您可以在需要时调用 reloadTeachers。
    • 老兄,你摇滚!工作如此美丽!还有一件事,你能教我为什么我做$('#selectSemestre').change()的方式是错误的吗?
    • 当您处理通过脚本动态添加到页面的新鲜 DOM 时,您必须使用 事件委托 on()
    • @PlayHardGoPro 你这样做的方式意味着只有在页面加载时页面上的元素才会发生更改。由于您重新创建了元素,因此没有帮助。 “开”确保即使您稍后添加元素,事件仍然会发生在它们身上。
    猜你喜欢
    • 1970-01-01
    • 2023-03-02
    • 1970-01-01
    • 1970-01-01
    • 2012-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-24
    相关资源
    最近更新 更多