#javascript #jquery
#javascript #jquery
Вопрос:
У меня есть 9 изображений, расположенных в 3 ряда. В каждой строке по 3 изображения. Все изображения разного размера. При наведении курсора я увеличиваю ширину и высоту изображения до 400px и 300px соответственно, а при наведении курсора мыши я восстанавливаю их первоначальный размер. Теперь проблема в том, что при случайном наведении курсора всплывают изображения, но некоторые из них не возвращаются к своему первоначальному размеру. Как мне это исправить? Пожалуйста, помогите.
Мой код:
jQuery(document).ready(function() {
jQuery('my-selector').hover(function() {
var someVariable = jQuery( 'my-selector img', this );
someVariable.attr('actualWidth', someVariable.width());
someVariable.attr('actualHeight', someVariable.height());
jQuery('my-selector').stop()
.animate({
width: "400px",
height: "300px"
}, 200, function() {
// Animation complete.
jQuery('show-some-div').show();
});
},
function() {
jQuery('my-selector').stop()
.animate({
width: someVariable.attr('actualWidth'),
height: someVariable.attr('actualHeight')}, 200, function() {
// Animation complete.
jQuery('show-some-div').hide();
});
Ответ №1:
На самом деле здесь есть три потенциальные проблемы, которые я замечаю.
Первое заключается в том, что вы как бы невнятно повторно выбираете свои элементы при срабатывании события. Это означает, что, хотя запускается только одно из ваших изображений, вы выполняете различные действия со всеми из них, или же вам приходится выполнять некоторую гимнастику, чтобы вернуться к тому, с чем на самом деле взаимодействовал пользователь.
Что может помочь вам с этой проблемой, так это тот факт, что при обратном вызове события jQuery контекстная ссылочная переменная this
будет указывать на html-элемент, на который ссылается событие. Это означает, что вместо выполнения
var someVariable = jQuery('my-selector img', this);
вы можете сделать
var someVariable = jQuery(this);
и это будет объект jQuery, который указывает на html-элемент, который вызвал событие. Мне нравится придерживаться соглашения, по которому объекты jQuery начинаются с $, поэтому я обычно делаю что-то вроде
var $this = $(this);
В любом случае, теперь, когда у вас определенно есть ссылка на элемент, который фактически вызвал событие mouseover
or mouseout
, вы можете использовать его для выполнения своих действий (я пока остановлюсь на некоторых переменных):
someVariable.stop().animate({ ... });
Вторая проблема заключается в том, что вы как бы путаетесь с DOM, когда начинаете attr
добавлять случайные атрибуты к элементам HTML. actualWidth
не является реальным атрибутом HTML, и некоторые браузеры отнесутся к этому факту более благосклонно, чем другие. К счастью, jQuery предоставляет способ сохранения переменных, которые связаны с некоторым конкретным элементом HTML. Просто используйте .data
, а не .attr
точно так, как вы уже используете .attr
, и он сохранит нужные вам данные:
someVariable.data('actualWidth', someVariable.width()); // sets actualWidth
// ... some time later ....
var someOtherVariable = someVariable.data('actualWidth'); // gets actualWidth
Третья проблема, которую я вижу здесь, заключается в следующем: что произойдет, если кто-то наведет курсор мыши на ваш элемент, но прежде чем он вернется к своему естественному размеру, он снова включит мышь? Теперь вы измеряете изображение до того, как оно уменьшится до его actualSize
размера, и называете это его actualSize
. Чтобы решить эту проблему, просто измерьте их actualSize
размеры по мере загрузки каждого из них (вы не хотите этого делать, page load
потому что изображения могут еще не быть загружены, вы хотите выполнить load
событие для каждого изображения, и каждое изображение запустит свое load
событие при загрузке и изменении размера):
jQuery('my-selector img').load(function()
{
var someVariable = jQuery(this);
someVariable.data('actualWidth', someVariable.width());
someVariable.data('actualHeight', someVariable.height());
});
Теперь, когда вы измерили каждое изображение и сохранили то, что действительно соответствует его размеру, вам не нужно выполнять эту работу каждый раз при mouseover
; просто разверните изображение до 400×300 вкл mouseover
, не заботясь об этом, а затем вернитесь к сохраненному выкл actualWidth
и actualHeight
при наведении курсора мыши.
Между этими тремя проблемами ваша проблема должна быть решена.
Комментарии:
1. или, возможно, используйте queue false в конце .animate может быть аккуратным? Или?
2. 1, отличный ответ. Я бы также проверил, установлено ли значение
actualWidth
иactualHeight
, прежде чем выполнять какое-либо изменение размера при наведении.3. Отличный результат анализа. Я попробую все эти вещи и дам вам знать.
4. Спасибо за ваше предложение, Клинт, это действительно очень помогло мне выяснить, в чем проблема. Я нашел что-то под названием hoverIntent (плагин). Теперь то, что он делает, это выводит изображение, только если вы наведете курсор на 1 или 2 секунды. Поэтому, даже если я случайным образом наведу курсор на изображения, ни одно из изображений не всплывает.. Это решает мою проблему