iframe floating frame (I didn’t even try it, considering the frames to be an outdated evil);object tag (we’ll do this trick).object tag to be scripted and fills its transparent background with white! Fortunately, it provides its proprietary embed tag for this purpose. Through conditional comments and style management, you can easily and validly ensure that normal browsers will display SVG via an object element, and IE through an embed . But will it?embed tag in many places on the Internet, you can read that it has such a wonderful pluginspage attribute that indicates the address that supposedly " will be sent to the user if his browser does not support SVG graphics ." <script language="JavaScript"><!-- checkAndGetSVGViewer(); // --> </script> <script language="JavaScript" src="viewSVJ.js"></script> <!--[if IE]> <script language="JScript" src="svgcheck.js"></script> <script language="VBScript" src="svgcheck.vbs"></script> <script language="JScript" src="viewSVJ.js"></script> <![endif]--> <!--[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 plugin script, if the SVG plugin is still not installed, we will go through the elements of the embed and replace them with warnings with links: 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>"; } } ); embed element should be written for each SVG picture, and links to several scripts (and also with a conditional comment) for each page containing them! Of course, there is a standardization, but ... In addition, these scripts litter the global namespace, and I don’t want to go into sorting out their obsolete code.fixSVG.js page one fixSVG.js script, where for IE we will write our branch, in which we will load into a dynamically created floating frame (yes, I snorted at their address, but this is the same solution for the browser, which has not been better yet!) scripts from "Edoubi" (Adobe); use them to check for the presence of an installed SVG plugin; if it is not installed, replace the images with the corresponding notifications with a link; and, finally, delete this frame (for the sake of purity of the page). Implementation details see below. <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> object element with an embed element if the SVG plugin is installed, and with a notification with a link if it is not already installed. <script type="text/ecmascript" src="fixSVG.js"></script> fixSVG.js file looks like this (using an already scripted conditional comment): /*@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 , loaded into a dynamically created floating frame: <!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 and svgcheck.vbs are adware, intact. And fixSVG_IE_5-8.js is ours: 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);// , svg element be given the width and height attributes, and the 5th, on the contrary, that they were not set! But at the same time scaling is not quite satisfactory.object SVG-images have a transparent background, it is filled with white (this is a bug ! And it is very old, more than two years old, and in 5 versions of these browsers it is not fixed), as in IE (but there we can simply add an embed element to the wmode attribute with the value transparent ).object , but img , then everything is fine, but so far Firefox does not understand this way of inserting the SVG image. Therefore, we write a script for Webkit-browsers in the above-mentioned fixSVG.js file (accepting the white background in the abnormal situation of disabled Javascript), replacing the loaded object document with the SVG-image on 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 ); object element, in Safari and Google Chrome (I hope sometime everywhere) - img , and in IE 5—8 - embed .load event, the object element is available to us, we can also hang a load event on it, and in its handler we will get the required one in a remarkable way. With jQuery, this could be done like this: $( function(){ $("object#SceletonObject").load( function(){ var SVGDocument=$(this)[0].getSVGDocument(); … } ); } ); embed element in it and it even has a SVG document already available, but that's the point! - it is completely empty. I could not embed load event to the embed element; it seems that it is not supported at all (however, those of the supposedly supported events that I have tried do not work either).object and embed loaded asynchronously , in a separate thread. This means, as I understand that, on the one hand, until the parsing of the main page is completed, the element is not yet available for attaching an event handler to it, and when it is finished, the element load event may already work and then the handler is already useless. It seems that it was the last case that I occasionally observed in experiments without catching any regularity in the glitch.load event for the object element is missing - it is in HTML only for the body element. So the fact that it even works somewhere is wrong!load event inside the SVG code of the svg element, calling the function HTML document from there. Somehow: <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 in the top-level window points to this window itself): <svg xmlns="http://www.w3.org/2000/svg" onload="parent.InitSVG(document);"> InitSVG function we can already get the SVG document and from it all its elements. Lepote!getElementsByTagName method a result of the HTMLCollection type, from which you can select elements by index, as from a regular array. And here we get (everywhere except Firefox) a result of the NodeList type, from which the item can only be pulled out using the special item( ) method item( ) . The framework does not count on this and breaks off (in any case, it was so in the fall, when I experimented with it). So you have to work directly with DOM methods, keeping cross-browser compatibility in mind. This is stressful, but possible.fill - fill ). Secondly, if the SVG element does not have any fill, then the mouseover and mouseout work only on the frame and may well not have time to work at all (fortunately, you can write the fill attribute once on the ancestor element and mouseout ).img tag..svg.gz to .svgz , then with amazement we see that the resulting file is adequately perceived only by Opera and Internet Explorer, and Firefox, Safari and Chrome turn up the nose, cursing the syntax of XML . Well, of course, what is XML there until you unzip it? And why, in fact, they do not unzip?Content-Type: image/svg+xml header required for SVG format to the browser Content-Type: image/svg+xml , but the Content-Encoding: gzip header Content-Encoding: gzip not required for its gzip version. Therefore, we will fix the server configuration or simply write the line “ AddEncoding gzip .svgz ” to the .htaccess file. <FilesMatch \.svgz$> <IfModule mod_gzip.c> mod_gzip_on No </IfModule> </FilesMatch> AddType directive works, but AddEncoding does not. Of course, the “Help” section on the provider's website does not contain a word about this quirk, or even even a single mention of nginx. Technical support stubbornly did not want to listen to me and give out their secrets, giving me insane replies: “The title is not given, because the server does not have the necessary settings forSource: https://habr.com/ru/post/99143/
All Articles