今どきの入力フォームはこう書け!「radioボタン編」

2021/05/27

HTML テクノロジー 特集

t f B! P L
eyecatch アラフィフだけど、まだまだ現役プログラマーの、弓削田です。 スマートフォンファースト然り、最新のwebサービス開発や、今どきのホームページを作るときのお問い合わせフォームなどで、 入力フォームを便利に使うことも多いかと思います。 そんな中、入力フォームもどんどん進化してきていますが、 その進化がユーザーライクではなく、なんとも扱いづらくなっているという事も否めません。 多くのフロントエンジニアがこうした事態に頭を悩ませて、時間を費やして、結果的に、 適当なライブラリに手を出して、無駄なパケットと、処理負荷を上げてしまう結果になっている人もいるんじゃないでしょうか? そんな入力フォームをどのwebブラウザで表示しても、安定して表示できる書き方として、 僕がいつも書いている書き方を紹介したいと思います。 今回は、その中で、radioボタンの書き方のソースコードを紹介しますね。

ブラウザごとの見栄え

<label><input type="radio" name="test" value="1">1</label><br> <label><input type="radio" name="test" value="2">2</label> 標準的なradioボタンを、ブラウザ別に表示してみます。

GoogleChrome

Firefox

Safari

iPhone

PCブラウザとスマホブラウザでは、まるでデザインが違っているのがわかります。 でも、CSSだけでここから変更するのは、少ししんどいし、どこまで行っても、ブラウザ依存系の問題がつきまといます。 そこで、どのブラウザでも同じ表示がされる書き方として、別のエレメントを作ってしまえばいいじゃんというやり方をします。

ソースコード

index.html <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="radio.css"> <script src="radio.js"></script> </head> <body> <label><input type="radio" name="test" value="1">1</label><br> <label><input type="radio" name="test" value="2" checked>2</label> </body> </html> radio.css span[type="radio"]{ border:2px solid orange; position:relative; display:inline-block; width:32px; height:32px; border-radius:50%; vertical-align:middle; margin:4px; cursor:pointer; } span[type="radio"][data-checked="true"]:before{ content:""; background-color:orange; width:80%; height:80%; display:block; position:absolute; top:50%; left:50%; transform:translate(-50%,-50%); border-radius:50%; } input[type="radio"][data-designed="1"]{ display:none; } radio.js window.$$radio = (function(){ // labelタグに入っているradioボタンの一覧を取得 let MAIN = function(){ let radios = document.querySelectorAll("label input[type='radio']"); if(!radios){return;} for(let radio of radios){ this.set_radio_button(radio); } }; // ラジオボタンの設定フロー MAIN.prototype.set_radio_button = function(radio){ if(!radio){return;} this.make_radio_button_design(radio); this.make_radio_button_event(radio); }; // 表示するラジオボタンエレメントの作成 MAIN.prototype.make_radio_button_design = function(radio){ if(!radio){return;} let span = document.createElement("span"); span.setAttribute("type" , "radio"); if(radio.name){ span.setAttribute("name" , radio.name); } if(radio.value){ span.setAttribute("value" , radio.value); } if(radio.className){ span.setAttribute("class" , radio.className); } radio.parentNode.insertBefore(span , radio); radio.setAttribute("data-designed" , "1"); this.check_radio(radio); }; // ラジオボタンにイベントセット MAIN.prototype.make_radio_button_event = function(radio){ if(!radio){return;} radio.addEventListener("click" , (function(e){ this.check_radio(e.target); }).bind(this)); }; // ラジオボタンのチェック状態を判定してspanを書き換える処理 MAIN.prototype.check_radio = function(target_elm){ if(!target_elm){return;} let radios = document.querySelectorAll("input[type='radio'][name='"+ target_elm.name +"']"); for(let radio of radios){ let span = radio.parentNode.querySelector("span[type='radio']"); if(!span){return;} if(radio.checked === true){ span.setAttribute("data-checked" , "true"); } else{ span.setAttribute("data-checked" , "false"); } } }; return MAIN; })(); // 起動処理(ページ読み込み完了を待ってスタート) switch(document.readyState){ case "complete" : new $$radio(); break; case "interactive" : window.addEventListener("DOMContentLoaded" , function(){new $$radio()}); break; default : window.addEventListener("load" , function(){new $$radio()}); break; }

表示サンプル

デモ

See the Pen efo-radio by YugetaKoji (@geta1972) on CodePen.

ちょこっと解説

inputタグのradioボタン(type)がlabelタグに囲まれているものをすべて置換する仕様にしています。 cssも自動で読み込むようにもできますが、とりあえずわかりやすいかと思って、簡易な書き方でご紹介するようにしました。 labelタグ内にかかれているradioボタンは、別のエレメントに置き換えてもクリック対応ができてしまうという HTMLの特性を利用した構成になっているんですね。 デザインに関して、オレンジ色のラジオボタンを表示していますが、 他のスタイルに変えたい場合は、cssファイルのspanタグとそのbefore疑似属性の箇所を変更(または、別CSSで上書き)することで、 簡単にデザイン変更は可能です。 javascriptファイルに、簡単なコメントを入れているので、見てもらうと非常にシンプルに処理しているのがわかってもらえると思います。 わざわざライブラリなんかダウンロードしてインクルードしなくても、 これぐらいのソースで、簡単にできてしまうので、処理の高速化をしたい人には、オススメですね。 ラジオボタンの表示を、そのまま別のエレメントに切り替えているので、そりゃあデザイン的に差がでなくなるのは、問題ないわけです。 ラジオボタンに仕込まれているイベントなども、このプログラムでは自動的に処理されるので、HTMLソースをそのままの状態で 簡単にデザイン置き換えができるので、使い勝手もいいと思いますよ。 この調子で、次はチェックボックス行ってみますか。

人気の投稿

このブログを検索

ごあいさつ

このWebサイトは、独自思考で我が道を行くユゲタの少し尖った思考のTechブログです。 毎日興味がどんどん切り替わるので、テーマはマルチになっています。 もしかしたらアイデアに困っている人の助けになるかもしれません。

ブログ アーカイブ