Ответ 1
Не можете ли вы сохранить вещи в jquery.data?
Я планирую иметь некоторые (много) объектов внутри svg-объекта, которые будут сгенерированы с использованием JavaScript.
Пользователь будет выполнять с ними разные действия: щелчок, переключение мыши, выключение мыши. Как только произойдет какое-либо событие, некоторые данные, специфичные для объекта, должны отображаться.
Вопрос: как получить данные об объекте? Например, пользователь нажал на прямоугольник, представляющий автомобиль "Make A" (имеется несколько прямоугольников, каждый из которых представляет отдельный make). Как я могу определить make? Есть ли способ связать "внешние данные" с svg-объектами?
Не можете ли вы сохранить вещи в jquery.data?
Объект Event, который вы получаете в обработчике click/mouseover/etc, имеет свойство target
, которое является элементом (технически любым EventTarget, но в этом случае это элемент), что событие было сначала отправлено.
Один из способов хранения пользовательских данных - использовать атрибуты с расширением имен. Причина, по которой вы должны указывать свои атрибуты, заключается в том, что они могут столкнуться с существующими или будущими атрибутами svg.
Вот пример:
var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
rect.setAttributeNS("http://www.example.com/yourcustomnamespace", "data", "whatever-data-you-want-here");
rect.addEventListener("click", myclickhandler, false);
...
function myclickhandler(evt)
{
var target = evt.target;
// specialcase for use elements
if (target.correspondingUseElement)
target = target.correspondingUseElement;
alert(target);
alert(target.getAttributeNS("http://www.example.com/yourcustomnamespace", "data"))
}
Вы можете сохранить ссылку на объект SVG, созданный в простой переменной javascript. Итак, когда вы создаете фигуру, вы можете сделать это:
myRect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
Теперь у вас есть ссылка на форму объекта SVG. Но если вы хотите сделать их интерактивными, вам просто нужно добавить атрибуты к объекту, подобному этому.
myRect.setAttribute("onclick", "jsFunc()");
где jsFunc() является ранее определенной функцией. Кроме того, чтобы упростить задачу, вы можете настроить события таким образом:
myRect.onclick = function(){jsFunct(this, otherArg);}
Теперь вы можете не только ссылаться на переменную, но и передавать эту переменную непосредственно функции jsFunc, используя такую альтернативу, используя этот указатель.
Если вам нужно создать много прямоугольников, вы можете сохранить их все в одном массиве, так что вы сможете получить доступ к каждому элементу с помощью индекса:
myRect = new Array();
for(i = 1; i <= numMakes; i = i + 1){
myRect[i] = document.createElementNS("http://www.w3.org/2000/svg", "rect");
}
Помните, что для получения свойства или атрибута вашего объекта вы можете использовать функцию getAttribute, например:
fillColor = myRect.getAttribute("fill");
x = myRect.getAttribute("x");
и т.д.
Вы можете создать новый объект типа переменной и установить, что один элемент является формой svg, а остальные члены - ваши настраиваемые поля данных.
var myRect = new Object();
myRect.shape = document.createElementNS("http://www.w3.org/2000/svg", "rect");
myRect.customField = myValue;
Хотя в целом небезопасно предполагать, что возможно расширить родные объекты с помощью свойств js expando, во всех реализациях SVG браузера безопасно хранить данные на узлах SVG DOM с использованием обычных свойств expando, например.
node.myCustomData = "foo"
Обратите внимание, что это не работает в Batik.
Вы можете прочитать эти потоки для получения дополнительной информации:
http://tech.groups.yahoo.com/group/svg-developers/message/64659
http://tech.groups.yahoo.com/group/svg-developers/message/63002
Вы можете хранить свои пользовательские данные в SVG с помощью пользовательских тегов или атрибутов - просто убедитесь, что вы используете свое собственное пространство имен:
Я вижу одно решение: во время заполнения svg-объекта элементами я может генерировать 'id' для каждого элемента так: "makeA", "makeB", "car_id_10", bike_id_20 ",... и т.д. И в слушателе событий я получу идентификатор целевого объекта, перейдя в специальный массив, который будет описывать объекты...
Это хорошая идея? Не уверен...
Элементы DOM могут иметь произвольные объекты, хранящиеся в атрибутах, а не только строки, так как вы можете ввести "нормальный" html-код.
someSVGElement.setAttribute("myApp.car.model", Global.Car.Models.mercedes");
Кроме того, с jquery 3 jquery поддерживает свой метод .data(...) (https://api.jquery.com/jquery.data/) на элементах svg