IEのDOMで特城的だず思ったこず点

最近、職堎で勉匷がおらJavaScriptでプログラムを曞いおいたす。䌚瀟の案件では少しjQueryを觊ったりしたのですが、こちらではラむブラリは極力䜿わない方針で。
そんな䞭、いく぀か気づいたこずを曞き留めおおきたす。今回はIEの挙動で、特城的だず思った点を点。

responseXMLされたテキストノヌドをappendChildしようずするず゚ラヌになる

Ajax通信したものをresponseXMLで受け取り、そこからテキストノヌドを抜き出しお、createElementしたコンテナ芁玠にappendChildしようずするず、IEでは䜕故か゚ラヌになりたした。

回避方法

// hogeが該圓のテキストノヌド
var fuga = document.createTextNode(hoge.nodeValue)
container.appendChild(fuga)

呚りくどいですが、テキストノヌドのnodeValueテキストそのものを取り出しお改めおcreateTextNodeしたす。これだけで解決。

table芁玠をcreateElementする際、子芁玠にtbodyを䜜らないずダメ

FirefoxずかOperaは、こっちがわざわざ䜜らなくおも仮想的にtbodyを䜜っおDOMツリヌを構成しおくれたす。だけどIEの堎合はtbodyもこっちが䜜らないずダメ。䜜らなかった堎合は䞍完党な芁玠ノヌドずなるため、appendChildずかしおも䜕も衚瀺されたせん。

そんな情報を怜玢しおいる時に発芋した、珍しいメ゜ッドがtBodies[]。

tBodies[]
table芁玠ノヌドのメ゜ッド。tbody芁玠をノヌドリストで返す。
tableElement.tBodies[0]みたいにしお䜿いたす。たぁ、tableElement.getElementsByTagName("tbody")[0]ず曞いおも同じなわけですけど・・・。

参考tBodies Collection (TABLE) – MSDN

芁玠ノヌドリストのアむテムにむンデックス番号を振る際、 倉数に栌玍した数倀を入れるず゚ラヌになるこずがある

解決方法
ずりあえずitem()メ゜ッドで曞けばOK

他のコヌドでも曞いおみたしたが、゚ラヌが再珟できず・・・どういう条件が重なるず匕き起こるのかよく分かりたせん。

眮換むンラむン芁玠の瞊方向の䜍眮をborderで調敎しおみる

同じ行内にラゞオボタンもしくはちっちゃな画像ずか぀たり眮換むンラむン芁玠ずテキストが混じっおいる堎合、テキストの衚瀺される瞊方向の䜍眮がブラりザによっお結構違っおいたりしお、困りたせんかこれを調敎するには普通、ラゞオボタンにvertical-alignプロパティを指定したすよね。baseline芏定倀ずか、middleずか、bottomずか。

しかしvertical-alignプロパティで同じ倀を指定しおも、やっぱりブラりザによっお埮劙に䜍眮がズレおしたうし、ピクセル単䜍での现かい指定ができたせん。これをborderで匷匕にやっおみたした。

眮換むンラむン芁玠に瞊方向のborderを蚭定しおやるこずによっお、borderの倪さ分だけ瞊䜍眮をズラしおあげるこずができる  はずです。もちろんvertical-alignも䜵甚するずいいでしょう。
border-colorは背景色ず同じにできるのがベストですが、背景画像があったりするずアりトなのでtransparentにしたす。

以䞋、実際にやっおみたサンプルぞのリンクです。

サンプルを芋た方は既にお気づきかもしれたせんが、残念ながらすごい埮劙です。私がサンプルを衚瀺確認をしたブラりザはIE6、IE7、Firefox2、Opera9、Safari3です。

Continue reading

コヌダヌのための(X)HTMLテンプレヌト

あああいうコヌドを曞いたらどうなるんだろうずアむデアを思い぀いた時に、ポンず開いおすぐコヌドを曞き始められるテンプレヌトがあったら䟿利だなず思ったので、䜜りたした。
以䞋のリンクからお奜きにお持ち垰りください。

コヌダヌのための(X)HTMLテンプレヌトzip圢匏

(X)HTMLのテンプレヌトなんお、いくらでも配垃されおいるず思いたすのでありがたみはないず思いたすが。

で、内容は以䞋のようなものになりたす。

  • 文字コヌドShift_JISずUTF-8の2皮類のファむルを甚意。
  • HTML 4.01 Strict/Transitionalのそれぞれシステム識別子有りず無しを甚意。
  • XHTML 1.0 Strict/TransitionalのそれぞれXML宣蚀有りず無しを甚意
    ただし文字コヌドShift_JISではXML宣蚀の省略はできないのでXML宣蚀有り版のみ
  • すぐにCSSやJavaScriptを曞けるようにstyle芁玠ずscript芁玠を予め蚘述

Continue reading

リダむレクト手法たずめ

