Не уверен, что то, что я собираюсь представить, проще, но, похоже, оно затрагивает некоторые ваши проблемы и соответствует моему вкусу.
Основная идея состоит в том, чтобы признать, что проблема сложна из-за нескольких состояний и адресована ей с использованием конечного автомата. Это позволяет декларативный подход, как этот один:
const TRANSITIONS = {
'small-inside' : {
'transitionend' : 'big-inside',
'mouseover' : 'small-inside',
'mouseout' : 'small-outside',
},
'small-outside' : {
'transitionend' : 'small-outside',
'mouseover' : 'small-inside',
'mouseout' : 'small-outside',
},
'big-inside' : {
'transitionend' : 'big-inside',
'mouseover' : 'big-inside',
'mouseout' : 'big-outside',
},
'big-outside' : {
'transitionend' : 'small-outside',
'mouseover' : 'big-inside',
'mouseout' : 'big-outside',
},
}
И довольно простой обработки событий:
function step(e){
box.className = TRANSITIONS[box.className][e.type];
}
box.addEventListener('transitionend', step);
box.addEventListener('mouseover', step);
box.addEventListener('mouseout', step);
Другое понимание, что вы можете указать задержку с помощью CSS transition-delay:3s
свойства:
div.small-inside,
div.big-inside {
width: 300px;
}
div.small-outside,
div.big-outside {
width: 150px;
}
div.big-outside {
transition-delay:3s;
}
Доказательство концепции находится здесь: http://codepen.io/anon/pen/pNNMWM.
Что мне не нравится в моем решении, так это то, что он предполагает, что начальное состояние small-outside
, в то время как на самом деле указатель мыши может быть хорошо расположен в пределах div при загрузке страницы. Вы упомянули способность запускать переходы состояний вручную из JS. Я считаю, что это возможно до тех пор, пока вы отслеживаете две отдельные логические переменные: «есть мышь внутри?» и «спрашивает ли он, что нужно расти?». Вы не можете смешивать их в одно состояние и ожидать правильного «подсчета». Как вы видите, у меня уже есть 2*2=4
, потому что я пытаюсь отслеживать {small,big}x{inside,outside}
- можно предположить, что он расширяет его до {small,big}x{inside,outside}x{js-open,js-close}
аналогичным образом, с некоторыми дополнительными «событиями», такими как «открыть» и «закрыть».
В чем проблемы с кодепином, который вы даете? – Alvaro
1) время перехода как в css, так и в js, что плохо для обслуживания 2) когда коробка сжимается, и вы быстро входите и выходите, это остановит переход в середине - я бы хотел, чтобы ящик продолжал сокращаться, когда вы уходите. – apieceofbart
Я решил это в другом кодефе, но он уродлив и использует setInterval: http: // codepen.io/anon/pen/yVJoZX если у кого-то есть лучшая идея, я бы с удовольствием посмотрел бы его – apieceofbart