Вы можете сделать это с событиями перехода, так что вы так и есть, вы создаете 2 класса css для перехода, один из которых содержит анимацию другой, удерживая дисплей в состоянии none. и вы переключаете их после окончания анимации? В моем случае я могу отображать div снова, если я нажимаю btn и удаляю оба класса.
Попробуйте отрезать ниже ...
$(document).ready(function() {
//assign transition event
$("table").on("animationend webkitAnimationEnd", ".visibility_switch_off", function(event) {
//we check if this is the same animation we want
if (event.originalEvent.animationName == "col_hide_anim") {
//after the animation we assign this new class that basically hides the elements.
$(this).addClass("animation-helper-display-none");
}
});
$("button").click(function(event) {
$("table tr .hide-col").toggleClass(function() {
//we switch the animation class in a toggle fashion...
//and we know in that after the animation end, there is will the animation-helper-display-none extra class, that we nee to remove, when we want to show the elements again, depending on the toggle state, so we create a relation between them.
if ($(this).is(".animation-helper-display-none")) {
//im toggleing and there is already the above classe, then what we want it to show the elements , so we remove both classes...
return "visibility_switch_off animation-helper-display-none";
} else {
//here we just want to hide the elements, so we just add the animation class, the other will be added later be the animationend event...
return "visibility_switch_off";
}
});
});
});
table th {
background-color: grey;
}
table td {
background-color: white;
padding:5px;
}
.animation-helper-display-none {
display: none;
}
table tr .visibility_switch_off {
animation-fill-mode: forwards;
animation-name: col_hide_anim;
animation-duration: 1s;
}
@-webkit-keyframes col_hide_anim {
0% {opacity: 1;}
100% {opacity: 0;}
}
@-moz-keyframes col_hide_anim {
0% {opacity: 1;}
100% {opacity: 0;}
}
@-o-keyframes col_hide_anim {
0% {opacity: 1;}
100% {opacity: 0;}
}
@keyframes col_hide_anim {
0% {opacity: 1;}
100% {opacity: 0;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table>
<theader>
<tr>
<th>Name</th>
<th class='hide-col'>Age</th>
<th>Country</th>
</tr>
</theader>
<tbody>
<tr>
<td>Name</td>
<td class='hide-col'>Age</td>
<td>Country</td>
</tr>
</tbody>
</table>
<button>Switch - Hide Age column with fadeout animation and display none after</button>
Поскольку отказоустойчивое поведение итератора не гарантируется.
Вы получаете это исключение, потому что вы
Плохо:
// we're using iterator
for (Iterator<String> i = c.iterator(); i.hasNext();) {
// here, the collection will check it hasn't been modified (in effort to fail fast)
String s = i.next();
if(s.equals("lalala")) {
// s is removed from the collection and the collection will take note it was modified
c.remove(s);
}
}
Хорошо:
// we're using iterator
for (Iterator<String> i = c.iterator(); i.hasNext();) {
// here, the collection will check it hasn't been modified (in effort to fail fast)
String s = i.next();
if(s.equals("lalala")) {
// s is removed from the collection through iterator, so the iterator knows the collection changed and can resume the iteration
i.remove();
}
}
Теперь, чтобы перейти к следующему элементу, «почему»: в приведенном выше коде обратите внимание на то, как выполняется проверка модификации - удаление помещает коллекцию как измененную, а следующая итерация проверяет любые изменения и терпит неудачу, если она обнаруживает изменение коллекции. Еще одна важная вещь: ArrayList
(не уверенный в других сборниках) делает not проверкой на модификацию в hasNext()
.
Поэтому могут произойти две странные вещи:
ArrayList.hasNext()
будет также возвращать false
, потому что итератор current index
теперь указывает на последний элемент (бывший второй по-последнему). Таким образом, даже в этом случае после удаления нет «следующего» элемента Обратите внимание, что все это соответствует документации ArrayList :
Обратите внимание, что неэффективное поведение итератора не может быть гарантировано, поскольку, как правило, невозможно сделать какие-либо серьезные гарантии при наличии несинхронизированной параллельной модификации. Неуправляемые итераторы бросают ConcurrentModificationException с максимальной эффективностью. Поэтому было бы неправильно писать программу, зависящую от этого исключения, за ее правильность: неудачное поведение итераторов должно использоваться только для обнаружения ошибок.
blockquote>Отредактировано для добавления:
Этот вопрос дает некоторую информацию о том, почему проверка параллельной модификации не выполнена в
]hasNext()
и выполняется только вnext()
.
Если вы посмотрите на исходный код для итератора ArrayList
(частный вложенный класс Itr
), вы увидите недостаток в коде.
Код должен быть с ошибкой, быстрый, который делается внутри итератора внутри, вызывая checkForComodification()
, однако hasNext()
не делает этот вызов, вероятно, по соображениям производительности.
Вместо hasNext()
:
public boolean hasNext() {
return cursor != size;
}
Это означает, что когда вы находитесь в элементе second last в списке, а затем удалите элемент (любой элемент), размер уменьшается, а hasNext()
думает, что вы 're на последнем элементе (которого вы не были) и возвращает false
, пропуская итерацию последнего элемента без ошибок.
OOPS !!!!
Из других ответов вы знаете, что является правильным способом удаления элемента в коллекции, когда вы выполняете итерацию коллекции. Я даю здесь объяснение основному вопросу. И ответ на ваш вопрос лежит в следующей трассировке стека
Exception in thread "main" java.util.ConcurrentModificationException
at java.util.ArrayList$Itr.checkForComodification(Unknown Source)
at java.util.ArrayList$Itr.next(Unknown Source)
at com.ii4sm.controller.Evil.removeLalala(Evil.java:23)
at com.ii4sm.controller.Evil.main(Evil.java:17)
В stacktrace очевидно, что строка i.next();
выдает ошибку. Но когда у вас есть только два элемента в коллекции.
Collection<String> c = new ArrayList<String>();
c.add("lalala");
c.add("lalala");
removeLalala(c);
System.err.println(c);
Когда первый удаляется i.hasNext()
возвращает false, а i.next()
никогда не выполняется, чтобы выбросить исключение
вы должны удалить из iterator
(i), а не collection
(c) напрямую;
попробуйте это:
for (Iterator<String> i = c.iterator(); i.hasNext();) {
String s = i.next();
if(s.equals("lalala")) {
i.remove(); //note here, changing c to i with no parameter.
}
}
EDIT:
Причина, по которой первая попытка вызывает исключение, а вторая - нет, просто из-за количества элементов в вашей коллекции.
, поскольку первый из них будет проходить цикл более одного раза и второй - только один раз. поэтому у него нет возможности выбросить исключение
Вы не можете удалить из списка, если вы просматриваете его с циклом «для каждого».
Вы не можете удалить элемент из коллекции, которую вы выполняете. Вы можете обойти это, явно используя Итератор и удалив там элемент. Вы можете использовать Итератор.
Если вы используете код ниже, вы не получите никакого исключения:
private static void removeLalala(Collection<String> c)
{
/*for (Iterator<String> i = c.iterator(); i.hasNext();) {
String s = i.next();
if(s.equals("lalala")) {
c.remove(s);
}
}*/
Iterator<String> it = c.iterator();
while (it.hasNext()) {
String st = it.next();
if (st.equals("lalala")) {
it.remove();
}
}
}