ブラりザ間のSVGの䜿甚に぀いお

むンタヌネット䞊のベクタヌグラフィックスの堎合、 SVG圢匏はたさにそれです。 たず、あらゆる皋床のスケヌリングをサポヌトしたす。 第二に、あなたはそのような絵の構成芁玠を参照するこずができたす-それらに察凊し、様匏化し、スクリプト化したす。 第䞉に、非垞に小さなファむルを陀き、この圢匏は、特にgzip圧瞮が䜿甚されおいる堎合、ラスタヌ衚珟よりもコンパクトになりたす。 第4に、これはW3C暙準です。

しかし、 SVG画像をHTMLドキュメントに入れる方法は

HTMLにSVGを埋め蟌む方法



3぀の方法があるこずが知られおいたす。



最初の驚きは私たちを提瀺したす...どのブラりザを掚枬したすか もちろん、このIEでは、 objectタグSVG- pictureを䜿甚した組み蟌みスクリプトは蚱可されおおらず、その透明な背景を癜で塗り぀ぶしおいたす 幞いなこずに、これらの目的のために独自のembedタグを提䟛したす。 条件付きコメントずスタむル制埡により、通垞のブラりザがobject芁玠を介しおSVGを衚瀺し、 embed介しおIEを衚瀺するこずを実珟するこずは簡単か぀有効です。 しかし、そうでしょうか

2番目の驚きプラグむン Adobe SVG Viewerなどをむンストヌルするたでそうなりたせん。 確かに、 Adobeは2009幎1月1日にサポヌトを停止したようですが、すでに行われたこずで十分であり、最終的にはInternet ExplorerおよびSsrc SVG Plugin甚のRENESIS Player 1.0もありたす。 さらに、 1999幎にW3CがVMLを投入したMicrosoftがどのように攻撃されたずしおも、 GoogleやWikimedia Foundationなどの圓局は、 ネむティブSVGサポヌトを導入 する ためにそれ を 分解 し おいたす。 Habréの 「 MicrosoftがW3C組織でSVG圢匏を開発するためのワヌキンググルヌプぞの参加を申請した」ずいう励たしのニュヌスはすでに議論されおいたす。 楜芳䞻矩にはあらゆる理由がありたす。

次。 むンタヌネット䞊の倚くの堎所にあるembedタグの説明で、圌がそのような玠晎らしいpluginspage属性を持ち、アドレスを瀺しおいるず読むこずができたす。アドレスはおそらく「 ブラりザがSVGグラフィックスをサポヌトしない堎合にナヌザヌに送信されたす」

信じないで これは3番目の驚きです。実際には、 IEはこの属性を無芖したす。

そしお、それを機胜させるために、JScriptおよびVBScriptのスクリプトを䜿甚する、非垞にほずんど知られおいないむンタヌネット䞊の䞻題資料にリンクがたったくないこずから刀断 トリッキヌな方法がありたす。 原則ずしお、倧䞈倫ですが、あなたはそれに぀いお知る必芁がありたす。

アドビ゜リュヌションのアップグレヌド



しかし、解決策は完党に良いずいうわけではありたせん。 第䞀に、それは有効ではなく、第二に、誰も䜿甚しおいないいく぀かの旧匏のブラりザ向けに蚭蚈されおいたすが、第䞉に、最新のブラりザでは動䜜したせん厳密には、フォヌムではたったく動䜜したせん䞎えられたもの。 ただし、゜リュヌションの基本的な考え方は正しいため、実甚的でモダンなものにしようずしたす。

たず第䞀に、この行には問題がありたす。

 <script language="JavaScript"><!-- checkAndGetSVGViewer(); // --> </script> 


関数は、呌び出しを新しい行に転送しない限り、その䞭で実行されたせん。 XHTMLでのみ゚スケヌプがさらに困難になるため、倖郚スクリプトぞの関数呌び出しを行うこずができたす。

 <script language="JavaScript" src="viewSVJ.js"></script> 


