Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/35.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jquery 如何在添加/删除嵌套子级时在每个级别自动更改祖先高度_Jquery_Css_Jquery Ui - Fatal编程技术网

Jquery 如何在添加/删除嵌套子级时在每个级别自动更改祖先高度

Jquery 如何在添加/删除嵌套子级时在每个级别自动更改祖先高度,jquery,css,jquery-ui,Jquery,Css,Jquery Ui,在我正在处理的当前项目中,我需要能够使用jQuery动态添加多级可排序嵌套列表。我有嵌套的可排序列表,但我遇到了这样的问题,即父母的下一个兄弟姐妹在视觉上与上一个父母兄弟姐妹的后代重叠,如所示 从视觉上看,我需要每个列表项不重叠其同级的任何子体,因此我的想法是需要根据子体元素的累积高度设置高度/边距底部 我能做的唯一尝试是: function resizeHeight(){ var setToChildrenHeights = function(){ var height

在我正在处理的当前项目中,我需要能够使用jQuery动态添加多级可排序嵌套列表。我有嵌套的可排序列表,但我遇到了这样的问题,即父母的下一个兄弟姐妹在视觉上与上一个父母兄弟姐妹的后代重叠,如所示

从视觉上看,我需要每个列表项不重叠其同级的任何子体,因此我的想法是需要根据子体元素的累积高度设置高度/边距底部

我能做的唯一尝试是:

function resizeHeight(){
    var setToChildrenHeights = function(){
        var height = $(this).height();
        $(this).children().each(function(){
            height += $(this).outerHeight();
        });
        $(this).css('margin-bottom',height);
    }
    $("li").each(setToChildrenHeights);
}
问题是,当我有3层嵌套列表时,它不起作用,即父对象被推到直接子对象之外,而不是子对象的子对象之外

作为参考,我使用的谷歌搜索的一个子集是:

jquery如何在添加/删除嵌套子级时在每个级别自动更改祖先高度 jquery父级高度更改为添加/删除嵌套子级 jquery列表容器高度随项目的添加而增加 jquery在添加子项时动态更改div的高度 动态添加/删除子项时jquery级联调整大小 jquery根据子元素高度调整列表元素高度 除了搜索jQueryAPI文档,到目前为止我还没有找到解决方案,我希望另一双眼睛能够指出我的错误。感谢您的帮助

更新: 我在这段代码中采用了递归方法,但不幸的是,它现在设置了太多的余量底部:

function recursiveResize($parentElement){
    var numChild = $parentElement.children().length

    console.log('number of children = '+numChild);
    var parentHeight = $parentElement.height();
    if (numChild<1)
        return parentHeight;
    var height = 0;
    $parentElement.children().each(function(){
        height += recursiveResize($(this));
    });
    return parentHeight + height;    
}

//try2
function newResizeRecursive(){
    var $parentElements = $('li');

    $parentElements.each(function(){
        var height = $(this).height();
        var childrenHeights = recursiveResize($(this));
        var newmargin = childrenHeights - height +3
        console.log('new margin = '+newmargin);
        console.log('before '+$(this).css('margin-bottom'))
        $(this).css('margin-bottom', (newmargin>3 ? newmargin: 3))
        console.log('after '+$(this).css('margin-bottom'))
    });    
}
根据我的要求,我相信我们可以为您重新编写代码。不幸的是,你的小提琴只会让我困惑,所以我不会更新它

每次附加元素时,应使用此函数返回的maxHeight调整父元素和父元素的父元素的大小:

var heightArray=$('#builder *').map(function(){
   return $(this).outerHeight();
}).get();

var maxHeight = Math.max.apply(Math, heightArray);
我认为您应该只需要切换父元素id的生成器

将来,使用JSFIDLE,您应该避免包含无关信息,并保持代码简单。您可能希望使用javascript附加按钮,这是有原因的,但是在JSFIDLE中,如果您只使用HTML区域,则更容易看到。

好的,我有一个工作区@James G.的建议是一个很好的开始,但事实证明,重新调整大小有两个问题:

为了使重新调整的大小正常工作,我最终需要找到所有叶节点,然后遍历树,根据其子代的大小重新调整每个祖先的大小,如下所示:

function resize(childId){
    //will find all the leafnodes
    var $leafnodes = findLeafNodes();

    //resize all ancestors of each leafnode
    $leafnodes.each(function(){
        resizebyID($(this).attr('id'));
    });
}

function resizebyID(childId){
    console.log('resize id='+childId);
    var $child = $('#'+childId);
    var $parent = $child.parent();
    var $grandparent = $parent.parent();

    //traverse each ansestor height in order
    $child.parentsUntil('#builder').each(function(){
        if ($(this).is('form')){}
        else{
            var heightsA = $(this).children().map(function(){
               return $(this).outerHeight();
            }).get();
            var heightsum =0;
            for(var i=0; i<heightsA.length; i++)
                heightsum += heightsA[i];

            $(this).css('margin-bottom',heightsum);

            console.log('ancestor:'+ $(this).attr('class')
                        +' height='+heightsum);
        }
    });
}

function findLeafNodes(){
    //try this, from #builder find the deepest child nodes 
    //and then resize each up the node from there:
    function innerMost( root ) {
        var $children = $( root ).children();

        while ( true ) {
            //set uniqueIDs so resize can work
            $children.each(function(){
                $(this).uniqueId();
            })
            var $temp = $children.children();
            if($temp.length > 0) $children = $temp;
            else return $children;
        }
    }

    var $inner = innerMost($('#builder'));
    return $inner;
}
我不仅需要在添加元素时重新调整大小,还需要在触发可排序事件时重新调整大小。因此,我设置了可排序对象,以便在触发事件时调用resize:

function getSortableContainer(containerClass) {
    var $sortableContainer = $('<ul class="' + containerClass + '"></ul>');
    var sortOptions = {
        placeholder: "ui-state-highlight",
        opacity: 0.5,
        connectWith: '.' + containerClass,
        change: function (event, ui) {},
        stop: function (event, ui) {
            console.log("New " + containerClass + " position: " + ui.item.index());
            resize(childID);
        }
    };

    $sortableContainer.sortable(sortOptions);
    $sortableContainer.disableSelection();
    console.log("new " + containerClass + " added");
    return $sortableContainer;
}

好的,在您的代码示例中,我将执行类似于:$'builder'.outerHeightmaxHeight?我已经使用jQuery大约一个星期了,所以仍然对这些东西有感觉。谢谢。也谢谢你关于简化小提琴的建议,我只是不知道如何做一把更简单的小提琴。我不能使用硬编码的html,因为:1。我的要求是builder中的所有内容都是动态生成的,2。每个嵌套列表必须在其自身级别上与其他列表一起排序。我已经尽了最大的努力简化了这把小提琴,清楚地说明了我需要帮助的地方以及安装程序的代码开始的地方。我很欢迎关于如何制作一个更简单的工作示例来满足我的需求的建议,谢谢。