JavaScriptだけで角丸Box。Nifty Corners(TM)がバージョンアップ。

ちょっと前に、CSSの角丸の話題が盛り上がり気味だったみたいで、うちの記事「CSSだけで、フレキシブルな角丸ボックスを作る方法」にも結構人が来ていてびっくり。

はてなの方をみると、「tikeda::Diary – 角丸ライブラリ」が人気です。

やっている内容は、「Flexible box with custom corners and borders | 456 Berea Street」と同じなのですが、色々サンプルのバリエーションを用意していたりPSD込みだったりで、親切でよさげです。

さて、前のエントリーでも指摘されましたが、CSSだけだとどうしてもマークアップ的に汚くなってしまうという欠点があります。

マークアップを重視するなら、どうせ見た目の問題なんだし、JavaScriptとCSSでやってしまってもいいですよね。

その思想で作られたNifty Cornersというテクニックがあります。

これについては、検索していただければ、相当数の解説記事が浮かび上がってくると思いますので割愛…。

今回は、なんていうかそれがバージョンアップしてNifty Corners Cube として公開されたという内容です。

とは言っても、前回のバージョンを使ってないので何がどうなったのかあまり分かってないのですが…。

仕様やサンプルは以下の本家のページを見てもらえれば、一番良いと思います。

【本家はこちら】

■Nifty Corners Cube – freedom to round

なんていうか、ぶっちゃけこちらの方の記事に刺激されて、もうちょっと掘り下げネタです(笑)

戯れ言日記 – 角丸ライブラリかぁ

コードを簡単に読んでみる。

とりあえず、このサイトのblockquote全てに、角丸を設定してみた。

ちょっと躓いたのですが、なんか、上手く行かなかった人は、niftycube.js内で、別のCSSをリンクさせてるところを、絶対パスで書くと上手く行くかも。

var niftyOk=(document.getElementById && document.createElement && Array.prototype.push);

二つのメソッドと、後Arrayオブジェクトがpushメソッドを使える環境なら”NiftyOK!”

var niftyCss=false; String.prototype.find=function(what){ return(this.indexOf(what)>=0 ? true : false); }

Stringオブジェクトそのものに、findというメソッドを追加してます。 自分の中に、引数の文字列があったら、trueを返すという。

var oldonload=window.onload;

oldonloadというオブジェクトに、window.onloadイベントハンドラを複製

if(typeof(NiftyLoad)!=’function’) NiftyLoad=function(){};

NiftyLoad関数がなければ、作成。

if(typeof(oldonload)==’function’)
window.onload=function(){oldonload();AddCss();NiftyLoad()};
else window.onload=function(){AddCss();NiftyLoad()};

oldonloadイベントハンドラに関数が →セットがされていれば、window.onloadイベントハンドラに、oldonload、AddCss、NiftyLoad関数をセット。 →セットされてなければ、window.onloadイベントハンドラに、AddCss、NiftyLoad関数をセット。

function AddCss(){
niftyCss=true;
var l=CreateEl(“link”);
l.setAttribute(“type”,”text/css”);
l.setAttribute(“rel”,”stylesheet”);
l.setAttribute(“href”,”niftyCorners.css”);
l.setAttribute(“media”,”screen”);
document.getElementsByTagName(“head”)[0].appendChild(l);
}

■AddCss関数について。(外部CSSを読み込んでくる関数)

niftyCssにTrueをセット。多分、起動フラグ。 niftyCorners.cssというCssファイルをJavascript経由で読み込ませる。

 ※JSファイル置いてみたけど、上手く行かなかった方は、   ここのCSSのパスを絶対パスにするといいかもです。

function Nifty(selector,options){
if(niftyOk==false) return;
if(niftyCss==false) AddCss();
var i,v=selector.split(“,”),h=0;
if(options==null) options=””;
if(options.find(“fixed-height”))
h=getElementsBySelector(v[0])[0].offsetHeight;
for(i=0;i<v.length;i++)
Rounded(v[i],options);
if(options.find(“height”)) SameHeight(selector,h);
}

■Nifty関数(セレクタとオプションが引数)

基本的にNifty()→Rounded()→AddTop() , AddBottom() と関数が連携して、丸くするみたいです。こいつがスタート地点です。HTMLでヘッダ部分に書いてあげる関数です。冒頭でniftyOkじゃなければ、ここで終わり。非対応ブラウザへの配慮。 niftyCssがfalse、つまりAddCss関数が実行されてなければ、実行。 引数として与えられたセレクタ(selector)をカンマ区切りで配列vに入れて、ついでに変数iとhを作る。 optionsがnullなら、空にしておく。 optionsの中に”fixed-height”があったら、後で出てくる”getElementsBySelector”関数(これ、めっさ便利ですな)とoffsetHeightプロパティを使って、対象のエレメントに設定されてる高さを維持する。 そして、後述する”Rounded関数”に対象のエレメントとオプションを渡す。 もし、optionsの中に’height’という文字列が合ったら、対象のエレメントを全て同じ高さにする”SameHeight”関数を動かす。