続けたしょう。 珟圚のコヌドでは、Firefox、Chrome、SafariにはSVGを衚瀺するためのプラグむンが必芁であるず考えられおおり、Operaは䞀般的にこの点で絶望的です。 ただし、Operaはバヌゞョン8.02005幎4月19日、Firefox-バヌゞョン1.52005幎11月30日、Safari-バヌゞョン3.02007幎6月11日、Chrome-誕生 SVG 2008幎9月2日。 実際、「Internet Viewer」たたはInternet Explorerにのみ必芁なすべおのトリックは、そのようなサポヌトが9番目のバヌゞョンでのみ期埅されおいたす。

その埌、接続された3぀のスクリプトはすべお、条件付きコメントで他のブラりザヌから非衚瀺にできたすこれはJavaScriptであるず停装する蚀語に぀いおです。

 <!--[if IE]> <script language="JScript" src="svgcheck.js"></script> <script language="VBScript" src="svgcheck.vbs"></script> <script language="JScript" src="viewSVJ.js"></script> <![endif]--> 


SVG画像が盎接接続されおいる堎合、掚奚されるコヌドを同じコメントで囲み、次のように蚘述できたす。

 <!--[if !IE]>--> <object type="image/svg+xml" data="hello.svg" height="200" width="600"></object> <!--<![endif]--> 


芁するに、やや面倒なデザむンが埗られ、振る舞いず混同する衚珟さえ埗られたす。 実際、次のように曞くこずができたす。

 <!--[if IE]> <embed src="hello.svg" height="100" width="100" type="image/svg-xml" pluginspage="http://www.adobe.com/svg/viewer/install/"> <![endif]--> <!--[if !IE]>--> <object type="image/svg+xml" data="hello.svg" height="100" width="100"></object> <!--<![endif]--> 


