【问题标题】:jQuery sortable keep table's widthjQuery sortable 保持表格的宽度
【发布时间】:2017-07-03 04:18:53
【问题描述】:

无法找到一个简单的解决方案让 jquery 的 sortable 在拖动元素期间保持表格的宽度,forcePlaceholderSize 这次实际上并没有工作,如果表格有一些大元素 - 如果我开始拖动它,那么表格的大小会调整为静止-table 元素的最大宽度,这就是我所做的:

jQuery("#sortable1").sortable({
    items: "tbody:not([not-sortable])",
    cursor: "move",
    zIndex: 9999,
    start: function (event, ui) {
        var colW = jQuery(".faq_glyph_owner").width();
        self.textWidth = ui.item.innerWidth() - colW * 3;
        jQuery(".faq_text").width(self.textWidth);
        jQuery("#sortable1").css("table-layout", "fixed");
        ui.item.find("div").parent().width(self.textWidth + colW);
    },
    stop: function (event, ui) {
        jQuery("#sortable1").css("table-layout", "auto");
    }
});

所以我通常只是按应有的大小计算大小并将固定布局应用于表格here is sample of this with table。所以我的问题是:是否有任何内置方法可以在排序期间保持表格宽度,好像拖动的元素仍在表格内?请注意,我不想保持表格的布局固定。 p>

附:请忽略“jQuery”,我们仍然有旧的原型代码会干扰它

【问题讨论】:

  • 您已经拥有的是实现此行为的最直接方法。 forcePlaceholderSize 选项只会在占位符不可见的情况下设置占位符的大小(即,它是一个 0 宽度的矩形,在这里它不是)。如果你想彻底,创建一个新的小部件,从 sortable 继承,并编写一个自定义占位符,但对于类似的效果,这是很多额外的工作

标签: javascript jquery css jquery-ui


【解决方案1】:

这是我为此使用的代码。我创建了一个辅助函数,它获取行中所有内容的高度和宽度,然后将其显式设置为这些高度和宽度,并在其中添加一行作为占位符。

var fixHelper = function (e, ui) {
    ui.children().each(function () {
        if ($(this).children().length > 0) {
            fixHelper(e, $(this));
        }
        if(parseInt($(this).css("margin-left")) != 0)
            $(this).css("margin-left", $(this).css("margin-left"));

        if (parseInt($(this).css("margin-right")) != 0)
            $(this).css("margin-right", $(this).css("margin-right"));

        $(this).width($(this).realWidth(true));
        $(this).height($(this).realHeight(true));
    });

    ui.height(ui.realHeight());
    return ui;
};

var unfixHelper = function (ui) {
    ui.children().each(function () {
        if ($(this).children().length > 0) {
            unfixHelper($(this));
        }
        $(this).css("margin-left", "");
        $(this).css("margin-right", "");
        $(this).css("width", "");
        $(this).css("height", "");
    });
    ui.css("height", "");
};


var sortableOptions = new Object({
    items: "tbody:not([not-sortable])",
    cursor: "move",
    zIndex: 9999,
    helper: fixHelper,
    start: function (e, ui) {
        ui.placeholder.height(ui.item.height());
        ui.placeholder.html("<td colspan=\"10\">&nbsp;</td>");
    },
    stop: function (e, ui) {
        unfixHelper(ui.item);
        ui.placeholder.html("");
    }   
});

jQuery("#sortable1").sortable(sortableOptions);

另一个文件(real-dimensions.js):

$.fn.realWidth = function (inner) {
    var $t = $(this);
    var rect = this[0].getBoundingClientRect();

    var width;
    if (rect.width) {
        // `width` is available for IE9+
        width = rect.width;

    } else {
        // Calculate width for IE8 and below
        width = rect.right - rect.left;
    }

    if (inner)
        width -= parseInt($t.css("padding-left")) + parseInt($t.css("padding-right"));

    return width;
}

$.fn.realHeight = function (inner) {
    var $t = $(this);
    var rect = this[0].getBoundingClientRect();

    var height;
    if (rect.height) {
        // `height` is available for IE9+
        height = rect.height;
    } else {
        // Calculate height for IE8 and below
        height = rect.top - rect.bottom;
    }

    if (inner)
        height -= parseInt($t.css("padding-top")) + parseInt($t.css("padding-bottom"));

    return height;
}

【讨论】:

  • 您的解决方案很棒,但它仍然使用一些计算,所以我不能接受它作为答案,因为我想知道是否有一些内置的可能性可以达到相同的结果,也许我应该指定这个有问题,谢谢
  • 请允许我向您保证,这的答案。没有内置的方法来实现这一点。任何“内置”方式也将使用计算。
  • 有更复杂的代码使用 javascript 的内置函数 .getBoundingClientRect() (.width / .height) 找出 real 高度和宽度(允许小数)我也用。我称他们为realWidth()realHeight()
  • 我坚持认为这不是我问的答案,因为我已经有办法用更少的代码做同样的事情,它就在我的问题中,我真正想要的是对于简单的解决方案,不需要任何关于 DOM 元素可排序的额外知识。如果没有这样的 - 那么这个问题没有答案,但它仍然不能让你的答案成为我正在寻找的东西
【解决方案2】:

可排序小部件中有一个名为helper 的选项。其目的是为拖动显示动作添加一些行为。 修改的相关部分是:

jQuery('#sortable1').sortable({
    helper: fixedWidth
});

function fixedWidth(e, ui) {
    var max_w = 0;
    // get the max width from all the children
    ui.children().each(function() {
        var w = $(this).width();
        if (w > max_w) max_w = w;
    });
    // set the width of the table to be the max
    $('#sortable1').width(max_w);
    return ui; 
}

可以在JSFiddle 中找到完整的实现。我从这个blog得到了灵感。

另外,如果你介意我的意见,我会以更简单的方式构建这个结构,使用&lt;ul&gt; 而不是&lt;table&gt;。喜欢this。您只需设置 &lt;ul&gt; 的样式即可获得固定宽度。

【讨论】:

    【解决方案3】:
    var fixHelper = function(e, ui) {  
      ui.children().each(function() {  
      console.log(e);
        $(this).width($(this).width());  
      });  
      return ui;  
    };
    
    $("#sortable1 tbody").sortable({  
        helper: fixHelper  
    }).disableSelection();
    

    JSfiddle

    Source article

    【讨论】:

    • 感谢您的链接,但如果指定按#sortable(这是必需的)而不是#sortable tbody(限制拖动到一个tbody,因此需要额外的connectTo),并且表格仍然折叠(至少在第一次拖动时)。它唯一没有折叠的行
    【解决方案4】:

    这个怎么样:

    $("#sortable1").sortable({
            items: "tbody:not([not-sortable])",
            helper: 'clone',
            cursor: "move",
            zIndex: 9999,
            start: function (event, ui) {
                $(ui.item[0]).show().css('opacity','0');
            },
            stop: function (event, ui) {
                $(ui.item[0]).css('opacity','1');
            }
        });
    

    您基本上是在克隆元素,而不是在移动时隐藏它,您只需应用 0 的 opacity ,然后在删除后应用 1 的 opacity 。我真的没有时间测试它。

    【讨论】:

    • 这真是个好主意,经过了一些测试,它正在工作,只需要进行一些更改以使其完全适合(现在这个元素虽然不透明度为 0,但仍然有边框),我会尽快标记你的答案,一旦设法创建一个完美运行的小提琴
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 2010-10-08
    • 1970-01-01
    • 1970-01-01
    • 2014-01-19
    • 2013-06-22
    • 2012-02-18
    相关资源
    最近更新 更多