【问题标题】:List elements animation doesn't work when hide/show隐藏/显示时列表元素动画不起作用
【发布时间】:2015-09-15 11:19:41
【问题描述】:

li 元素是否可以从这里开始动画:

http://jsfiddle.net/8XM3q/light/

在使用显示/隐藏功能而不是删除时进行动画处理? 当我将“删除”更改为“隐藏”时,元素没有移动:http://jsfiddle.net/8XM3q/90/

我想将此功能用于我的内容过滤动画 - 这就是为什么我必须将“删除”替换为“隐藏/显示”。

我不擅长 JS,但我认为它会计算所有元素,即使它们是隐藏的:

function createListStyles(rulePattern, rows, cols) {
var rules = [], index = 0;
for (var rowIndex = 0; rowIndex < rows; rowIndex++) {
    for (var colIndex = 0; colIndex < cols; colIndex++) {
        var x = (colIndex * 100) + "%",
            y = (rowIndex * 100) + "%",
            transforms = "{ -webkit-transform: translate3d(" + x + ", " + y + ", 0); transform: translate3d(" + x + ", " + y + ", 0); }";
        rules.push(rulePattern.replace("{0}", ++index) + transforms);
    }
}
var headElem = document.getElementsByTagName("head")[0],
    styleElem = $("<style>").attr("type", "text/css").appendTo(headElem)[0];
if (styleElem.styleSheet) {
    styleElem.styleSheet.cssText = rules.join("\n");
} else {
    styleElem.textContent = rules.join("\n");
}

所以我的问题是如何调整这部分代码以仅计算“显示”(显示)元素?

【问题讨论】:

  • 这里的问题是CSS选择器".items li:nth-child({0})"不关心元素是否隐藏。只要元素仍然存在,nth-child 就会计算它。统计元素个数是这段代码定位的核心。
  • 所以不可能应用/更改该代码来隐藏/显示功能?
  • 我看不出有任何方法可以这样做(仅使用 CSS 规则,使用 nth-child 和 translate3d)。请问,float 没有解决你的问题?

标签: javascript animation html-lists show-hide removeclass


【解决方案1】:

如果您想拥有动画并且仍然拥有所有数据,请使用 detach() 函数而不是删除:jQuery - detach

要计算或选择元素,请尝试使用附加到每个元素的 css 类来执行此操作。

【讨论】:

  • 我认为这是一个很好的答案,但如何让它在我的过滤站点上工作:jsfiddle.net/8u43sz53?我尝试使用 detach() 和 append 但元素没有再次出现。
  • 看这里(这是前面的例子):jsfiddle.net 你可以在分离时记住 te 元素(就像我在名为 element 的变量中所做的那样),然后使用 append 函数将此元素附加到适当的位置。这只是一个示例,因此它只记住最后删除的元素,但我相信它显示了它是如何工作的。
  • 谢谢你的解释:)
【解决方案2】:

我编辑了你的 jsFiddle: http://jsfiddle.net/8XM3q/101/

请注意我更改了这一行:编辑:http://jsfiddle.net/8XM3q/101/ $(this).closest("li").remove();

对此: $(this).closest("li").hide("slow",function(){$(this).detach()});

这意味着隐藏项目,速度 = 慢,完成隐藏后将其移除。

希望这就是你的意思。

编辑:包括分离。

【讨论】:

  • 我想将此功能用于我的内容过滤动画 - 这就是为什么我必须将“删除”替换为“隐藏/显示”我根本不想删除元素。如果我的问题误导了您,我很抱歉。
  • 如果您根本不想删除,只需隐藏然后在我的小提琴中将这个$(this).closest("li").hide("slow",function(){$(this).remove()}); 替换为$(this).closest("li").hide("slow");
  • 该元素被隐藏,但该元素之后的元素不会移动以取代它的位置,就像我删除元素时一样。
【解决方案3】:

As per your comment:

我想将此功能用于我的内容过滤动画 - 这就是为什么我必须将“删除”替换为“隐藏/显示”我不想 完全删除元素。如果我的问题误导了您,我很抱歉。

您可以做的是使用缓存来存储列表项,因为它们在您进行内容过滤时是隐藏的。稍后当您需要重置整个列表时,您可以从缓存中补充项目。

相关代码片段...

HTML

...
<button class="append">Add new item</button>
<button class="replenish">Replenish from cache</button>
<div id="cache"></div>

JS

...
$(this).closest("li").hide(600, function() { 
    $(this).appendTo($('#cache')); 
});
...
$(".replenish").click(function () {
    $("#cache").children().eq(0).appendTo($(".items")).show();
});

