こんにちは!先日健康診断で脂肪肝と診断された橋浦です!
先日Web案件で、文字列の幅を取得してwidthに設定したい場面がありました。
しかし、その文字列はjQueryで動的に生成していたため単純なwidth();などでは取得できず…。
結局2通り方法を試して、2つ目の方法でやっと上手くいったのでした。
今回は、せっかくなのでその方法を紹介してみたいと思います。
① 文字数を数えて、数から判断しちゃう
プログラミングに関してチンパンジー並の経験と知識しかない僕が浅知恵を絞って最初に思いついた方法です。
幅は取れないけど、consoleで調べたら文字列の内容は取得できている模様。
なら、文字数を取得して、その数を幅にしちゃえばいいじゃないッ!!!!!
ということで書いたソースがこちら。
DEMO
1 2 |
var textLength1 = $(".textArea").text().length; $(".textWidth").css({"width":textLength1 + "em"}); |
取得した文字数に単位”em”をつけてそのまんま幅にしちゃってます。
確かにこの方法でピッタリ幅になっている文字列もありました。
ですがこの方法、小文字や数字、記号のことは全く考えられておりません…。
ちょっとでもそれらが入っていると余計に大きく幅が取られてしまい、全然駄目駄目に。
ピッタリ幅を取るためには、違う方法を考える必要がありました。
② 1回書き出しをして、そこから幅を取っちゃう
この方法はこのサイト様を参考にさせて頂きました。
みかづきブログ その3 jqueryで動的につくったテキストの幅を取得する
まず元ソースはこちら。
DEMO
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
// forked from kimmy's "テキストの長さを計測する(仮)" http://jsdo.it/kimmy/61Uq (function(win, doc, $) { 'use strict'; var $txt = $("<span>"), width; $txt.text('おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。おっしゃ。れっつ。世界征服。'); width = getWidth($txt); doc.write(width + 'px'); function getWidth($txt, opt_max) { var $body = $(document.body), $dummyWrapper = $('<div>'), $dummy = $('<span>'), width; $dummyWrapper.css({ position: 'absolute', top: 0, left: 0, width: opt_max || 9999, 'z-index': -1 }); $dummy.text($txt.text()); $dummy.css({ color: 'transparent', font: $txt.css('font'), 'letter-spacing': $txt.css('letter-spacing') }); $body.append($dummyWrapper.append($dummy)); width = $dummy.width(); setTimeout(function() { $dummy.remove(); }, 0); return $dummy.width(); } })(this, document, $); |
次に独自に変更したソースはこちら。
DEMO
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 32 33 34 35 36 |
$(function(){ var $txtBox = $(".textArea").text(); width = getWidth(textBox); $(".textWidth").css({"width":width + "px"}); }); function getWidth($txt, opt_max) { var $body = $(document.body), $dummyWrapper = $('<div class="testArea">'), //変更点1 $dummy = $('<span class="testText">'), //変更点2 width; $dummyWrapper.css({ position: 'absolute', top: 0, left: 0, width: opt_max || 9999, 'z-index': -1 }); $dummy.text($txt.text()); $dummy.css({ color: 'transparent', //変更点3 'letter-spacing': $txt.css('letter-spacing') }); $body.append($dummyWrapper.append($dummy)); width = $dummy.width(); setTimeout(function() { $dummyWrapper.remove(); //変更点4 }, 0); return width; //変更点5 } |
何をしてるかというと、
① testAreaというクラス名のdiv要素を新たに作る。
② その中にtestTextというクラス名のspan要素を作る。
③ ②で作った要素内に、幅を取りたい文字列を書き出す。
④ 書き出した後で、testTextの幅を取得し、widthという名前で定義する。
⑤ このままでは要素作りっぱなしになっちゃうので、testAreaを削除する。
⑥ returnで④で定義したwidthを返す。
ざっと上記のことを上記の順番でしています。
あらかじめ入っていないと取得できないのなら、一度実際に書き出してしまえばいいじゃない!!
という発想のもと、書き出した幅を取得してから設定するという方法を取っています。
また、変更ソースには元ソース様から変更した点がコメントアウトで記入されております。
変更点に対する変更内容は以下のようになっております。
変更点1と変更点2では、class名の追加をしています。
変更点3では、CSSのfontの指定を削除。
変更点4では、remove対象を$dammyWrapperにしています。
変更点5では、returnを単にwidthとしています。
変更点3は削除のみしていますが、これでは当然意図した幅を取得できません。
なので、CSSに以下の記述を追加してください。
DEMO
1 2 |
.testArea .testText { font-size: 14px;} //ここには取得したい文字列のフォントサイズを入力 |
なぜわざわざfontの指定をCSSファイルの中に変更したかというと、こちらIE対策になっております。
IE以外のブラウザではちゃんとjs側のfunction getWidth()の中でしているフォント指定が効いているのですが、なぜかIEでは効かないのでCSSファイルの方に記述しました。ほんとIE様カンベンして。
何はともあれ、これで文字列の幅が綺麗に取れました。
おわりに
Webサイト制作って何が大変かって、クロスブラウザ対応ですよね。
CSSの指定一つとってもブラウザ毎に様々な解釈があったりして表示がズレにズレたり…。
もしかしたら今回の文字列が取得できなかった問題も、もっとスマートな方法があったかもしれません。
コーダー道は続くよどこまでも。これからもIE様に悩まされながら精進していきたいと思います。
では皆様、また会う日まで!