【问题标题】:Can't find element in DOM after loading it with ajax (want to bind jquery plug in to it)用ajax加载后在DOM中找不到元素(想绑定jquery插件)
【发布时间】:2023-04-07 12:20:01
【问题描述】:

所以我有 2 个 html 页面。 1 用作容器,1 用作内容。 当我使用表格加载内容页面时,我可以使用拖放操作。

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

我正在使用拖放作为教程http://isocra.com/2008/02/table-drag-and-drop-jquery-plugin/

我的代码如下所示:

$(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"
    });     
}

这怎么可能?我能做些什么呢? 谁能帮我解决这个问题。

很短: 我想访问我使用 ajax 加载到我的容器页面中的表的 ID,并在其上使用 jquery 拖放插件。

编辑

调查结果:

不知何故,我在容器页面中的表被重命名为 pSqlaTable,而不是我在控制器页面中给它的 id。

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

这就是为什么代码找不到表 annymore 多亏了 Fábio Batista,此代码已修复:

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

,但是我现在如何使用 dnd 插件呢?

它现在找到了表,但我仍然无法将 dnd 插件绑定到它,我可以将 jquery 插件绑定到 ajax 加载的表吗?

编辑

//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"
    });    
} 

这是我仍然坚持的代码。 tableid 是正确的,但 jquery 的初始化不正确。我不能拖着桌子上的卓尔人。我的语法错了吗?

编辑

难道我无法将 jquery 绑定到表格,因为我使用 ZPT(或 javascript)在其他页面上动态生成表格?

【问题讨论】:

  • .tableDnD 行上的“卡在这里”是什么意思?是否有任何错误打印到 JS 控制台?如果是这样,请包括它。如果没有,您可能是正确的,它找不到 #tableDiagnose 元素,我会检查以确保使用该 ID 正确创建 HTML。
  • 没有给出错误,我会检查表是否获得了正确的 id,但这应该不是问题。以防万一。根本不可能将工作控制器包含到容器页面中吗?还是我真的需要把我的 dnd 逻辑放在容器页面上?
  • 可以在不破坏 JS 事件的情况下将 HTML(例如你的控制器)嵌入到容器中,但这涉及到使用特殊的 JS 方法(如 .detach 和 .append)after 根据您的解决方案,HTML 已在前端初始化,否则请确保您的 ID 不会更改。我认为,这将是您看到的一个单独的后端错误。 ...至于将“dnd 的逻辑放在容器页面上”,我会考虑将该 JS 模块化为一个共享的 .js 文件,如果您在多个地方需要它,该文件可以根据需要重复使用。
  • 我会试试的,谢谢你的意见
  • 你能console.log(data) 告诉我们吗?

标签: javascript jquery html ajax dom


【解决方案1】:

插件问题。

您正在混合大量外部库和代码。这会导致版本之间可能不匹配,并且代码中出现大量黑框。

作为开发人员,这应该会让您感到非常不安。在你的代码库中有你不完全理解的代码会很快变得非常令人沮丧。

另一种选择。

通常,这类插件为我们提供功能,因为 JavaScript 开发人员可以在没有它们的情况下轻松完成。这个开发过程,在足够简单的场景中,让我们创建我们理解的代码并且更容易维护。我们不仅从这个过程中学习,而且我们还创建了更小的特定代码。一般来说,社区驱动的解决方案非常好,但重要的是要记住它们不是灵丹妙药。通常,您会被一个不那么活跃的项目卡住,该项目对您的特定情况有一个错误,您必须挖掘一个庞大的、不熟悉的代码库。

您的代码

那么这个拖放插件有什么作用呢?

好吧,我将其分解如下:

  • 在表行上监听the mousedown 事件
  • 当此类事件触发时,开始移动表格行以匹配鼠标位置
  • mouseup 出现时,检测到它并最终确定位置。

让我们看看如何做类似的事情。 假设表格的 HTML 类似于:

<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

接下来,我们将监听选择事件。我们将向表格行添加一个事件以供选择,并在鼠标向上时向文档添加一个事件。 jQuery 为此类事件提供了事件侦听器。由于我们希望这些事件即使在 AJAX 之后仍然存在,我们将使用.on,它允许我们使用委托事件。 .on 表示即使我们稍后在表格中添加内容也没关系。

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 的此类代码。

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

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

You can see a working fiddle here

这很好,但我们想要真正改变元素的位置。因此,我们需要更改表结构以允许这样做。我们可以删除元素,并将其附加到正确的位置。我们将检查我们是否有一个选定的元素,如果有,我们可以在 mousemove 事件中将其与当前元素进行比较。对于初学者,我们可以检测是否应该使用以下内容进行拖动:

$(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)

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

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)

现在,到目前为止,我们只有几行代码,这很好,因为我们确切地知道发生了什么,并且不需要使用很多我们不完全理解的外部代码行。

但它会 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 的 HTML。让我们看看它是否有效?

So why does it work? 好吧,我们使用了delegated events,这意味着我们不关心我们正在加载的元素现在是否在屏幕上。自从我们自己构建代码并知道我们的最终目标是什么以来,我们就有了这样做的洞察力。剩下要做的就是稍微清理一下代码。

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

(function($){

})(jQuery);

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

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

最终,我们的代码可能会look something like this.

使用它,将是一个简单的$.GertVDragTable("#MySpecialTable"); 或者,我们可以将它放在$.fn 上并允许每个函数调用它。这是一个品味问题。

请不要复制意大利面 :) 如果您在每个阶段都停下来想想为什么采取了下一步,我将不胜感激。

【讨论】:

  • 不是如何实现 jquery 的答案。但帮助我完成了开始我自己的 dnd 的技巧。感谢您的帮助和好帖子。
