ブラウザ間の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年にW3CVMLを投入したMicrosoftがどのよう攻撃されたとしても、 GoogleWikimedia 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倍の高価なプランを購入する提案です!)。 最終的に、彼らは私に引用が何であるかを説明しませんでしたが、彼らはあきらめて正しいタイトルを自分で与え始めました。



All Articles