Сочетание Raphael и jQuery для достижения совместимости браузера - PullRequest
10 голосов
/ 11 октября 2010

Обнаружив, что IE не обрабатывает javascript onmouseout, я решил вместо этого использовать jQuery, чтобы обеспечить совместимость с различными браузерами.Я делаю область, определенную путем svg, светящейся, когда на нее наведена мышь, и я адаптировал код, предоставленный на веб-сайте Raphael, из примера Австралии .

В этом кодекаждый штат Австралии определяется путем Рафаэля, например, Тасмания:

 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]?И как, черт возьми, я добираюсь до этого?

Ответы [ 5 ]

19 голосов
/ 11 октября 2010

Примечание: Это демо было сделано со старой версией Рафаэля.Теперь у Рафаэля есть свои собственные обработчики событий, включая .mouseover() и .hover().


Сокращение отit:

Просто оберните объект DOM, чтобы сделать из него объект jQuery, или используйте встроенные в Raphael пользовательские обработчики событий:

$(st[0]).mouseover( ... );            // This uses the jQuery .mouseover() method

Или, возможно, более удобно, и поддерживается IE:

$(st[0]).hover( ... );                //     This uses the jQuery .hover() method

Или, используя Метод встроенного обработчика событий Raphael :

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() с элементом Raphael ( протестировано в 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");    
    });
});​

Попробуйте это с помощью jsFiddle

Дополнительно, Raphael .hover()Кажется, что метод работает и в IE.

7 голосов
/ 11 октября 2010

Вам не нужно присваивать ему класс, чтобы открыть его для jQuery.Конечно, нет.Вы можете просто передать свой элемент DOM в jQuery, и он сделает волшебство за вас ...

$(st[0]).mouseout(function() {
  alert("That mouse is outta here!");
};

Вы видите синтаксис массива, потому что библиотеки Javascript обычно поддерживают ссылку на исходный элемент (по сути, просто «оборачивая» его и добавляя функциональность).Объяснение псевдокода ...

st == Raphael element
st[0] == DOM element
5 голосов
/ 02 марта 2011

Если в итоге вы просто скопируете код, который используется в демонстрационной программе Australia, вы столкнетесь с проблемами IE независимо от того, какой обработчик (hover, mouseover и т. Д.) Вы используете.

После некоторого стука головы мне кажется, что st.toFront () в функциях hover in / out отменяет событие "mouse out" в IE. Удалите эти строки из примера кода, и все будет в порядке.

1 голос
/ 14 марта 2013

В моем случае реальная проблема заключалась в вызове .toFront каждую чертову миллисекунду, потому что .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) { }
);
1 голос
/ 11 октября 2010

Это немного хитрости javascript, передается st. Посмотрите на код JS в примере с australia.

(function (st, state) {
                    .. some code referring to st[0] in here .. 
                })(aus[state], state);

Так st [0] в этом коде относится к узлу DOM пути из aus [state] .

Попробуйте сами с этим простым примером в консоли Firebug:

(function(a,b) {alert(a); })("hello", "b");

НТН

...