【解决方案2】:

您不需要将 ID 用作选择器,您可以使用任何可以找到您的表格的表达式。

如果在生成的$.ajax 调用中只有一个表,您可以使用不会更改的容器 ID 搜索“容器内的表”:

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

如果有多个表,请使用不同类型的选择器,而不是 ID。 CSS 类可以正常工作:

$('table.table-diagnose').tableDnD( ... );

data- 属性也是如此:

$("table[data-diagnose]").tableDnD( ... );

【讨论】:

  • 请注意data 属性是 HTML5 属性,并非所有浏览器都支持。
【解决方案3】:

尝试将title 添加到您的表中,如下所示:

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

然后使用 jQuery attribute selector 查找此表,而不是通过 id 查找。

$('table[title="table-content"]').tableDnD({ 
// the rest of your code

【讨论】:

  • 这是一段不错的代码,但 Fábio Batista 的建议对我来说很好。 $('#diagnoses_zelf table').tableDnD( ... );
  • 它帮助了我一点,它没有解决问题,所以我不会接受它作为答案。对不起。
【解决方案4】:

如果您的 id 发生变化,则不应使用 ID:

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

插件

function initialize_table() 
{
    $('.tableDiagnose.table').tableDnD({    
        onDrop: function(table, row) {
        alert(table + "     "  +  row);
        },
        dragHandle: ".dragHandle"
    });   
    DP('nee');  
}

编辑:ajax 是异步的:

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
                    update_table(); 
                    initialize_table();    // <== calls jquery plug in
                },
            error: function(){
                alert('error');
              } 
        });
        //removed .done as you already have a success option in ajax


    return false;   
}

编辑:发现你的错误............ 您检索表 id 然后在 $(tableid) 中选择它,但您错过了#

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);
    // but you really should limit the use of variables when you don't need them*/
    //$('#'+tableid).tableDnD({            
    //like this directly
    $('#diagnoses_zelf table').tableDnD({    
        onDrop: function(table, row) {
        alert(table + "     "  +  row);

        },
        onDragStart: function(table,row){
        var tette = $(row).index;
        //alert(tette);
        },
        dragHandle: ".dragHandle"
    });     
}

See the demo here

编辑

【讨论】:

  • 感谢您的输入,我使用$('#diagnoses_zelf table').tableDnD( ... ); 修复了(找不到我的表ID问题)
  • 我已经看了一下代码,试试$.tableDnD.makeDraggable($('#diagnoses_zelf table'))
  • 我应该把它放在哪里,因为我看不出这将如何帮助我将插件绑定到表格。
  • @GertV 查看我的编辑部分。您忘记了表 ID 选择器中的 #
  • 我会让你知道我的发现,我现在要再次检查我的代码,因为它在你的示例中确实有效。
【解决方案5】:

您是在容器页面还是在内容页面中包含脚本文件?我猜你可能想在使用 getScript 调用 dnd 插件时尝试加载它:

...
$.getScript('pathTotableDnDlib').done(function(){
    $(tableid).tableDnD({    
    onDrop: function(table, row) {
    alert(table + "     "  +  row);

    },
    onDragStart: function(table,row){
    var tette = $(row).index;
    alert(tette);
    },
    dragHandle: ".dragHandle"
});});
...

关于 getscript 的更多信息:here

【讨论】:

  • 首先我将它添加到我的内容页面中。一切都在那里工作,直到我将它加载到我的容器页面中。我现在将代码转移到我的容器页面。脚本本身是可调用的,这就是为什么我不明白为什么我不能将它绑定到表格。我可以将 jquery 插件绑定到加载的内容吗?
  • @GertV 当然可以。如果 id 正确,则内容加载正常,并且插件本身已加载并且...“可插入”。您可能想尝试加载内容并尝试从开发人员控制台绑定插件。检查插件是否加载,调用$().tableDnD,它应该输入函数字符串,如果是,尝试调用initialize_table(),如果插件(调用后)是有界的,那么它可能是同步问题。
【解决方案6】:

@BenjaminGruenbaum 非常感谢本教程,我修改了一些代码以阻止在表格标题上拖放并提高拖动流动性跟踪鼠标方向。

var old_y = 0;
(function ($) {
    $.GertVDragTable = function (tableName) {
        var selected;
        $(document).on("mousedown", tableName+" tr",function (e) {
            e.preventDefault(); //stop the text selection;
            if (($(this).find('th').length)== 0){   //prevent dragging on tr containing th
            selected = $(this);
            selected.find("td").css("background-color", "black");
            selected.find("td").css("color", "white");
            }
        });

        $(document).on("mouseup", function () {
            selected.find("td").css("background-color", "");
            selected.find("td").css("color", "");
            selected = null;
        });
        $(document).on("mousemove", function (e) {
            if (selected != null ) { // got an element selected
                if ($(tableName).has(e.target).length > 0) { //in the table
                    var el = $(e.target).closest("tr"); //the tr element we're on
                    if (el.find('th').length==0){ //prevent dropping on headers row

                    if (e.pageY > old_y){       //**
                    el.after(selected);}else{   //**-->more fluid dragging based on mouse direction
                        el.before(selected);    //**
                    }

                }
                }
                old_y = e.pageY;
            }
        });

        $(tableName).on('selectstart', false); //Don't let the user select the table
    }
})(jQuery);

这是小提琴http://jsfiddle.net/59rdq/

我希望它对某人有用。

【讨论】:

    猜你喜欢
    • 2012-05-18
    • 1970-01-01
    • 2014-05-09
    • 2012-03-23
    • 2012-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    相关资源
    最近更新 更多