$(function() { $(document.body).on("click", ".delete", function (evt) { evt.preventDefault(); $(this).closest("li").remove(); }); $(".append").click(function () { $("<li>New item</li>").insertAfter($(".items").children()[2]); }); $(".reorder").click(function () { $(".items li") .snapshotStyles() .tsort({ order: "rand" }) .releaseSnapshot(); }); $(".items").sortable({ start: function (event, ui) { // Temporarily move the dragged item to the end of the list so that it doesn't offset the items // below it (jQuery UI adds a 'placeholder' element which creates the desired offset during dragging) $(ui.item).appendTo(this).addClass("dragging"); }, stop: function (event, ui) { // jQuery UI instantly moves the element to its final position, but we want it to transition there. // So, first convert the final top/left position into a translate3d style override var newTranslation = "translate3d(" + ui.position.left + "px, " + ui.position.top + "px, 0)"; $(ui.item).css("-webkit-transform", newTranslation) .css("transform", newTranslation); // ... then remove that override within a snapshot so that it transitions. $(ui.item).snapshotStyles().removeClass("dragging").releaseSnapshot(); } }); // 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); // Snapshotting utils (function () { var stylesToSnapshot = ["transform", "-webkit-transform"]; $.fn.snapshotStyles = function () { if (window.getComputedStyle) { $(this).each(function () { for (var i = 0; i < stylesToSnapshot.length; i++) this.style[stylesToSnapshot[i]] = getComputedStyle(this)[stylesToSnapshot[i]]; }); } return this; }; $.fn.releaseSnapshot = function () { $(this).each(function () { this.offsetHeight; // Force position to be recomputed before transition starts for (var i = 0; i < stylesToSnapshot.length; i++) this.style[stylesToSnapshot[i]] = ""; }); }; })();
<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 item</button> <button class="reorder">Random order</button> <!--[if lte IE 9]><style type="text/css"> /* Old IE doesn't support CSS transform or transitions */ .items li { position: relative; display: inline-block; } </style><![endif]-->
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; cursor: move; -webkit-transition: all 0.2s ease-out; transition: all 0.2s ease-out; } .items li.dragging:nth-child(n) { -webkit-transform: none; -webkit-transition: none; transform: none; transition: none; box-shadow: 0 0 8px black; background-color: white; }