L’utilisation du tag de base sur une page contenant des éléments de marqueur SVG ne permet pas de rendre le marqueur

J’ai rencontré un problème en essayant d’utiliser des éléments de marqueur SVG dans une visualisation basée sur SVG. J’ajoute mes modifications à une application Web qui inclut une balise de base sur chaque page, de sorte que toute référence à des fichiers CSS, des fichiers javascript, etc. peut être relative.

J’ai un exemple de code ci-dessous qui reproduit le problème. Il y a un élément de ligne et un élément de marqueur défini. L’élément marqueur est référencé par la ligne dans son atsortingbut ‘marker-end’, via uri et id du marqueur. Sans la balise de base, la flèche s’affiche correctement. Avec l’étiquette de base, elle n’est pas affichée. La raison en est que la balise de base modifie la façon dont le navigateur résout les URL .. même pour l’URL simple basée sur l’ID spécifiée dans l’atsortingbut marqueur de fin de ligne.

Est-il possible de contourner ce problème sans avoir à supprimer l’étiquette de base?

Je ne peux pas vraiment l’enlever car son utilisation est assez ancrée dans le produit sur lequel je travaille. Je dois prendre en charge Firefox, Chrome et IE9 + pour mon application Web. Firefox et Chrome produisent tous deux ce problème. IE fonctionne très bien (c.-à-d. Les marqueurs de flèche).

    .link { stroke: #999; stroke-opacity: .6; } marker#arrow { fill: black; }              

L’ élément HTML est utilisé pour dire “résoudre toutes les URL relatives relatives à cette page, mais à un nouvel emplacement”. Dans votre cas, vous lui avez demandé de résoudre le problème relatif au répertoire contenant la page HTML.

L’atsortingbut SVG marker-mid="url(…)" est une référence FuncIRI . Lorsque vous utilisez une valeur comme url(#foo) cette IRI relative est normalement résolue par rapport à la page en cours, trouvant l’élément avec l’identifiant foo . Mais, lorsque vous utilisez , vous changez d’emplacement.

Pour résoudre ce problème, utilisez une meilleure valeur. Comme votre référence de base est le répertoire en cours, vous pouvez simplement utiliser le nom du fichier en cours:

  

Si vous avez un href différent de celui que vous avez montré, par exemple:

  

alors vous devrez utiliser un href absolu, par exemple

  

Dans le contexte d’une application Web riche telle que celle créée sur Angular, où vous devez définir la pour que le fonctionnement de la navigation de style HTML5 fonctionne, il peut être compliqué d’essayer de résoudre ce problème de manière permanente.

Dans mon cas, l’application sur laquelle je travaillais montrait un générateur de diagramme interactif basé sur SVG qui modifierait l’URL de l’application lorsque je sélectionnais des éléments.

Ce que j’ai fait a été d’append un gestionnaire d’événement global qui corrigerait tous les styles en ligne url(#...) dans tout élément de la page:

 $rootScope.$on 'fixSVGReference', -> $('path').each -> $path = $ this if (style = $path.attr 'style')? $path.attr 'style', style.replace /url\([^)#]*#/g, "url(#{location.href}\#" 

Ensuite, déclenchez ce gestionnaire à des endroits clés, comme lorsque l’état de l’application change (j’utilise un ui-router )

 $rootScope.$on '$stateChangeSuccess', -> $timeout (-> $rootScope.$emit 'fixSVGReference'), 5 

De même que partout où je sais, il y aurait des chemins nouveaux / mis à jour comme ceux-ci. Ici, la $timeout est due au fait que les noeuds DOM sont réellement modifiés de façon asynchrone après le déclenchement de l’événement $stateChangeSuccess .

Essayez avec javascript:

  

Avec natif:

 document.getElementById('something').setAtsortingbute('marker-mid', 'url(' + location.href + '#arrow)'); 

Avec jQuery:

 $('#something').attr('marker-mid', 'url(' + location.href + '#arrow)'); 

Cela fonctionne juste.

Dans Angular 2+, vous pouvez injecter le chemin de base dans votre module d’application au lieu d’utiliser la balise . Cela a résolu le problème dans Edge et Firefox pour moi.

 import { APP_BASE_HREF } from '@angular/common'; @NgModule({ providers: [{ provide: APP_BASE_HREF, useValue: '/' }] }) export class AppModule { } 

https://angular.io/docs/ts/latest/api/common/index/APP_BASE_HREF-let.html

Si vous ne voulez pas modifier / animer le svg, il existe une solution plus simple que de changer le paramètre url() .

Inclure le svg comme image:

  

Ember 2.7 remplacera la par rootURL qui devrait résoudre ce problème.

En attendant, dans mon d3 pour les dégradés, j’utilise les éléments suivants:

.attr('fill', `url(${Ember.$(location).attr('href')}#my-gradient)`);

Si vous ne le faites pas, l’élément que vous ciblez semblera transparent.

Sur Windows actuellement (04-2017), tous les navigateurs se comportent comme prévu ( mask = url (“# svgmask”) ). Chrome, Firefox, même IE 11 !! – mais Edge présente une erreur.

Ainsi, pour Microsoft Edge, vous devez toujours indiquer le chemin absolu ( mask = “url (path / to / this-document.htm # svgmask)” ) pour vos ID de masque lorsque vous utilisez une balise de base dans votre document: