|
XHTML, document.write() i AdsenseJakiś czas temu, w trakcie prac nad serwisem Poradnik Webmastera postanowiłem przejść z HTML 4.01 Transitional na XHTML 1.0 Strict. Początek pracy był prosty - pozmieniałem literki na małe w nazwach znaczników i atrybutach, pozamykałem znaczniki i przeniosłem elementy prezentacyjne do arkusza CSS. Po wykonaniu tego strona przeszła test poprawności składniowej na walidatorze W3C, ale nadal wymagała jeszcze poprawek ze względu na różnice w interpretacji kodu przez przeglądarki, głównie przez MSIE, który nawet w wersji 7 wciąż nie jest w pełni zgodny ze standardami. Ostatecznie strona jednak zaczęła sensownie wyglądać pod wszystkimi przeglądarkami, więc postanowiłem wykonać kolejny krok, czyli zmienić typ MIME. Dokumenty XHTML 1.0 powinny być wysyłane z użyciem typu MIME <?php if ($xhtml) print "<script type=\"text/javascript\"><![CDATA[\n"; else print "<script type=\"text/javascript\"><!--\n"; ?> // Tutaj jest ciało skryptu <?php if ($xhtml) print "//--></script>\n"; else print "]]></script>\n"; ?> Alternatywnym rozwiązaniem byłoby przeniesienie skryptów do zewnętrznych plików i dołączenie ich do strony, ale uznałem że w moim przypadku albo tego nie mogę zastosować (Adsense), albo nie warto (krótkie skrypty JavaScript umieszczone w Kursie JavaScript. Po zastosowaniu powyższego fragmentu kodu część skryptów JavaScript zaczęła działać. Niestety nadal nie działały te które korzystały z document.write = function(str){ // convert str to string str += ""; var moz = !window.opera && !/Apple/.test(navigator.vendor); // Watch for writing out closing tags, we just // ignore these (as we auto-generate our own) if ( str.match(/^<\//) ) return; // Make sure & are formatted properly, but Opera // messes this up and just ignores it if ( !window.opera ) str = str.replace(/&(?![#a-z0-9]+;)/g, "&"); // Watch for when no closing tag is provided // (Only does one element, quite weak) // Skip already closed elements if (!str.match(/^<([a-z0-9]+).*<\/\1>$/)) str = str.replace(/<([a-z]+)(.*[^\/])>$/, "<$1$2></$1>"); // Mozilla assumes that everything in XHTML innerHTML // is actually XHTML - Opera and Safari assume that it's XML if ( !moz ) str = str.replace(/(<[a-z]+)/g, "$1 xmlns='http://www.w3.org/1999/xhtml'"); // The HTML needs to be within a XHTML element //var div = document.createElementNS("http://www.w3.org/1999/xhtml","div"); if(document.createElementNS){ var div = document.createElementNS("http://www.w3.org/1999/xhtml", "div") } else { var div = document.createElement("div"); div.setAttribute("xmlns", "http://www.w3.org/1999/xhtml"); } div.innerHTML = str; // Find the last element in the document var pos; // Opera and Safari treat getElementsByTagName("*") accurately // always including the last element on the page if ( !moz ) { pos = document.getElementsByTagName("*"); pos = pos[pos.length - 1]; // Mozilla does not, we have to traverse manually } else { pos = document; while ( pos.lastChild && pos.lastChild.nodeType == 1 ) pos = pos.lastChild; } // Add all the nodes in that position var nodes = div.childNodes; while ( nodes.length ) pos.parentNode.appendChild( nodes[0] ); }; Gotowy skrypt najlepiej jest umieścić w zewnętrznym pliku i następnie dołączyć do wysyłanego dokumentu jeżeli jest wysyłany jako if ($xhtml) print "<script type=\"text/javascript\" src=\"doc_write.js\"></script>"; Zaprezentowane powyżej rozwiązanie jest to pewna "proteza" która pozwoli na uruchomienie niektórych skryptów JavaScript korzystających z W przypadku gdy jednak nie ma wyjścia i trzeba użyć skryptu który wypisuje kod HTML "po kawałku", lub też np. zawiera znaczniki pisane dużymi literami, trzeba zastosować dodatkowe rozwiązanie - na czas działania tamtego skryptu trzeba dostarczyć funkcję <script type="text/javascript"><![CDATA[ var str = ""; orig_doc_write = document.write; document.write = function(s) { str += s; } ]]></script> <!-- tutaj jest skrypt sprawiajacy problemy --> <script type="text/javascript"><![CDATA[ document.write = orig_doc_write; document.write(str); ]]></script> W powyższym przykładzie wszystkie wywołania Oczywiście zaprezentowane tutaj na końcu rozwiązanie powinno być traktowane jako rozwiązanie awaryjne, które można zastosować w sytuacji gdy nie ma już innej możliwości poradzenia sobie z problemem. W każdej innej sytuacji warto natomiast zastosować inne rozwiązania, które są "przyjazne" XHTML. Dodaj linka na swojej stronie! Po prostu skopiuj poniższy kod i wklej go na swojej stronie WWW. Gotowy link będzie wyglądał w taki sposób: |
| ||||||||||||||||||||||||||||||