Нужен совет о лучшем подходе к этой проблеме:
Я безумно влюбился в RaphaëlJS , так как он сделал SVG реализуемым для меня и моего кодирования, поскольку ему удалось привести IE в сгиб.
Однако мне не нравится включать файл .js
для каждого SVG-изображения, которое я хочу отобразить на странице.
Итак, я покопался в интернете, чтобы посмотреть, смогу ли я найти что-то более «динамичное», и нашел это: (ниже моя отредактированная версия кода, которую я нашел здесь: http://groups.google.com/group/raphaeljs/msg/ce59df3d01736a6f)
function parseXML(xml) {
if (window.ActiveXObject && window.GetObject) {
var dom = new ActiveXObject('Microsoft.XMLDOM');
dom.loadXML(xml);
return dom;
}
if (window.DOMParser) {
return new DOMParser().parseFromString(xml, 'text/xml');
throw new Error('No XML parser available');
}
}
(function($) {
$.fn.render_raphaels = function(options) {
var defaults, options, counter, img_path, doc, root, vb, dims, img, node, path, atts, container, new_svg, inline;
defaults = {};
options = $.extend(defaults, options);
counter = 0;
inline = false;
// find all the img's that point to SVGs
$('img[src*="\.svg"]').each(function() {
$(this).fadeOut(1000);
img_path = $(this).attr('src');
if (!$(this).attr('id')) new_svg = true;
if ($(this).hasClass('inline')) inline = true;
container = jQuery('<div/>', {
id: $(this).attr('id') ? $(this).attr('id') : 'svg-' + (counter + 1),
'class': $(this).attr('class') ? $(this).attr('class') : 'svg'
}).hide().insertBefore($(this));
$.get(img_path, null, function(doc) {
doc = parseXML(doc);
root = $(doc).find('svg')[0];
dims = [root.getAttribute('width'), root.getAttribute('height')];
if(new_svg) container.css({ width: dims[0], height: dims[1] });
if(inline) container.css('display', 'inline-block');
img = Raphael(container.attr('id'), parseInt(dims[0]), parseInt(dims[1]));
$(root).find('path').each(function() {
node = this;
path = img.path($(this).attr('d'));
$(['stroke-linejoin','stroke','stroke-miterlimit','stroke-width','fill','stroke-linecap']).each(function() {
if($(node).attr(this.toString())) {
path.attr(this, $(node).attr(this.toString()));
} else {
path.attr(this, 0);
}
});
if($(node).attr('style')) {
atts = $(node).attr('style').split(';');
for(var i=0; i < atts.length; i++) {
bits = atts[i].split(':');
path.attr(bits[0],bits[1]);
}
}
});
}, 'text');
$(this).remove(); // removes the original image after the new one has been redrawn
container.fadeIn(2000);
});
};
})(jQuery);
По сути, это позволяет мне просто написать обычный тег изображения с графикой .svg
, и плагин jQuery автоматически заменит его версией Raphaël-рендеринга.
Это прекрасно работает в браузерах, не поддерживающих SVG, таких как IE, но в современных браузерах, которые фактически уже поддерживают графику SVG, тег изображения работает как есть (без Raphaël), поэтому при загрузке Raphaël он выгружает существующее изображение, затем исчезает в версии Рафаэля ... по сути, создавая мерцание. Я пытался преуменьшить это, выцветая в новой версии, но я все еще сталкиваюсь с проблемой, которую показывает старая, скрытая, а затем снова показанная.
Мне нужен способ согласовать желаемое поведение в проблемных браузерах, таких как IE, и нежелательное поведение в современных, совместимых со стандартами браузерах, таких как Safari 4 и Firefox 3. Но я хочу сделать это таким образом, чтобы я не не нужно существенно менять способ кодирования (почему я в первую очередь использую плагин).
Я знаю, что SVG все еще немного новаторский, но есть ли у кого-нибудь мысли о том, как мне это обойти?
ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Если это вообще возможно, я бы хотел избежать ориентации на браузер ... Я ищу управляемое и функциональное решение рабочего процесса, а не взлом браузера.
2-Й ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я не хочу решение на основе Flash; Я хочу быть настолько «родным», насколько это возможно, и я считаю, что JavaScript намного больше, чем Flash. (Вот почему я так рад за Рафаэля, потому что я могу держаться подальше от Флэша).