function Rounded(selector,options){
var i,top=””,bottom=””,v=new Array();
if(options!=””){
options=options.replace(“left”,”tl bl”);
options=options.replace(“right”,”tr br”);
options=options.replace(“top”,”tr tl”);
options=options.replace(“bottom”,”br bl”);
options=options.replace(“transparent”,”alias”);
if(options.find(“tl”)){
top=”both”;
if(!options.find(“tr”)) top=”left”;
}
else if(options.find(“tr”)) top=”right”;
if(options.find(“bl”)){
bottom=”both”;
if(!options.find(“br”)) bottom=”left”;
}
else if(options.find(“br”)) bottom=”right”;
}
if(top==”” && bottom==”” && !options.find(“none”)){top=”both”;bottom=”both”;}
v=getElementsBySelector(selector);
for(i=0;i<v.length;i++){
FixIE(v[i]);
if(top!=””) AddTop(v[i],top,options);
if(bottom!=””) AddBottom(v[i],bottom,options);
} }

■Rounded関数(対象のエレメントと、オプションを引数に。)

まず、ここは元ドキュメントのoptionパラメータのとこを見てもらうと、すぐあれだと思うのですが、

tl 左上の角
tr 右上の角
bl 右下の角
br 左下の角
top 上二つの角
bottom 下二つの角
left 左側二つの角
right 右側二つの角
all (default) 全ての角(デフォルト)
none なし

となってます。 まず、最終的にはtlとtrとblとbrの組み合わせになるように、optionsの値を置換。 関数の中で宣言してるtopとbottomに、”left”とか”right”とかの値が入っていきます。 ここが丸くなるのね。 そして、対象のエレメントと、丸くする部分と、元のoptionsの値を、FixIE関数を通した後に、AddTop関数とAddBottom関数を動かして、実際に丸くさせていきます。

function AddTop(el,side,options){
var d=CreateEl(“b”),lim=4,border=””,p,i,btype=”r”,bk,color;
d.style.marginLeft=”-“+getPadding(el,”Left”)+”px”;
d.style.marginRight=”-“+getPadding(el,”Right”)+”px”;
if(options.find(“alias”) || (color=getBk(el))==”transparent”){
color=”transparent”;bk=”transparent”; border=getParentBk(el);btype=”t”;
}
else{
bk=getParentBk(el); border=Mix(color,bk);
}
d.style.background=bk;
d.className=”niftycorners”;
p=getPadding(el,”Top”);
if(options.find(“small”)){
d.style.marginBottom=(p-2)+”px”;
btype+=”s”; lim=2;
}
else if(options.find(“big”)){
d.style.marginBottom=(p-10)+”px”;
btype+=”b”; lim=8;
}
else d.style.marginBottom=(p-5)+”px”;
for(i=1;i<=lim;i++)
d.appendChild(CreateStrip(i,side,color,border,btype));
el.style.paddingTop=”0″;
el.insertBefore(d,el.firstChild);
}

■AddTop関数(対象エレメント , 丸くする部分 , オプション が引数)

そろそろ、実際に丸くするところみたいですー。 一気に変数を宣言。CreateElっていうのは、後で出てきますが、CreateElementのことでした。 d,lim,border,p,i,btype,bk,colorと、たくさんの変数がっ。 それぞれ、後に出てくるgetParentBk関数とかMix関数で、対象のオブジェクトにあったプロパティを、CreateElで作ったbエレメントに与えていきます。getPaddingなんていう関数、最初からあったんですね、全然知らんかったです。使えるのかな。 なんか、おっかけていくのがだんだんしんどくなってきました。こまいです。

【参照サイト】

G の索引 (共通 DOM API)

AddBottom関数はほぼ同じだから省略で…。 後、色々サブルーチン的なのも省略で…。 最後に一つだけ。 便利な getElementsBySelector関数が一番最後にあります。 ゴリゴリと、力技でセレクタを分解して、エレメントのリストにしています。 これ、他でも便利に使えそう…。

Webコンサルタント中山陽平公式サイト お悩みの方へ。一回のご相談で解決することもあります
ラウンドナップ・コンサルティングへのお問合せ方法 お電話でのご相談もお気軽に。[048-234-3361](10〜16 土日祝日除)全国対応 24時間受付 お問合せメールフォーム