在使用ajax加载DOM后找不到元素(想绑定jQuery插入到它) [英] Can't find element in DOM after loading it with ajax (want to bind jquery plug in to it)

查看:90
本文介绍了在使用ajax加载DOM后找不到元素(想绑定jQuery插入到它)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以我有2个HTML页面。 1作为容器起作用,1作为内容。
当我加载一个表的内容页面时,我可以使用拖放。



但是当我去我的容器页面并加载内容页面变成带有ajax的div,拖放停止工作。内容页面内的所有其他JavaScript功能仍然可行。我如何将jquery dnd插件绑定到加载ajax的表中?



我正在使用drag&作为教程事件行

  • 当这样的事件触发时,开始移动表行以匹配鼠标位置

  • mouseup 发生,检测并确定位置。



  • 让我们看看我们可以做些类似的事情。
    我们假设表的HTML是这样的:

     < table> 
    < tbody>
    < tr>
    < td>你好1< / td>
    < / tr>< tr>
    < td>你好2< / td>
    < / tr>
    < / tbody>
    < / table>

    这是一个带有一些基本样式的表格的小提琴



    接下来,我们将听取选择事件。我们将在表格行中添加一个事件以供选择,并将文档添加到鼠标悬停时。 jQuery有这样的事件的事件监听器。由于我们希望这些事件能够保持即使在AJAX之后,我们将使用 .on ,让我们使用委托事件。 .on 意味着即使我们在后面添加内容也没关系。

      var selected; //当前选中的行
    $(document).on(mousedown,#MySpecialTable tr,function(){
    $(#textDiv).text(this.textContent);
    selected = this;
    });
    $(document).on(mouseup,function(){
    $(#textDiv)。text(Left+ selected.textContent);
    selected = null;
    });

    这是一个这样的代码的工作小提琴



    现在,我们将要实际更改拖放和停止工作,即更新当前位置反映鼠标的位置。我们可以听 mousemove 事件,并检测我们当前的元素。像$

    }); 

    你可以在这里看到一个工作小提琴



    这很好,但是我们想要实际更改元素的位置。所以我们需要改变表格结构。我们可以删除元素,并将其附加到正确的位置。我们将检查我们是否有一个选定的元素,如果我们这样做,我们可以跟踪它与mousemove事件中的当前元素。我们可以让初学者检测我们是否应该拖动以下东西:

      $(document).on(mousemove,function e){
    if(selected!= null){//获取一个元素
    if($(#MySpecialTable)。(e.target).length> 0){//在表
    $(#mousePos)。text(DRAGGING);
    }
    } else {
    $(#mousePos)。 SELECTED);
    }
    });

    (小提琴)



    现在,我们将添加实际选择,当目标不是我们的元素时,我们将替换元素,我们在桌子。我们的完整代码应该是这样的:

      var selected; 
    $(document).on(mousedown,#MySpecialTable tr,function(e){
    e.preventDefault(); //停止文本选择;
    $ #textDiv)。text(this.textContent);
    selected = $(this);
    selected.find(td)。css(background-color,#999);
    });
    $(document).on(mouseup,function(){
    $(#textDiv)。text(Left+ selected.text());
    selected。 find(td)。css(background-color,);
    selected = null;
    });
    $(document).on(mousemove,function(e){
    if(selected!= null){//获取一个元素
    if($(#MySpecialTable ).has(e.target).length> 0){//在表
    var el = $(e.target).closest(tr); //我们所在的tr元素
    el.before(selected); //替换元素
    }
    } else {
    $(#mousePos)。text(NOT SELECTED);
    }
    });

    $(#MySpecialTable)。on('selectstart',false); //不要让用户选择表

    小提琴



    现在,到目前为止,我们只有几行代码,这是很好的,因为我们知道正在发生什么,不需要使用大量的外部代码行,我们不完全了解。



    但是它会是AJAX吗?



    让我们用AJAX将数据加载到表中,看看!我们将使用 setTimeout 来模拟AJAX响应,这将允许我们模拟异步请求。我们将使用

      setTimeout(function(){
    $(#MySpecialTable)。html(< ; tr>< td> Hello 1< / td>< / tr>< tr>< td> Hello 2< / td>< / tr>< tr>< td> Hello 3< / td> ;< / tr>< tr>< td> Hello 4< / td>< / tr>< tr>< td> Hello 5< / td>< / tr>< tr> td> Hello 6< / td>< / tr>);
    },1000);

    这意味着,更新 #MySpecialTable

    所以为什么它工作?,我们使用委托事件,这意味着我们不在乎我们'重新加载现在或不在屏幕中。我们有自己的洞察力,因为我们自己建立我们的代码,知道我们的最终目标是什么。唯一要做的就是清理代码。



    我们将在下面的代码中包装,以防止$在非冲突模式下成为一个问题(也就是说,$已经在页面中使用:

     (function($){

    })(jQuery);

    接下来我们将为表事件添加一个绑定:

      $。GertVDragTable = function(elementSelector){//其余的代码

    最终,我们的代码可能会看起来像这样。



    使用它,将是一个简单的 $。GertVDragTable(#MySpecialTable); 或者,我们可以把它放在 $。fn 上,让每一个函数调用它,这是一个味道。



    否复制面食请:) :)如果您停止在每个阶段,并认为为什么下一步被采取,我将不胜感激。


    So I have 2 html pages. 1 that functions as container and 1 that functions as content. When I load the content page with a table I'm able to use drag and drop.

    But when I go to my container page and load the content page into a div with ajax, the drag and drop stops working. All other javascript functionalities inside the content page still work. How can I bind the jquery dnd plugin to the table loaded with ajax?

    I'm using drag & drop with this as tutorial http://isocra.com/2008/02/table-drag-and-drop-jquery-plugin/

    my code looks like this:

    $(window).load(function()
    {   if(temp == 0)
        { 
            DP("eerste keer")
            load_table(); 
            temp = 1;
        }
    } );
    
    function load_table()
    {    
        DP('load_table');
        $.ajax({
                //async: false,
                type: "POST",
                url: "/diagnose_hoofdpagina/table_diagnose/" + DosierID, // <== loads requested page
                success: function (data) {
                        $("#diagnoses_zelf").html(''); //<== clears current content of div
                        $("#diagnoses_zelf").append(data).trigger('create'); // <== appends requested page
                    },
                error: function(){
                    alert('error');
                  } 
            }).done(function() {
            update_table(); 
            initialize_table();    // <== calls jquery plug in
            });
    
        return false;   
    }
    
    
    function initialize_table() 
    {
        var tableid = $('#diagnoses_zelf table').attr('id'); //< this finds the correct table thanks to Fábio Batista => this option worked, rest didn't
        alert(tableid);
        $(tableid).tableDnD({    
            onDrop: function(table, row) {
            alert(table + "     "  +  row);
    
            },
            onDragStart: function(table,row){
            var tette = $(row).index;
            alert(tette);
            },
            dragHandle: ".dragHandle"
        });     
    }
    

    How is this possible and what can I do about it? Can anyone help me with this please.

    Very short: I want access to the ID of the table I load into my container page with ajax and use the jquery drag and drop plug in on it.

    EDIT

    Findings:

    Somehow my table in the container page got renamed to pSqlaTable instead of the id I gave to it in the controller page which is.

    <table id="tableDiagnose" class="table table-hover">
    

    Thats why the code couldn't find the table annymore Got fixed by this code thanks to Fábio Batista:

    $('#diagnoses_zelf table').tableDnD( ... );
    

    , but how can I use the dnd plugin now ?

    It finds the table now, but I'm still not able to bind the dnd plugin to it, Am I able to bind a jquery plug in to ajax loaded tables ?

    EDIT

    //drag & drop http://isocra.com/2008/02/table-drag-and-drop-jquery-plugin/
    function initialize_table() 
    {
        var tableid = $('#diagnoses_zelf table').attr('id');
        alert(tableid);
        $('#' + tableid).tableDnD({    
            onDrop: function(table, row) {
            alert(table + "     "  +  row);
    
            },
            onDragStart: function(table,row){
            alert('issemer?');
            },
            dragHandle: ".dragHandle"
        });    
    } 
    

    This is the code i'm still stuck with. tableid is correct but the initialisation of the jquery isn't. I can't drag the drows in the table. Is my syntax wrong ?

    EDIT

    Could it be that I can't bind the jquery to the table because I dynamicaly generate the table on the other page with ZPT (or javascript) ?

    解决方案

    The issue with plugins.

    You're mixing lots of external libraries and code. This results in possible mis-matches between versions, and a lot of black boxes in your code.

    As a developer, this should make you feel very uneasy. Having code you do not fully understand in your code base can get really frustrating really fast.

    The alternative.

    Often, these sort of plugins provide functionality we, as JavaScript developers can accomplish just as easily without them. This development process, in simple enough scenarios, lets us create code we understand and have an easier time maintaining. Not only do we learn from this process, but we also create smaller bits of specific code. Community driven solutions are very good in general, but it's important to remember they're not a silver bullet. Often you're stuck using a not-so-active project which has a bug for your specific case and you have to dig through a large, unfamiliar code base.

    Your code

    So what does this drag and drop plugin do?

    Well, I'd break it down as the following:

    • Listens to the mousedown event on table rows
    • When such an event fires, start moving the table row to match the mouse position
    • When mouseup occurs, detect that, and finalize the position.

    Let us see how we can do something similar. Let's assume the table's HTML is something like:

    <table>
        <tbody>
        <tr>
            <td> Hello 1</td>
        </tr><tr>
            <td> Hello 2</td>
        </tr>
        </tbody>
    </table>
    

    Here is a fiddle with the table with some basic styling applied

    Next, we'll listen to the selection events. We'll add an event to the table rows for selection and to the document to when the mouse is up. jQuery has event listeners for such events. Since we want these events to stick even after AJAX, we'll use .on which lets us use delegated events. .on means that even if we add content to the table later, it won't matter.

    var selected; // currently selected row
    $(document).on("mousedown","#MySpecialTable tr",function(){
       $("#textDiv").text(this.textContent); 
        selected = this;
    });
    $(document).on("mouseup",function(){
        $("#textDiv").text("Left "+selected.textContent); 
        selected = null;
    });
    

    Here is a working fiddle of such code.

    Now, we'll want to actually change the drag&drop to work when, that is, update the current position to the one reflecting the mouse position. We can listen to mousemove events, and detect the element we're currently on. Something like

    $(document).on("mousemove",function(e){
        $("#textDiv").text($(e.target).html());
    });
    

    You can see a working fiddle here

    That's nice, but we want to actually change the element position. So we'll need to change the table structure to allow that. We can remove the element, and append it at the correct position. We'll check if we have a selected element, and if we do, we can track it compared to the current element in the mousemove event. We can for starters detect if we should drag with something like:

    $(document).on("mousemove",function(e){
        if(selected !=null){// got an element selected
            if($("#MySpecialTable").has(e.target).length > 0){ //in the table
                $("#mousePos").text("DRAGGING");    
            }
        }else{
            $("#mousePos").text("NOT SELECTED");
        }
    });
    

    (Fiddle)

    Now, we'll add actual selection, we'll replace the elements when the target is not our element and we're in the table. Our full code should be something like:

    var selected;
    $(document).on("mousedown","#MySpecialTable tr",function(e){
        e.preventDefault();//stop the text selection;
       $("#textDiv").text(this.textContent); 
        selected = $(this);
        selected.find("td").css("background-color","#999");
    });
    $(document).on("mouseup",function(){
        $("#textDiv").text("Left "+selected.text()); 
        selected.find("td").css("background-color","");
        selected = null;
    });
    $(document).on("mousemove",function(e){
        if(selected !=null){// got an element selected
            if($("#MySpecialTable").has(e.target).length > 0){ //in the table
                var el = $(e.target).closest("tr");//the tr element we're on
                el.before(selected);// replace the elements
            }
        }else{
            $("#mousePos").text("NOT SELECTED");
        }
    });
    
    $("#MySpecialTable").on('selectstart', false);//Don't let the user select the table
    

    (Fiddle)

    Now, so far we only have a few lines of code, which is nice since we know exactly what's going on and didn't need to use lots of lines of external code we don't fully understand.

    But will it AJAX?

    Let's load the data into the table with AJAX and see! We'll simulate an AJAX response using a setTimeout which would allow us to simulate an asynchronous request. We'll use

    setTimeout(function(){
        $("#MySpecialTable").html("<tr><td> Hello 1</td></tr><tr><td> Hello 2</td></tr><tr><td> Hello 3</td></tr><tr><td> Hello 4</td></tr><tr><td> Hello 5</td></tr><tr><td> Hello 6</td></tr>");
    },1000);
    

    This means, update the HTML of #MySpecialTable after one second. Let's see if it works shall we?

    So why does it work? well, we used delegated events which means we don't care if the elements we're loading are in the screen right now or not. We had the insight to do this since we built our code ourselves and knew what our final goal was. The only thing left to do is clean the code a little.

    We'll wrap our code in the following, to prevent $ from being an issue in non-conflict mode (that is, $ is already taken in the page:

    (function($){
    
    })(jQuery);
    

    Next we'll add a binding for our table event:

    $.GertVDragTable = function(elementSelector){ // rest of code.
    

    Eventually, our code might look something like this.

    Using it, would be a simple $.GertVDragTable("#MySpecialTable"); alternatively, we can put it on $.fn and allow every function to call it. Which is a matter of taste.

    No copy-pasta please :) I'd appreciate it if you stop on every stage and think why the next step was taken.

    这篇关于在使用ajax加载DOM后找不到元素(想绑定jQuery插入到它)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