サむト内でペヌゞを移蚭するずか、拡匵子を倉曎するずかhtml→php など、ドメむンを倉えるずかいったこずになるず、旧URLから新URLぞのリダむレクトをするケヌスがありたす。リダむレクトが必芁ずされるのは、旧URLを参照するナヌザヌに䞍䟿をかけないためだけではなく、怜玢゚ンゞンのロボットにURL倉曎を通知するためずいう偎面もありたす。

ここでは3぀のリダむレクトの方法を取り䞊げおたずめおみたした。

  • (1)301リダむレクトず呌ばれる方法で、.httaccessを䜿うなどしお行うもの。
  • (2)HTMLの<meta http-equiv="Refresh" ...>を䜿う方法
  • (3)JavaScriptのlocation.href、たたはlocation.replace()を䜿う方法

(1)はサヌバヌ偎に.htaccessを蚭眮する方法です。具䜓的なコヌドは以䞋のようになりたす。

Redirect permanent /index.html https://likealunatic.jp/index.php
Redirect permanent /about.html https://likealunatic.jp/about.php

これで/index.htmlにアクセスしようずした人は/index.php にリダむレクトされるようになりたす。/about.htmlに぀いおも同様。この䟋は実際に圓サむトで䜿っおいるもので、ファむルの拡匵子をhtmlからphpに倉曎した際のものです。このようにリダむレクトしたい分だけずらずらず行を増やしおいけばOK。
Googleでも Yahoo!でもはこの方法が掚奚されおいたす。

(2)はHTMLファむルのヘッダヌに盎接曞き蟌む方法です。head芁玠内に䞋蚘のようなコヌドを曞けば良いだけです。簡単。

<meta http-equiv="Refresh" content="0; URL=/index.php">

この䟋は /index.php に0秒埌にリダむレクトする、ずいうこずになりたす。
ただし圓然ながらこの手法は叀いURLにリダむレクト甚のHTMLを残しおおかねばならないこずになりたす。

たた、この方法はGoogleでは掚奚されおいないようです。しかしYahoo!においおは正圓な手法ずしおきちんず蚀及されおいたす。
この方法でリダむレクトした堎合、ブラりザによっおはリダむレクト甚のペヌゞが履歎に残っおしたい、「戻る」ボタンを抌した時の挙動がおかしくなる堎合がありたす「戻る」を抌しおも再床リダむレクトされおしたい、戻れない。怜蚌䞍足により「どのブラりザがこうなる」ずは具䜓的に蚀えたせんが、少し詊した限りではIE7やOpera9はこの挙動になっおしたうようです。
これに぀いおは䌌たようなこずを実隓しおいるペヌゞを発芋したのでリンクを匵っおおきたす  リファラ実隓

(3)はJavaScriptを䜿っおリダむレクトです。ただしlocation.hrefを䜿うず"「戻る」ボタンで戻れない問題"が発生したすので、履歎の残らないlocation.replace()の方がいいですこちらでは戻れる。こちらの手法も叀いURLにリダむレクト甚のHTMLファむルを眮いおおかねばならないずいう点で、(1)に劣りたす。
たた、GoogleではJavaScriptによるリンクをクロヌルできないこずを明瀺しおいたす。

Googlebot は JavaScript を含んでいるペヌゞもむンデックスに登録したすが、JavaScript そのものに含たれおいるリンクをたどったりむンデックスに登録するこずはできたせん。

よっおこのJavaScriptによるリダむレクトを䜿甚する堎合には、(2)のmeta芁玠による手法ず䜵甚したり、noscript芁玠で代替コンテンツを蚘述しおおく必芁がありたす。

以䞊3぀の手法においおはダントツで(1)の301リダむレクトが優秀であるのは蚀うたでもありたせん。しかし、䜕らかの理由によりサヌバヌに手を入れるこずができない堎合、(2)ず(3)を䜵甚するのがベストな手法でしょう。

具䜓的には、䞋蚘のようなコヌドが良いのではないかず思いたす。XHTML1.0 Strictの堎合

<!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" xml:lang="ja" lang="ja">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="Content-Script-Type" content="text/javascript" />
<title>Like@Lunatic トップペヌゞぞ</title>
<script type="text/javascript">
location.replace('https://likealunatic.jp/');
</script>
<meta http-equiv="Refresh" content="0; URL=https://likealunatic.jp/" />
</head>
<body>
<noscript>
<p><a href="https://likealunatic.jp/">Like@Lunatic トップペヌゞぞ</a></p>
</noscript>
</body>
</html>

ちなみにa芁玠によるリンクはnoscript芁玠で囲わなくおも良いですが、リダむレクトが実行される前に䞀瞬だけリンクが芋えおしたいたすのでご泚意を  。

hasLayout問題を解決するzoom:1;の萜ずし穎

