タグクラウドの日本語文字の改行を制御したい

category-icon

 こんばんは。以前、フォーラムで

「タグボックス(いわゆるタグクラウド)に含まれる日本語のキーワードが途中で改行されることがありますが、これを防ぐ方法はありますか?」

という質問があったように記憶しています(探し出せませんでしたが・・・)。

 その時は、「日本語折り返しの制御はなかなか難しいかもですねぇ」みたいに答えていたと思いますが、ちょっとやってみたところ解決できたのでエントリーとして残しておきます。

 まずは、以下のショットを。これはppBlogを含めた多くのブログで見かけるタグクラウドGですが、日本語の文字列が途中で改行されて、一瞥しただけではキーワードが認識しにくくなっています。このサンプルのタグクラウドは、まだエントリー数が少ないのでそうでもないですが、タグの数が多くなると、結構みづらくなるのではと思います。
shot1
日本語文字列は半端に改行されている。
 そこで以下のショットのように改善したいです。
shot2
日本語文字が途中で改行されていないことが分かる。

 これはスタイルシート(CSS)をうまく使うことで解決できます。IE系なら、IE5の時代からword-breakというW3Cのワーキングドラフトに含まれる仕様Link を先行実装しているので、これを使えば少なくともIE5-7では意図した結果が得られます。この値の指定をkeep-allにすればOKです。これで日本語の単語が途中で改行されることはなくなります。でも、これはFirefoxが対応していません。さらには、IE8ではbreak-allの挙動がIE5-7と違うようで、Safari/Chromeと同じように振舞うようです。その結果、keep-allを指定しても、日本語の単語は途中で改行され得ます(参考:「CSS 3におけるテキストの自動改行と禁則処理の定義Link 」)。

 なのでword-breakに頼らずに別の仕様をあたることにします。

 ラッキーなことにどのブラウザでも対応しているものがありました。white-spaceです。

white-spaceプロパティは、ソース中の半角スペース・タブ・改行の表示の仕方を指定する際に使用します。

引用元: white-space-スタイルシートリファレンスLink

 空白だけでなく、改行の表示にもかかわっているのがポイントですね。ppBlogでは、タグクラウドはだいたい以下のようなソースを出力します。

<ul class="sidebar-tags">
 <li><a href="#" rel="tag" style="font-size: 11px;">DOM storage</a></li>
 <li><a href="#" rel="tag" style="font-size: 11px;">Flex</a></li>
 <li><a href="#" rel="tag" style="font-size: 12px;">CSS</a></li>
 <li><a href="#" rel="tag" style="font-size: 13px;">フーリエ級数</a></li>
 <li><a href="#" rel="tag" style="font-size: 11px;">PHP</a></li>
 <li><a href="#" rel="tag" style="font-size: 15px;">トラベラーズ</a></li>
 <li><a href="#" rel="tag" style="font-size: 11px;">ppBlogTips</a></li>
 <li><a href="#" rel="tag" style="font-size: 29px;">ppBlog</a></li>
 <li><a href="#" rel="tag" style="font-size: 11px;">無限級数</a></li>
 <li><a href="#" rel="tag" style="font-size: 11px;">Ajax</a></li>
 <li><a href="#" rel="tag" style="font-size: 21px;">アップデート</a></li>
 <li><a href="#" rel="tag" style="font-size: 29px;">JavaScript</a></li>
 <li><a href="#" rel="tag" style="font-size: 11px;">Firefox</a></li>
 <li><a href="#" rel="tag" style="font-size: 11px;">アマゾン</a></li>
 <li><a href="#" rel="tag" style="font-size: 11px;">ゴールドバッハの予想</a></li>
</ul>

これに対して、スタイルシートの指定は以下のようにすれば、うまく行きます。

ul.sidebar-tags li { 
  display: inline;
  white-space: nowrap; /* これがポイント! */
  padding-right: 3px;
  zoom: 1; /* これはIE7以下向け */
}

 基本的には、white-space: nowrap;で事足りますが、これだけだと、IE7以下で表示が崩れるので、IE7以下のhasLayoutGを有効にするためにzoom:1という指定をしています。これはほかのブラウザでは無視されます。

 では、具体的なサンプルを見てみましょう。→http://p2b.jp/demo/tagCloud.htmlLink

 ちなみに、タグクラウドという名称の由来は、雲(=クラウド, cloud)みたいだからです。なのでサンプルでは、雲のイラストを付けてみました。パワーポイントで円や直線、3角形を組み合わせて適当に作成したんですが、思わずに良い出来栄えになりました:)


— posted by martin at 01:37 pm   commentComment [2]  pingTrackBack [0]

テーマのプレビューで編集位置まで戻す

category-icon

 タイトルだけだと何のことやら分からないと思いますが、ppBlogの「テーマ管理」では、テンプレートのHTMLやスタイルシートを修正した際に、どういう風に変更が反映されるか、実際にプレビューボタンで確認することが出来ます。そのプレビュー画面では、以下のように「戻る」のリンクでもとの編集画面に戻ります。
shot2

 従来だと、この戻るリンクで戻ると、マウスのカーソルは長々しいテキストエリアの先頭に戻っているので、再度編集部位を探しつつ、そこまでスクロールする必要がありました(Ctrl+Fで検索するのが常套手段ですが)。スタイルシートの編集では、テキスト量が多い傾向にあり、直前の編集部位を探し出すのは大変です。

 なのでその辺を改善してみました。やりたいのは以下のことです。
shot
スクロールバーの位置に注目。

 テキストエリアのスクロールバーの位置はJavaScriptから制御することが出来ます。具体的には、scrollTop を使います。流れとしては、プレビューボタンを押したタイミングで、スクロール量を取得(scrollTopで可能)、プレビューから戻ったときに、取得した値を指定すれば良いわけです(指定もscrollTopです)。実際には、テキストエリアだけではなく、ブラウザのスクロールバーもscrollTopで制御できるので、この2つのスクロール量を保持するようにしています。

 やってみると意外と簡単に実装できました。もっと早くやっておけば良かったです。試されたい方は、以下のutils.phpmodules/theme.inc.phpでどうぞ。

— posted by martin at 09:46 pm   commentComment [0]  pingTrackBack [0]

 

Firefoxに伴うアップデート

category-icon

 こんばんは。普段はブラウザとしてFirefoxを使っています。で、先ほどブログの方で記事を投稿したら、Firefoxだけ(厳密にはGeckoエンジンブラウザ)に読み込ませるツールチップのスクリプトが動作していないことに気付きました。

 Firefoxは、画像などで多用されるTITLE属性内の改行や改行コードを無視します。実は仕様としては正しい振る舞いです。でも、TITLE属性の改行が有効な方がブラウザの使い手には優しいと思うので、ppBlogでは、FirefoxでもTITLE属性内の改行が有効になるようなスクリプトを用意しています。

 で、その読み込ませる際に、次のようにしています。

 if(client.Gecko) oParts.loadScript(baseURL + 'js/firefoxtooltip.js');

 このブラウザ判定は、window.GeckoActiveXObject でやっていたんですが、これがいつの間にやら認識されなくなったようです。実は、今日Firefoxの自動アップデートがありバージョンが3.5.6になりました。で、リリースノートを見てみると、どうやら

http://www.mozilla-japan.org/security/announce/2009/mfsa2009-71.html

が関係している模様。でも、これで認識しなくなるのかなという疑問もありつつ、この部分を修正しました。最新のoParts.jsを添付しておきます。

添付ファイル: oParts.jsattachedIcon 

— posted by martin at 03:55 am   commentComment [0]  pingTrackBack [0]

localStorageでIE8がクラッシュする件 続き

category-icon

 こんばんは。前回の書き庫Link で、localStorageに空の値を入れるとIE8がクラッシュすると書きました。なので、空の値が入らないようなチェックを入れれば良いのですが、それだけだとナンなので、症状をもう少し追ってみました。

 もう一度、(IE8が)クラッシュするコードを書いておきます。
function addItem(){
 var key = document.getElementById("key").value;
 var value = document.getElementById("value").value;
 window.localStorage[key] = value; // valueが空白だとクラッシュ!
}
 以下のように、直接空の値を入れる分には大丈夫でした。
