しかし、 SVG画像をHTMLドキュメントに入れる方法は?
HTMLにSVGを埋め込む方法
3つの方法があることが知られています。
- コードに直接(ただし-ああ、ああ!-IEはこのメソッドを受け入れず、他のブラウザはXHTMLドキュメントでのみ許可しますが、これは常に可能ではありません);
-
iframe
フローティングフレームにiframe
しました(フレームは時代遅れの悪であると考えたため、試してさえいませんでした)。 -
object
タグを使用しobject
(これは私たちが行うことです)。
最初の驚きは私たちを提示します...どのブラウザを推測しますか? もちろん、この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倍の高価なプランを購入する提案です!)。 最終的に、彼らは私に引用が何であるかを説明しませんでしたが、彼らはあきらめて正しいタイトルを自分で与え始めました。