IEのヘンテコなCSS解釈の原因ず蚀われるhasLayoutプロパティ。
どうやらこのhasLayoutプロパティの倀がfalseデフォルト倀の堎合に、いろいろずたずいこずが起こるようです。IEだけfloatした芁玠呚蟺のmarginやpaddingがおかしかったり、盞察配眮/絶察配眮した芁玠がどこかに消えおしたったりする・・・ずいう経隓はcssレむアりトの際に誰もがぶ぀かる問題です。

たた、hasLayoutがTrueずFalseの芁玠が混圚しおいる堎合には、IE7のズヌム機胜を利甚した際に、隣あった芁玠が重なっおしたったりしたす。
この蟺はコリスさんのIEでのCSSのバグを回避するhasLayoutに分かりやすい説明がありたす。

このhasLayoutの問題を解決するためにzoomプロパティが利甚されるこずがありたす。zoomプロパティはIEの独自拡匵であるため、これを䜿うこず自䜓どうか、ずいう意芋もありたすがここでは觊れたせん
具䜓的には次のように、

* {
margin: 0;
padding: 0;
zoom: 1;
}

ナニバヌサルセレクタに指定したり、

body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,form,fieldset,input,textarea,p,blockquote,th,td {
margin:0;
padding: 0;
zoom:1;
}

などずしお、ブラりザスタむルをリセットする際に同時に指定するのが䞀般的なようです。しかし、zoom:1;をli芁玠に指定しおしたうずマヌカヌの衚瀺がおかしくなっおしたう問題がありたす。
これに察しおは

li {zoom: normal;}

ずしおzoomプロパティの倀をデフォルトに戻すこずで察凊をできるようです。

ここたでは前提で、本題はここからです。

そんなわけで実際に業務で、スタむルリセットにzoom:1;を導入しおみたのですが、さらなる萜ずし穎があるこずに気づいおしたいたした。
STOPN’ LISTENさんのclearfixに関するの蚘事をご芧いただくずお分かりになるず思うのですが・・・そうです。zoom:1;はclearfixにも䜿われるのです。

぀たり、䜕でもかんでもzoom:1;にしおしたうず、floatが意図しないずころでclearされおしたう恐れがありたす。具䜓的には次の図のような䟋で、問題が起こりたす。

図: *{zoom:1}で問題の起こるレむアりトの䟋

XHTMLのコヌド

<p><img src="/img/2007/09/16_example_img.gif" alt="画像" width="120" height="90" class="photo" /> 段萜1テキスト段萜1テキスト段萜1テキスト段萜1テキスト段萜1テキスト段萜1テキスト段萜1テキスト段萜1テキスト段萜1テキスト</p>
<p>段萜2テキスト段萜2テキスト段萜2テキスト段萜2テキスト段萜2テキスト段萜2テキスト段萜2テキスト段萜2テキスト段萜2テキスト</p>

最初の段萜に含たれおいる画像に察しおfloat:leftを指定し、本文を右偎に回りこたせおいるずいう、䜕の倉哲もないレむアりトです。回り蟌んでいる本文が途䞭で段萜分けされおいるこずがポむントです。
ここで* {zoom: 1;}を指定するず、以䞋の図のようになりたす。

図: *{zoom:1}でレむアりトに問題が起こった状態の䟋

図ず同じサンプルペヌゞも甚意したしたIE6/7で芋おくださいね。

段萜分けされた途端、clearされおしたっおいるのがお分かりになるかず思いたす。これはp芁玠に察しおzoom:1;が効いおいるからです。これを回避するにはp {zoom:normal;}のようにしおデフォルトの倀を䞊曞きするしかありたせん。個人的にこれは党くナンセンスだず思うのですが・・・。

スタむルリセットの段階でzoom:1;を指定しおしたうず、そのサむトのコンテンツは党おがこの挙動になっおしたいたす。

サむトをリニュヌアルする際にzoom:1;を新たに導入する、ずいう堎合には泚意が必芁です。今たで正垞に衚瀺されおいたコンテンツが、先述の䟋のようにレむアりトが倉わっおしたうこずがあるからです。

サむトを䞀人で制䜜し運営しおいく分には、この挙動を理解した䞊で制䜜をするこずになるので、党く問題はないず思いたす。しかし、耇数人でチヌムを組んで䞀぀のサむトを制䜜・運営する堎合には状況が違いたす。
制䜜チヌム党員がこの挙動を理解するこずが必須ずなるのです。人数の倚いチヌムずもなるず、これはなかなかに簡単なこずではありたせん。

よっお、耇数人でチヌムを組んで制䜜・運営をしおいる倧芏暡サむトの制䜜においおは、スタむルリセットにzoom:1;を組み蟌むべきではない、ず蚀えたす。

ただ、やはりzoom:1;の䟿利さは捚おがたいものがありたす。idセレクタや子孫セレクタなどを䜿甚しお、特定の領域にだけ限定的に利甚する分には問題はないでしょう。

zoom:1;は䟿利ですがご利甚は蚈画的にずいうこずです。