function addItem(){
 var key = document.getElementById("key").value;
 var value = document.getElementById("value").value; // これは使用しない
 window.localStorage[key] = ""; // 直接、空の値を入れる → これは大丈夫。
}

 ほうほう。で、クラッシュするデモページのHTMLソースをよく見てみると、input[type=text]でvalueの値を指定していないですね。もしかしてこのせいかなぁ、と

<input type="text" id="value" value="" />

value=""を追加しましたが、やっぱりクラッシュします。input[type=text]の値がないときでも、 document.getElementById("value").value はちゃんと文字列として解釈されます(typeof value == "string")。デモページは、input[type=text]のvalue値を取得していますが、これはTEXTAREA要素であっても、やはり内容が空っぽの場合、IE8ではクラッシュを引き起こしました。

 何でですかねぇ。試しに、強引に文字列ではないオブジェクトを入れてもクラッシュしません

window.localStorage[key] = document.getElementById("value"); // これは [object] という文字列に変換される

 確かに、文字列のstringだとブラウザが解釈しているのに、それが空っぽだとクラッシュするわけです。じゃ、以下はどうだろうか。

var empty = ""; // 空っぽの変数を用意する。
window.localStorage[key] = empty; // これはセーフ。クラッシュしない。

さすがにこれはオッケーです。じゃ以下はどうだろうか?

 var val = document.getElementById("val").value; // これが空っぽとする
 var empty = "";              // val もempty も空っぽの場合
 alert(empty === val); // 厳密等価演算子は true を返す
 window.localStorage[key] = val; // なのに、val だとクラッシュ!

 とりあえず string と認識しているはずなのに、代入する段階以降で、別のクラッシュを引き起こす「何か」と解釈されるらしい。というわけで、とりあえず以下のようにすれば、IE8でのクラッシュを回避できることが分かった。でも、ナンだかすっきりしないですね:(

function addItem(){
 var _key = document.getElementById("key").value;
 var _val = document.getElementById("val").value;
 window.localStorage[_key] = new String(_val); // new String()で明示してあげる
 alert("localStorage."+_key+" の値は「"+localStorage[_key]+"」です。");
}

new String()でちゃんと文字列オブジェクトとして再評価してあげると良いらしい。というわけで、IE8でもクラッシュしないlocalStorageのデモページをリンクしておきます。

 →http://p2b.jp/demo/localStorage2.htmlLink

 ちなみに、上のコードでalert(typeof new String(_val)) は何となるでしょうか? これは、 もはやstring ではなくobjectとなります。文字列オブジェクトです。

 

— posted by martin at 06:46 am   commentComment [0]  pingTrackBack [0]

localStorageで空の値を入れるとIE8がクラッシュする件

category-icon

 こんにちは。そろそろppBlogにもlocalStorageGに対応したスクリプトを組み込もうかと思っていますが、IE8で空(から)の値を入れるとブラウザがクラッシュして終了する現象に遭いました。MacBook Pro上のVMware Fusionに入れたWindows7 RC版IE8で発生します。正規版だとOKなのかなぁ。

 簡単なデモを用意しました(IE8ならクラッシュしても良い状態でアクセス)。→http://p2b.jp/demo/localStorage.html

 Firefox3.5では値が空でもエラーも何も起きませんが、IE8では即座にクラッシュです。そのスクリーンショットをば。適当なキーを設定して(例えば「foo」)、値を何も設定せずに「追加」ボタンを押すと発生。

IE8-crashed
クラッシュしても自動的に復元されますが・・・。

上記ページのスクリプトはごくシンプルなもの。

if(typeof localStorage != "object"){
 if(typeof globalStorage == "object"){ // Firefox2 possible
  localStorage = globalStorage[location.hostname];
 } else alert("お使いのブラウザはこのスクリプトに対応していません。");
}

function addItem(){
 var key = document.getElementById("key").value;
 var value = document.getElementById("value").value;
 window.localStorage[key] = value;
}

 空の値かどうかチェックすれば済む話ですが。

関連エントリー(解決編?)

  ■http://p2b.jp/200912-localStorage-crashes-IE8-with-empty-value-part2

 


— posted by martin at 09:36 pm   commentComment [5]  pingTrackBack [1]

T: Y: ALL: Online:
Created in 0.0046 sec.
prev
2024.3
next
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31