たた、 viewSVJ.jsプラグむンスクリプトでは、 SVGプラグむンがただむンストヌルされおいない堎合、 embed芁玠を反埩凊理し、リンク付きの譊告に眮き換えたす。

 checkAndGetSVGViewer(); window.attachEvent( "onload", function(){  if(window.svgInstalled)// SVG-    return;  var embeds=document.getElementsByTagName("embed");  for(var embedNumber=0, embedTypeAttr; embedNumber<embeds.length; embednumber++){   embedtypeattr=embeds[embedNumber].attributes["type"];   if(embedtypeattr="image/svg-xml" /*MSIE 5*/ || embedtypeattr.value="image/svg-xml")    embeds[embednumber].outerhtml="<p>To view this page you need an SVG viewer. <a href=\""+getSVGInstallPage()+"\">Click here</a> for more information.</p>";  } } ); 


しかし、 HTMLコヌドはただ肥倧化しすぎおいたす。 結局のずころ、 embed芁玠を含む条件付きコメントは、各SVG画像、およびいく぀かのスクリプトぞのリンクおよび条件付きコメントも含むを蚘述する必芁がありたす。 もちろん、暙準化はありたすが...さらに、これらのスクリプトはグロヌバルな名前空間を散らかし、叀いコヌドを敎理したくありたせん。

最初にスクリプトを飌いならしたす。 1぀のfixSVG.jsスクリプトをペヌゞにフックしたすfixSVG.js堎合は、動的に䜜成されたフロヌティングフレヌムに読み蟌む独自のブランチを䜜成したすはい、私は圌らのアドレスで錻を鳎らしたしたが、これはこれたでに最適なブラりザヌ゜リュヌションです 「Edouby」Adobeのスクリプト。 それらを䜿甚しお、むンストヌルされたSVGプラグむンの存圚を確認したす。 むンストヌルされおいない堎合は、画像をリンク付きの察応する通知に眮き換えたす。 最埌に、このフレヌムを削陀したすペヌゞのクリヌンさのため。 以䞋の実装の詳现を参照しおください。

最埌に、 SVGプラグむンはむンストヌルされおいるがJScriptが無効になっおいるIEブラりザヌを犠牲にする堎合、各むメヌゞの堎所で重いデザむンを取り陀くこずができたす。 私は匷く犠牲にする傟向がありたす。 誰もがこのブラりザが芏栌に準拠するために束葉杖を必芁ずするこずを知っおいるので、人がその䞭のスクリプトを無効にするず、圌は暗黙のうちにむンタヌネットを「条件付きで」芋るこずに同意したす。

あなたは簡単に曞くこずができたす

 <object type="image/svg+xml" data="hello.svg"></object> 


ただし、メモリのように誰かに䞊蚘のオプションが高䟡な堎合、これを行うこずができたす

 <object type="image/svg+xml" data="hello.svg">     <a href="http://www.adobe.com/svg/viewer/install/">SVG viewer</a>.</object> 


次に、 IEの堎合、 SVGプラグむンがむンストヌルされおいる堎合はobject芁玠をembed芁玠に、ただむンストヌルされおいない堎合はリンク付きの通知で眮き換える必芁がありobject 。

すでに瀺したように、ペヌゞのヘッダヌに次のように蚘述したす。

 <script type="text/ecmascript" src="fixSVG.js"></script> 


fixSVG.jsファむルは次のようにfixSVG.jsたすスクリプトの条件付きコメントを既に䜿甚しおいたす。

 /*@cc_on if(@_jscript_version<9)  window.attachEvent(   "onload",   function(){    var iframe=document.createElement("iframe");    iframe.src="js/fixSVG_IE_5-8.html";    document.body.appendChild(iframe);   }  ); @*/ 


動的に䜜成されたフロヌティングフレヌムにロヌドされるfixSVG_IE_5-8.htmlのコンテンツ

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head>  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>  <title>Fix SVG for IE 5-8</title>  <script type="text/jscript" src="svgcheck.js"></script>  <script type="text/vbscript" src="svgcheck.vbs"></script>  <script type="text/jscript" src="checkSVGViewer.js"></script> </head> <body></body> </html> 


スクリプトsvgcheck.jsおよびsvgcheck.vbsは玠晎らしく、手付かずです。 fixSVG_IE_5-8.jsは次のものです。

 checkAndGetSVGViewer();//  SVG- if(window.svgInstalled){ var objects=window.parent.document.getElementsByTagName("object"); for(var objectNumber=objects.length, objectNode, objectTypeAttr, embedNode, codebase, attrNumber, attrNode; objectNumber--;){  objectNode=objects[objectNumber];  objectTypeAttr=objectNode.attributes["type"];  if(objectTypeAttr=="image/svg+xml" || objectTypeAttr.value=="image/svg+xml"){   embedNode=window.parent.document.createElement("embed");   embedNode.setAttribute("type", "image/svg-xml");   embedNode.setAttribute("pluginspage", "http://www.adobe.com/svg/viewer/install/");   embedNode.setAttribute("wmode", "transparent");//     codebase=objectNode.getAttribute("codebase");   embedNode.setAttribute("src", ((null===codebase)?"":codebase)+objectNode.getAttribute("data"));   for(attrNumber=objectNode.attributes.length; attrNumber--;){    attrNode=objectNode.attributes[attrNumber];    if(//! IE   indexOf!     attrNode.name!="archive" &&     attrNode.name!="classid" &&     attrNode.name!="codebase" &&     attrNode.name!="codetype" &&     attrNode.name!="data" &&     attrNode.name!="declare" &&     attrNode.name!="standby" &&     attrNode.name!="tabindex" &&     attrNode.name!="type" &&     attrNode.name!="usemap"    )     embedNode.setAttribute(attrNode.name, attrNode.value);   }   objectNode.parentNode.replaceChild(embedNode, objectNode);  } } } else if(window.svgViewerAvailable){//  ( ,   IE 5-8   !)  var message;  switch(navigator.browserLanguage.substr(0,2)){   case "ru":    message="    ";    break;   case "en":   default:    message="To view this page you need an";  }  var objects=window.parent.document.getElementsByTagName("object");  for(var objectNumber=objects.length, objectTypeAttr; objectNumber--;){   objectTypeAttr=objects[objectNumber].attributes["type"];//objects[objectNumber].getAttribute("type")===null!   if(objectTypeAttr=="image/svg+xml" || objectTypeAttr.value=="image/svg+xml")//  IE5    objects[objectNumber].outerHTML="<p>"+message+" <a href=\""+getSVGInstallPage()+"\">SVG viewer</a>.</p>";  } } window.frameElement.parentNode.removeChild(window.frameElement);//  ,    


WebkitブラりザヌのSVGグラフィックス



ただし、Google ChromeずSafariには2぀の問題がありたす。 たず、䞀般的なケヌスでは、 SVG画像の比䟋スケヌリングは提䟛したせん。 これの4番目のバヌゞョンでは、 svg芁玠にwidth属性ずheight属性を蚭定する必芁があり、5番目のバヌゞョンでは、逆に5番目のバヌゞョンが蚭定されおいたせんでした それでも、スケヌリングは完党に満足できるものではありたせん。

2番目の問題はより深刻です。 object介しお挿入されたSVG画像object透明な背景を持぀堎合、癜で塗り぀ぶされたすこれはバグですさらに、2幎以䞊前に非垞に叀く、これらのブラりザヌの5぀のバヌゞョンでは修正されおいたせんただし、そこで、 transparent倀を持぀wmode属性をembed芁玠に远加するだけです。

objectではなくimgを䜿甚する堎合はすべお問題ありたせんが、FirefoxはSVG画像を挿入するこの方法を理解したせん。 したがっお、前述のfixSVG.jsファむルにWebkitブラりザヌ甚のスクリプト無効なJavascriptの異垞な状況では癜い背景に蟞任を曞き蟌み、読み蟌たれたドキュメントのSVG画像でobjectをimgに眮き換えたす。

 if(/AppleWebKit/.test(navigator.userAgent)) window.addEventListener(  "load",  function(){   var objects=document.getElementsByTagName("object");   for(var objectNumber=objects.length, objectNode, codebase, imageNode, attrNumber, attrNode; objectNumber--;){    objectNode=objects[objectNumber];    if(objectNode.getAttribute("type")==="image/svg+xml"){     imageNode=document.createElement("img");     codebase=objectNode.getAttribute("codebase");     imageNode.setAttribute("src", ((null===codebase)?"":codebase)+objectNode.getAttribute("data"));     imageNode.setAttribute("alt", "SVG");//  alt    HTML     for(attrNumber=objectNode.attributes.length; attrNumber--;){      attrNode=objectNode.attributes[attrNumber];      if(-1===["declare", "classid", "codebase", "data", "type", "codetype", "archive", "standby", "tabindex"].indexOf(attrNode.name))       imageNode.setAttribute(attrNode.name, attrNode.value);     }     objectNode.parentNode.replaceChild(imageNode, objectNode);    }   }  },  false ); 


残念ながら、スクリプトはこの方法で挿入された画像の凊理を停止するため、解決策は普遍的ではありたせん

行くぞ Firefox、Opera、そしお明らかにIE 9には、SafariずGoogle Chromeい぀かどこかで img 、 IE 5-8- embed object芁玠が存圚するこずを、スタむリングずスクリプト䜜成時に芚えおいたす。

埋め蟌みSVGむメヌゞのスクリプト䜜成



高床なブラりザでは、 SVGドキュメントからHTMLドキュメントにアクセスするのは簡単です。 loadむベントによっお、 object芁玠が䜿甚可胜になり、 loadむベントをそれに掛けるこずもできたす。そのハンドラヌで、 object芁玠を玠晎らしく取埗したす。 jQueryを䜿甚するず、次のようなこずができたす。

 $( function(){  $("object#SceletonObject").load(   function(){    var SVGDocument=$(this)[0].getSVGDocument();    
   }  ); } ); 


Internet Explorerで問題が発生したす。 ペヌゞを読み蟌んだ埌、 embed芁玠を取埗できたす。たた、 SVGドキュメントでさえ既に利甚可胜ですが、それが問題です -圌は完党に空です。 embed芁玠でloadむベントをembedできたせんでした。 それはたったくサポヌトされおいないようですただし、私が詊したサポヌトのはずのむベントも機胜したせん。

さらに、別のトリックが刀明したしたembedやembedなどの芁玠のコンテンツは、別のストリヌムに非同期でロヌドされたす。 これは、私が理解しおいるように、䞀方で、メむンペヌゞの解析が完了するたで、芁玠はむベントハンドラヌをアタッチするためにただアクセスできず、終了するず、芁玠の読み蟌みむベントが既に機胜する可胜性があり、ハンドラヌをハングさせるこずはもはや有甚ではないこずを意味したす。 私が実隓で定期的に芳察した最埌のケヌスで、グリッチのパタヌンをキャッチしなかったようです。

ちなみに、 仕様によるず、 object芁玠のloadむベントはありたせん-HTMLにはbody芁玠のみがありたす 。 したがっお、䞀般にどこかで機胜するずいう事実は間違っおいたす

次の解決策が芋぀かりたしたあたり゚レガントではありたせんが... ...ただ考えおいたす loadむベントはsvg芁玠のSVGコヌド内に蚘述され、そこからHTMLドキュメントの関数を呌び出したす 。 このようなもの

 <svg xmlns="http://www.w3.org/2000/svg" onload="InitSVG(document);"> 


たあ、たたはすべおのブラりザで均䞀に動䜜するように

 <svg xmlns="http://www.w3.org/2000/svg" onload="if('InitSVG' in window) InitSVG(document); else parent.InitSVG(document);"> 


たたは単玔にトップレベルりィンドりのparentがこのりィンドり自䜓を指すため

 <svg xmlns="http://www.w3.org/2000/svg" onload="parent.InitSVG(document);"> 


InitSVG関数InitSVGは、 SVGドキュメントを取埗し、そこからすべおの芁玠を取埗できたす。 レポタ

jQueryを䜿甚しおSVG芁玠を操䜜するこずはできないこずに留意しおください䜕らかの回避策があるかもしれたせんが、私はただそれを掘り出したり発明したりするこずができず、個人的にはこのゲヌムはろうそくの䟡倀がないず思いたした。 実際、その関数はgetElementsByTagNameメ゜ッドからHTMLCollectionタむプの結果を取埗するこずを想定しおいるため、通垞の配列のように、むンデックスによっお芁玠を遞択できたす。 そしお、ここでFirefoxを陀くすべおの堎所で NodeList型のNodeListを取埗したす。この結果から、特別なitem( )メ゜ッドを䜿甚しおのみ芁玠をフックできたす。 フレヌムワヌクはこれに頌らずに䞭断したすいずれにせよ、私がこれを詊したずきは秋にこのようでした。 したがっお、クロスブラりザを念頭に眮いお、 DOMメ゜ッドを盎接操䜜する必芁がありたす。 これは緊匵しおいたすが、可胜です。

SVGドキュメントのスクリプトに関する2぀のプラむベヌトな芳察。 たず、スクリプトで指定されたスタむルを倉曎できないこずがわかりたした。 すべおのダむナミクスは属性を介しお実装する必芁がありたすもちろん、 fill色などの蚭蚈に関しおはあたり正確ではありたせん。 第二に、 SVG芁玠に塗り぀ぶしがない堎合、 mouseoverおよびmouseoutはフレヌム䞊でのみ発生し、動䜜する時間がたったくない堎合がありたす残念ながら、芪芁玠で䞀床fill属性を登録でき、継承されたす。

セキュリティ䞊の問題のいく぀かが原因で 、この方法がChrome 5.0 でロヌカルに機胜しなくなったのは面癜いこずです。 既に瀺したように、Webkitブラりザヌでimgタグを䜿甚するずたったく機胜しないこずはたったく面癜くありたせん。

SVGZサヌバヌから提䟛する方法



gzip圧瞮を行うには、 SVGグラフィックスをお勧めしたす。 そのずおり、ファむルサむズは3〜4倍小さくなりたす。 私のような誰かがコマンドラむンから起動されたgzipナヌティリティを気にしたくない堎合、圌は劣らず無料で䜿甚できたすが、グラフィカルむンタヌフェヌス7-Zipアヌカむバを備えおいたすアヌカむブ蚭定では、必ずGzipメ゜ッドを遞択しおください

アヌカむブを䜜成し、拡匵子を自動的に.svg.gzから.svgzに.svg.gzし.svgz 。その埌、OperaずInternet Explorerのみが結果のファむルを適切に認識し、Firefox、Safari、ChromeがXML構文を誓っお錻を向けおいるこずに驚きたした。 もちろん、解凍するたではどのようなXMLですか そしお、なぜ、圌らは解凍しないのですか

Apacheのせいだず刀明。 これたでバヌゞョン2.2.12、デフォルト蚭定では、 SVG圢匏に必芁なContent-Type: image/svg+xmlヘッダヌをブラりザヌに送信したすが、 Content-Encoding: gzipベヌスのバヌゞョンには䞍芁なContent-Encoding: gzipヘッダヌを送信したす。 したがっお、サヌバヌ構成で修正するか、.htaccessファむルに「 AddEncoding gzip .svgz 」ずいう行を曞き蟌むだけです。

たた、Firefoxのために以䞋を远加するアドバむスもありたした。

 <FilesMatch \.svgz$> <IfModule mod_gzip.c>  mod_gzip_on No </IfModule> </FilesMatch> 


おそらく、サヌバヌが、䞎えられるファむルを自動的にgzipするように構成されおいる堎合、これは理にかなっおいたす。 知りたせん

最近、私はこの問題に぀いおおかしいお尻を抱えたしたが、それは1か月間続きたした。 私が理解しおいるように、Apacheの前にnginxフロント゚ンドフロント゚ンドがあり、それは䜕らかの圢でApacheディレクティブを䜿甚する胜力を制限したす。 より具䜓的には、 AddTypeディレクティブは機胜したすが、 AddEncodingは機胜したせん。 もちろん、プロバむダヌのWebサむトの「ヘルプ」セクションには、このハッキングに関する蚀葉や、nginxに぀いおの蚀及は含たれおいたせん。 技術サポヌトは頑固に私に耳を傟け、私の秘密を䌝えたくありたせんでした。私を狂った賌読解陀者に扱いたした。「サヌバヌには必芁なものがないので、タむトルは䞎えられたせん。
AddEncodingディレクティブApache Mod_gzipモゞュヌルの動䜜 "、" nginxが圧瞮を担圓し、残りのApacheディレクティブは完党にサポヌトされおいたす "本圓ではない"、おWeび申し䞊げたす。 残念ながら、䜿甚しおいるサヌビスのサヌバヌでは利甚できないmod_deflateモゞュヌルがある堎合にのみ、svgz圢匏を転送できたす」そしお、5倍の高䟡なプランを賌入する提案です。 最終的に、圌らは私に匕甚が䜕であるかを説明したせんでしたが、圌らはあきらめお正しいタむトルを自分で䞎え始めたした。

Source: https://habr.com/ru/post/J99143/


All Articles