Объединение Raphael и jQuery для обеспечения совместимости с браузером
Обнаружив, что IE не обрабатывает javascript onmouseout
, я решил использовать jQuery, чтобы обеспечить совместимость кросс-браузера автоматически. Я делаю область, определенную путём svg, загорается, когда мышь нависает над ней, и я адаптировал код, представленный на веб-сайте Рафаэля, из примера Австралия.
В этом коде каждое состояние Австралии определяется путем Рафаэля, например Tasmania:
aus.tas = R.path("...").attr(attr);
Этот путь ('st') затем передается функции:
st[0].onmouseover = function () {
...
};
В отличие от того, что я ожидал бы, код st[0].onmouseover
, а не просто st.onmouseover
. Таким образом, путь должен быть массивом, а st[0]
, что бы это ни было, - это то, что зависает.
Чтобы заменить onmouseover
эквивалентом jQuery (который я считаю .mouseout()
), мне нужно назначить класс st[0]
, чтобы я мог ссылаться на него с помощью jQuery. Мой вопрос: как мне это сделать? Если код был st.onmouseover
, это было бы просто, но почему путь (st
) - массив? Что такое st[0]
? И как, черт возьми, я добираюсь до него?
Ответы
Ответ 1
Примечание. Это демо было сделано со старой версией Рафаэля. Теперь у Raphael есть свои собственные обработчики событий, в том числе .mouseover()
и .hover()
.
Короче:
Просто оберните объект DOM, чтобы сделать из него объект jQuery, или используйте Raphael, встроенный в пользовательские обработчики событий:
$(st[0]).mouseover( ... ); // This uses the jQuery .mouseover() method
Или, возможно, более удобный и поддерживаемый IE:
$(st[0]).hover( ... ); // This uses the jQuery .hover() method
Или, используя Рафаэль, встроенный в метод обработчика событий:
st.mouseover( ... ); // This uses the Raphael .mouseover() method
st.hover( ... ); // This uses the Raphael .hover() method
Долгое время:
Вы можете получить ссылку на объект DOM для работы с node
или [0]
, так как RaphaelObject[0]
всегда является ссылкой на элемент DOM:
aus.tas = R.path("...").attr(attr);
// aus.tas is a Raphael object
// aus.tas[0] is aus.tas.node is the reference to the DOM Object
$(aus.tas[0]).mouseover(function() { // Could have also use aus.tas.node
...
});
// Raphael now has custom event handlers
aus.tas.mouseover(function() {
...
});
aus.tas.hover(function() {
...
}, function() {
...
});
Итак, с вами функция:
(function (st, state) {
// st is a Raphael Object
// st[0] is st.node is the reference to the DOM Object
// This is now using jQuery for mouseover!
$(st[0]).mouseover(function() {
...
});
...
})(aus[state], state);
Кроме того, я бы предложил заглянуть в функцию jQuery .hover()
, которая отлично справляется с IE:
(function (st, state) {
// This is now using jQuery not Raphael for hover!
$(st[0]).hover(function() {
... // the mouseenter function
}, function() {
... // the mouseleave function
});
...
})(aus[state], state);
Как упрощенная демонстрация, вот как привязать mouseenter
и mouseout
с помощью .hover()
к элементу Рафаэля (проверенному в IE 8):
$(function() {
var elie, paper = Raphael("canvas", 500, 500);
// Create Raphael element
elie = paper.rect(0,0,100,100).attr("fill","#000");
// Get reference to DOM object using .node and bind
// mouseover and mouseout to it:
$(elie[0]).hover(function() {
elie.attr("fill","#FFF");
},function() {
elie.attr("fill","#000");
});
});
Кроме того, метод Raphael .hover()
, похоже, работает и в IE.
Ответ 2
Вам не нужно назначать ему класс, чтобы выставить его в jQuery. Конечно нет. Вы можете просто передать свой элемент DOM в jQuery, и он сделает магию для вас...
$(st[0]).mouseout(function() {
alert("That mouse is outta here!");
};
Вы видите синтаксис массива, потому что, как правило, библиотеки Javascript поддерживают ссылку на исходный элемент (по сути, просто "обертывая" его и добавляя функциональность). Объяснение псевдокода...
st == Raphael element
st[0] == DOM element
Ответ 3
Если вы просто скопируете код, используемый демоверсией в Австралии, вы столкнетесь с проблемой IE, независимо от того, какой обработчик (наведение, наведение мыши и т.д.) вы используете.
После того, как я немного наткнулся на него, кажется, что функция st.toFront() в функции ввода/вывода отменяет событие "мыши" в IE. Удалите эти строки из кода примера, и все должно быть в порядке.
Ответ 4
Это немного обмана javascript, st передается. Посмотрите на JS-код в примере australia.
(function (st, state) {
.. some code referring to st[0] in here ..
})(aus[state], state);
Итак, st [0] в этом коде ссылается на путь DOM node из aus [state].
Попробуйте сами, используя этот простой пример в консоли Firebug:
(function(a,b) {alert(a); })("hello", "b");
HTH
Ответ 5
В моем случае, фактическая проблема заключалась в вызове .toFront для каждого freakin millisecond, потому что .hover(fooFunction, outFunction) вызывает fooFunction с каждым сдвигом курсора мыши. На самом деле, имя вполне предполагает, что это вызов наведения, а не центр мыши:)
Итак, трюк заключается в том, чтобы убедиться, что ваш fooFunction или его содержимое выполняется только один раз (onmouseenter). Даже в IE это отлично работает для меня, без доступа к каким-либо узлам DOM или к доступу к другим материалам, которые я не хочу касаться:
var MouseEventHelper = {
hover: function (el, funcIn, funcOut) {
var entered = false;
el.hover(
function (e) {
if (entered) {
return;
}
funcIn(e);
entered = true;
},
function (e) {
funcOut(e);
entered = false;
}
);
}
}
Затем замените ваши зависающие вызовы следующим образом:
var el = paper.rect(...);
MouseEventHelper.hover(
el,
function (e) {
// do whatever you want!
el.toFront();
}
function (e) { }
);