Вопрос по svg, javascript, jquery – Динамическое добавление SVG-градиента

8

У меня есть этот SVG-контейнер с путями. Я хочу отредактировать его, поэтому пути & apos; заполнить будет шаблон. Это моя неудачная попытка:

Я добавляю градиент:

$('svg defs').prepend('<linearGradient id="MyGradient"><stop offset="5%" stop-color="#F60" /><stop offset="95%" stop-color="#FF6" /></linearGradient>');

И затем измените пути & apos; заполнить:

$(base + ' svg path').each(function() {
    this.setAttribute('fill','url(#MyGradient)')
}

Это не работает. Что мне не хватает?

Ваш Ответ

4   ответа
3

Нашел решение. Это немного некрасиво, но не требует использования дополнительных плагинов.

Очевидно, что шаблон должен быть включен в тег при первом создании SVG (он, вероятно, только тогда читается).

Таким образом, замена содержимого оболочки SVG-тега на самих себя работает (base Быть той оберткой)

$(base).html($(base).html())
Error: User Rate Limit Exceeded<svg xmlns="…">Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededbase = $('#embed_container_id')Error: User Rate Limit Exceeded
3

Я думаю, вам придется использовать плагин SVG для jQuery (найденоВот). При добавлении SVG-элементов используется «обычный» Библиотека jQuery, возможно, пространства имен перепутаны.

Попробуйте следующее:

svg.linearGradient( $('svg defs'), 
                    'MyGradient', 
                    [ ['5%', '#F60'], ['95%', '#FF6']] );

(Однако не совсем уверен. Возможно, вам придется немного поиграться с этим кодом.)

EDIT

Только что создал этоиграть на скрипке чтобы проверить тезис (как предложено @Phrogz). Действительно возвращаетсяhttp://www.w3.org/1999/xhtml в качестве пространства имен для вставленного<linearGradient>, что является неправильным пространством имен и, следовательно, подтверждает мои предположения.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededconsole.log($('#MyGradient')[0].namespaceURI)Error: User Rate Limit Exceededhttp://www.w3.org/2000/svgError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
21

Ваша проблема (что вам «не хватает») заключается в том, что jQuery создает новые элементы в пространстве имен XHTML, в то время как элементы SVG должны создаваться в пространстве имен SVG. Вы не можете использовать необработанный код в строке для элементов SVG.

Самый простой (без плагинов) метод - перестать так сильно полагаться на jQuery и просто использовать простые методы DOM для создания элементов. Да, это более многословно, чем просто использование jQuery для магического конструирования ваших элементов ... но в этом случае jQuery не работает.

Demo: http://jsfiddle.net/nra29/2/

createGradient($('svg')[0],'MyGradient',[
  {offset:'5%', 'stop-color':'#f60'},
  {offset:'95%','stop-color':'#ff6'}
]);
$('svg path').attr('fill','url(#MyGradient)');

// svg:   the owning <svg> element
// id:    an id="..." attribute for the gradient
// stops: an array of objects with <stop> attributes
function createGradient(svg,id,stops){
  var svgNS = svg.namespaceURI;
  var grad  = document.createElementNS(svgNS,'linearGradient');
  grad.setAttribute('id',id);
  for (var i=0;i<stops.length;i++){
    var attrs = stops[i];
    var stop = document.createElementNS(svgNS,'stop');
    for (var attr in attrs){
      if (attrs.hasOwnProperty(attr)) stop.setAttribute(attr,attrs[attr]);
    }
    grad.appendChild(stop);
  }

  var defs = svg.querySelector('defs') ||
      svg.insertBefore( document.createElementNS(svgNS,'defs'), svg.firstChild);
  return defs.appendChild(grad);
}

Using a Library

Кроме того, вы можете включитьКит Вудс & apos; & quot; jQuery SVG & quot; плагин у этого есть много удобных методов для общих операций SVG, включая способностьсоздавать линейные градиенты.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit ExceededlessError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
3

Я просто хочу зайти и сказать, что нашел более элегантное решение, которое позволяет вам продолжать использовать jQuery с элементами SVG, но без библиотеки jQuery SVG (которая больше не обновляется и имеет некоторые проблемы с jQuery 1.8 или выше). Просто используйте функцию, подобную этой:

createSVGElement= function(element) {
    return $(document.createElementNS('http://www.w3.org/2000/svg', element));
}
<,/code>

он создает элемент SVG в пространстве имен SVG и инкапсулирует его с помощью jQuery, после того как элемент создан в нужном пространстве имен, вы можете свободно использовать его с jQuery:

Затем вы можете использовать функцию следующим образом:

var $myGradient= createSVGElement('linearGradient')
    .attr( {
        id:"MyGradient"
    });

//if you dont need `defs`, skip this next line
var $myDefs = createSVGElement('defs');

createSVGElement('stop')
    .attr({
        offset: "5%",
        "stop-color": "#F60"
    })
    .appendTo($myGradient);


createSVGElement('stop')
    .attr({
        offset:"95%",
        "stop-color":"#FF6"
    })
    .appendTo($myGradient);

//Use this if you already have `defs`
$('svg defs').prepend($myGradient);

//Use this if you dont have `defs`
$('svg').prepend($myDefs);
$('svg defs').prepend($myGradient);

Это не так компактно, как хотелось бы, поскольку вы должны создавать каждый элемент вручную, но это намного лучше, чем манипулировать всем с помощью методов DOM.

Небольшое примечание, функция jQuery .attr () предполагает, что все атрибуты в нижнем регистре, что не относится к элементам SVG (например,viewBox приписывать<svg> теги). Чтобы обойти это, при установке атрибутов с заглавными буквами используйте что-то вроде этого:

$("svg")[0].setAttribute("viewBox", "0 0 1000 1000");
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded

Похожие вопросы