Может ли Prototype расширять элементы SVG? - PullRequest
12 голосов
/ 04 февраля 2012

Я пытаюсь разработать интерактивную карту SVG и не могу заставить Prototype расширять встроенные элементы SVG.Вот мой пример кода (данные пути удалены, потому что он огромен):

<svg id="map" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="330" height="500" viewBox="-16037,-19651 28871,44234">
    <g id="state_outline">
        <path id="state" fill="white" stroke-width="200" d="..." />
        <path id="water" fill="#a0a0ff" d="..." />
    </g>
    <g id="counties">
        <path class="county" id="adams" d="..." />
        ...
    </g>
</svg>

<div id="nottamap"></div>       

<script type="text/javascript">
    console.log($('nottamap'));
    console.log($('nottamap').identify());
    console.log($('counties'));
    console.log($('counties').identify());
</script>

Результат выполнения:

<div id="nottamap">
nottamap
<g id="counties">
$("counties").identify is not a function

$ () просто отказывается расширять передаваемый элементэто, если это часть элемента SVG.Есть ли что-то во взаимодействии Prototype с элементами XML, которое я не понимаю, или есть лучший способ для меня?

Ответы [ 2 ]

10 голосов
/ 04 февраля 2012

Прототип увеличивает элементы с помощью метода Element.addMethods. Если вы посмотрите на исходный код , вы увидите следующую часть:

var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
  Element.prototype;

if (F.ElementExtensions) {
  copy(Element.Methods, elementPrototype);
  copy(Element.Methods.Simulated, elementPrototype, true);
}

Здесь предпочтение отдается HTMLElement.prototype, которые SVG-элементы не наследуют. Он возвращается к Element.prototype в тех браузерах ( кашель IE кашель ), которые также не поддерживают SVG. Вы можете редактировать исходный код напрямую и копировать все действия копирования на SVGElement.


Это звучит как большая работа, когда вы понимаете, что можно использовать более простой взлом. Статические методы Element.* по-прежнему работают при непосредственном использовании. Вместо $('counties').identify() используйте Element.identify('counties'). Где вы можете сделать что-то вроде этого:

$$('.classname').invoke('hide');

Вы можете принять хороший функциональный эквивалент:

$$('.classname').each(Element.hide);
// or replace Element.hide with Effect.fade or any other effect

Недостатком является то, что вы теряете способность использовать метод цепочки.

6 голосов
/ 02 ноября 2012
Предложение

clockworkgeek об изменении исходного кода прототипа мне очень помогло.В прототипе v. 1.7 все, что нужно, это изменить соответствующую часть на

var elementPrototype = window.HTMLElement ? HTMLElement.prototype :
  Element.prototype;

if (F.ElementExtensions) {
  if (window.SVGElement) {
    copy(Element.Methods, SVGElement.prototype);
    copy(Element.Methods.Simulated, SVGElement.prototype, true);
  }
  copy(Element.Methods, elementPrototype);
  copy(Element.Methods.Simulated, elementPrototype, true);
}

В прототипе v. 1.7.1 необходимые изменения:

var ELEMENT_PROTOTYPE = window.HTMLElement ? HTMLElement.prototype :
  Element.prototype;

if (F.ElementExtensions) {
  if (window.SVGElement) {
    mergeMethods(SVGElement.prototype, Element.Methods);
    mergeMethods(SVGElement.prototype, Element.Methods.Simulated, true);
  }
  mergeMethods(ELEMENT_PROTOTYPE, Element.Methods);
  mergeMethods(ELEMENT_PROTOTYPE, Element.Methods.Simulated, true);
}

Я нашелготовое решение в этом блоге

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...