演示小提琴:http://jsfiddle.net/abhitalks/8XM3q/102/

片段

$(function() {
    $(document.body).on("click", ".delete", function (evt) {
        evt.preventDefault();
        $(this).closest("li").hide(600, function() { 
            $(this).appendTo($('#cache')); 
		});
    });
    
    $(".append").click(function () {
        $("<li>New item  <a href='#' class='delete'>delete</a></li>").insertAfter($(".items").children()[2]);
    });
    $(".replenish").click(function () {
        $("#cache").children().eq(0).appendTo($(".items")).show();
    });

    // Workaround for Webkit bug: force scroll height to be recomputed after the transition ends, not only when it starts
    $(".items").on("webkitTransitionEnd", function () {
        $(this).hide().offset();
        $(this).show();
    });
});

function createListStyles(rulePattern, rows, cols) {
    var rules = [], index = 0;
    for (var rowIndex = 0; rowIndex < rows; rowIndex++) {
        for (var colIndex = 0; colIndex < cols; colIndex++) {
            var x = (colIndex * 100) + "%",
                y = (rowIndex * 100) + "%",
                transforms = "{ -webkit-transform: translate3d(" + x + ", " + y + ", 0); transform: translate3d(" + x + ", " + y + ", 0); }";
            rules.push(rulePattern.replace("{0}", ++index) + transforms);
        }
    }
    var headElem = document.getElementsByTagName("head")[0],
        styleElem = $("<style>").attr("type", "text/css").appendTo(headElem)[0];
    if (styleElem.styleSheet) {
        styleElem.styleSheet.cssText = rules.join("\n");
    } else {
        styleElem.textContent = rules.join("\n");
    }
}

createListStyles(".items li:nth-child({0})", 50, 3);
body { font-family: Arial; }
.items { 
    list-style-type: none; padding: 0; position: relative;
    border: 1px solid black; height: 220px; overflow-y: auto; overflow-x: hidden;
    width: 600px;
}
.items li { 
    height: 50px; width: 200px; line-height: 50px; padding-left: 20px;
    border: 1px solid silver; background: #eee; box-sizing: border-box; -moz-box-sizing: border-box;
    position: absolute; top: 0; left: 0; 
    -webkit-transition: all 0.2s ease-out; transition: all 0.2s ease-out;
}
div.cache { display: none; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<ul class="items">
    <li>Monday <a href="#" class="delete">delete</a>
    </li><li>Tuesday <a href="#" class="delete">delete</a>
    </li><li>Wednesday <a href="#" class="delete">delete</a>
    </li><li>Thursday <a href="#" class="delete">delete</a>
    </li><li>Friday <a href="#" class="delete">delete</a>
    </li><li>Saturday <a href="#" class="delete">delete</a>
    </li><li>Sunday <a href="#" class="delete">delete</a></li>
</ul>
<button class="append">Add new item</button>
<button class="replenish">Replenish from cache</button>
<div id="cache"></div>

【讨论】:

  • 如果我错了,请纠正我,但我认为您的方法太复杂(我不是说复杂),并且在处理大型项目时会导致代码难以理解。当我们选择不包含该类元素的元素时,添加“已删除”类会更简单、更容易。
  • @LyesBEN:(1)这不是我的代码。我只做了几个改变来解决 Op 的问题。 (2) 你有没有读过这个问题,你是否试图理解 Op 的问题是什么?
  • 是的,你可以看看我的回答。 Op 想要隐藏元素,但在循环这些元素时仍然不包含它。我引用“但我认为它计算所有元素,即使它们被隐藏”
  • @LyesBEN:很好。那么,您为什么不从 Op 的小提琴中制作一个工作演示,并将其包含在您的答案中。
【解决方案4】:

编辑:有一种更简单的方法,无需添加任何类,就是使用:visible 选择器

你需要了解一个概念是Javascript,也就是函数被认为是对象。您可以将一个函数传递给另一个函数,或者从一个函数返回一个函数。

让我们查看有关 jQuery 的文档以了解 hide 函数

.hide( duration [, easing ] [, complete ] )

它说它接受一个函数作为完成的参数,当隐藏动画完成时调用它。

hide 函数不会从 DOM 中移除元素,而只是顾名思义“隐藏”它。所以我们要做的是隐藏元素,然后当隐藏动画完成时,我们向列表元素添加一个“已移除”类。

我们将通过像这样传递一个函数(complete 参数)来实现:

$(this).closest("li").hide(400, function() {
  $(this).addClass('removed');
});

当你想选择没有被“移除”的列表元素时,使用这个选择器$('li:not(.removed)')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    相关资源
    最近更新 更多