简体   繁体   中英

List elements animation doesn't work when hide/show

Is it possible for li elements animation from here:

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

to animate when there is show/hide function used instead of remove? When i have changed "remove" to "hide" elements didn't move: http://jsfiddle.net/8XM3q/90/

I wanted to use this function for my content filtering animations - thats why i have to replace "remove" to "hide/show".

I'm not good at JS but i think that it counts all elements, even when they are hidden:

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

So my question is how to adapt that part of code to count only "show" (displayed) elements?

I edited your jsFiddle: http://jsfiddle.net/8XM3q/101/

notice that I changed this line:EDIT: http://jsfiddle.net/8XM3q/101/ $(this).closest("li").remove();

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

This means hide the item, speed = slow, when done hiding remove it.

Hope this is what you meant.

EDIT: Included detach.

If you want to have the animation and still have all of the data then use detach() function instead of remove: jQuery - detach

And to count or select elements try to do this using css's class attached to each element.

As per your comment :

I wanted to use this function for my content filtering animations - thats why i have to replace "remove" to "hide/show" I don't want to remove elements at all. Im sorry if I mislead You with my question.

What you can do is to use a cache to store the list-items as they are hidden when you do the content filtering. Later when you need to reset the entire list, you can replenish the items from the cache.

Relevant code fragment...

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

Demo Fiddle: http://jsfiddle.net/abhitalks/8XM3q/102/

Snippet :

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

EDIT: There is a simpler way without adding any classes, is to use the :visible selector

You need to understand a concept is Javascript, which is that functions are considered objects. You can pass a function to another function, or return a function from a function.

Let's check the documentation on jQuery for the hide function

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

It says that it accepts a function as an argument for complete, which is called when the hide animation is complete.

The function hide does not remove the element from the DOM but simply "hides" it as the name suggests. So what we want to do, is hide the element then when the animation of hiding is done, we add a class "removed" to the list element.

We will accomplish that by passing a function ( complete argument) like so :

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

When you want to select the list elements that are not "removed", use this selector $('li:not(.removed)')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM