0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【JavaScript】入力フォームを使ったHTMLページをスッキリした見た目にする

Last updated at Posted at 2021-09-11

コードだけをみたい人は最後に全体を載せてますのでそちらへ。

それでは本題の前に、
まずは普通にhtmlでselect要素1つ、input-text要素1つを設置します。

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>text and select form</title>
</head>
<body>
	<select>
     	<option value="2021">2021</option>
	     <option value="2022">2022</option>
 	    <option value="2023">2023</option>
  	</select><br><br>
	<input type="text">
</body>
</html>

上のHTMLをブラウザで見るとselect要素とinput-text要素が表示されます。

これらを多用して「入力ページ」を作るのはいいのですが、
そのページを印刷してそのまま利用するわけにはいきません。

フォームを使ったページを印刷すると、
行がズレる、フォント・大きさ・ベースラインが合わない、見た目のイメージが変わる、
といったことが起こるからです。

HTMLの入力フォームは印刷してみるとWYSIWYGじゃないんです。

そこで、
「入力フォームを使ったHTMLページをJavaScriptでスッキリした見た目にする」
ということを考えました。

目指すのは、
文字列クリック → 入力フォームが出現 → フォーム入力終了 → フォーム消滅 → 文字列に戻る
です。

まずは、HTMLを書き換えます。

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>text and select form</title>
</head>
<body>
	<!--spanで囲みます-->
	<span>2021</span><br><br>
	<!--spanで囲みます-->
	<!--text入力変更前の文を適当に-->
	<span>textを書き換えます</span>
</body>
</html>

上のHTMLをブラウザで見ると「2021年」「textを書き換えます」がそれぞれ文字列で現れています。

次に、Javascriptで扱えるようにspanタグに「id」と「onclick」イベントハンドラを配置します。
「onclick」で起動する関数は後ほど配置します。

<html>
<head>
<meta charset="UTF-8">
<title>text and select form</title>
</head>
<body>
	<!--「id」と「onclick」を配置します-->
	<span id="year" onclick="">2021</span><br><br>
	<!--「id」と「onclick」を配置します-->
	<span id="line" onclick="">textを書き換えます</span>
</body>
</html>

次に、Javascriptの本体を書き込むscriptタグを、今回はわかりやすいようにspanタグの直下にそれぞれ配置します。

<html>
<head>
<meta charset="UTF-8">
<title>text and select form</title>
</head>
<body>
	<span id="year" onclick="">2021</span><!--scriptタグを配置します-->
 	<script>
 	</script>
<br><br>
	<span id="line" onclick="">textを書き換えます</span>
	<!--scriptタグを配置します-->
 	<script>
 	</script>
</body>
</html>

続いて、最初のscriptタグにspan id="year"用のJavaScriptを書きます。

    <span id="year" onclick="">2021</span><script>
        let spanYearTag=document.getElementById("year");
        let optionsArray=[2021,2022,2023];//select要素のoptionsの配列です

        /*span id="year"のonclickで起動する関数です*/
        function toSelect(){
            let keepNen=Number(spanYearTag.innerHTML); //span id="year"の内容を(一応数値化して)変数に格納

            /*select要素を構築します*/
            let selectElement='<select id="year-select" onchange="fromSelect()">';//idとonchangeを書きます
            for(let i=0; i<optionsArray.length; i++){//optionsArray配列からselect要素のoptionsを書きます
                selectElement+='<option value="'+optionsArray[i]+'">'+optionsArray[i]+'</option>';
            }         
            selectElement+='</select>';
            
            /*span id="year"にselect要素を配置します*/
            spanYearTag.innerHTML=selectElement;//ここでselect要素が実体化します
            
            /*表示されていた「年」と同じoptionsをselectedにします*/
            for(let i=0; i<optionsArray.length; i++){//
                if(keepNen==optionsArray[i]){
                    document.getElementById("year-select").options[i].selected=true;
                    break;
                }
            }
            
            /*span id="year"のonclickハンドラを無効にします*/
            spanYearTag.onclick=null;//spanタグ内にselectタグあるので、selectタグへのクリックが上位spanタグに影響しないようにするためです
        }

        /*select id="year-select"のonchangeで起動する関数です*/
        function fromSelect(){//
            let selectTag=document.getElementById("year-select");
            let selectNen=selectTag.value;//selectで選択されたvalueを格納
            
            /*span id="year"に選択された年を配置します*/
            spanYearTag.innerHTML=selectNen;//ここでselect要素と選択された「年」が入れ替わります

            /*span id="year"にonclickを新たに配置します*/
            spanYearTag.onclick=new Function("toSelect()");//nullにしたものを復活です
        }
    </script>

上記のJavaSciptのtoSelect関数をspan id="year"のonclickに配置します。

<html>
<head>
<meta charset="UTF-8">
<title>text and select form</title>
</head>
<body>
	<!--toSelect関数をspan id="year"のonclickに設置します-->
	<span id="year" onclick="toSelect()">2021</span><script>
 		/*--略--*/
	</script>
<br><br>
	<span id="line" onclick="">textを書き換えます</span>
 	<script>
 	</script>
</body>
</html>

次に、二つ目のscriptタグにspan id="line"用のJavaScriptを書きます。

<script>
        let spanInputTag=document.getElementById("line");

        /*span id="line"のonclickで起動する関数です*/
        function toText(){
            let keepLine=spanInputTag.innerHTML; //span id="line"の内容を変数に格納。

            /*text要素を構築します*/
            let textElement='<input type="text" id="line-text" value="'+keepLine+'"  onblur="fromText()">';//idとonchangeを書きます valueに変更前の文字列を設定します
            
            /*span id="line"にtext要素を配置します*/
            spanInputTag.innerHTML=textElement;//ここでtext要素が実体化します

            /*text要素にフォーカスします*/
            document.getElementById("line-text").focus();
            document.getElementById("line-text").select();
            /*span id="line"のonclickハンドラを無効にします*/
            spanInputTag.onclick=null;//spanタグ内にselectタグあるので、selectタグへのクリックが上位spanタグに影響しないようにするためです
        }	

        /*input text id="line-text"のonblurで起動する関数です*/
        function fromText(){//
            let textTag=document.getElementById("line-text");
            let getLine=textTag.value;//textで入力されたvalueを格納
            
            /*span id="line"に入力された文字列を配置します*/
            spanInputTag.innerHTML=getLine;//ここでtext要素と入力された文字列が入れ替わります

            /*span id="line"にonclickを新たに配置します*/
            spanInputTag.onclick=new Function("toText()");//nullにしたものを復活させます
        }
    </script>

上記のJavaSciptのtoText()関数をspan id="line"のonclickに設置します。

<html>
<head>
<meta charset="UTF-8">
<title>text and select form</title>
</head>
<body>
	<span id="year" onclick="toSelect()">2021</span><script>
 		/*--略--*/
	</script>
<br><br>
	<!--toText関数をspan id="line"のonclickに設置します-->
	<span id="line" onclick="toText()">textを書き換えます</span>
 	<script>
		/*--略--*/
 	</script>
</body>
</html>

HTMLとJavaScript全体です。

<!doctype html>
<html>
<head>
<meta charset="UTF-8">
<title>text and select form</title>
</head>
<body>
	<span id="year" onclick="toSelect()">2021</span><script>
        let spanYearTag=document.getElementById("year");
        let optionsArray=[2021,2022,2023];//select要素のoptionsの配列です

        /*span id="year"のonclickで起動する関数です*/
        function toSelect(){
            let keepNen=Number(spanYearTag.innerHTML); //span id="year"の内容を(一応数値化して)変数に格納

            /*select要素を構築します*/
            let selectElement='<select id="year-select" onchange="fromSelect()">';//idとonchangeを書きます
            for(let i=0; i<optionsArray.length; i++){//optionsArray配列からselect要素のoptionsを書きます
                selectElement+='<option value="'+optionsArray[i]+'">'+optionsArray[i]+'</option>';
            }         
            selectElement+='</select>';
            
            /*span id="year"にselect要素を配置します*/
            spanYearTag.innerHTML=selectElement;//ここでselect要素が出現します
            
            /*表示されていた「年」と同じoptionsをselectedにします*/
            for(let i=0; i<optionsArray.length; i++){//
                if(keepNen==optionsArray[i]){
                    document.getElementById("year-select").options[i].selected=true;
                    break;
                }
            }
            
            /*span id="year"のonclickハンドラを無効にします*/
            spanYearTag.onclick=null;//spanタグ内にselectタグがあるので、selectタグへのクリックが上位のspanタグに影響しないようにしています
        }

        /*select id="year-select"のonchangeで起動する関数です*/
        function fromSelect(){//
            let selectTag=document.getElementById("year-select");
            let selectNen=selectTag.value;//selectで選択されたvalueを変数に格納
            
            /*span id="year"に選択された年を配置します*/
            spanYearTag.innerHTML=selectNen;//ここでselect要素と選択された「年」が入れ替わります

            /*span id="year"にonclickを新たに配置します*/
            spanYearTag.onclick=new Function("toSelect()");//nullにしたものを復活です
        }
    </script>
<br><br>
	<span id="line" onclick="toText()">textを書き換えます</span>
<script>
        let spanInputTag=document.getElementById("line");

        /*span id="line"のonclickで起動する関数です*/
        function toText(){
            let keepLine=spanInputTag.innerHTML; //span id="line"の内容を変数に格納。

            /*text要素を構築します*/
            let textElement='<input type="text" id="line-text" value="'+keepLine+'"  onblur="fromText()">';//idとonchangeを書きます valueに変更前の文字列を設定します
            
            /*span id="line"にtext要素を配置します*/
            spanInputTag.innerHTML=textElement;//ここでtext要素が出現します

            /*text要素にフォーカスします*/
            document.getElementById("line-text").focus();
            document.getElementById("line-text").select();
            /*span id="line"のonclickハンドラを無効にします*/
            spanInputTag.onclick=null;//spanタグ内にselectタグあるので、selectタグへのクリックが上位spanタグに影響しないようにしています
        }	

        /*input text id="line-text"のonblurで起動する関数です*/
        function fromText(){//
            let textTag=document.getElementById("line-text");
            let getLine=textTag.value;//textで入力されたvalueを格納
            
            /*span id="line"に入力された文字列を配置します*/
            spanInputTag.innerHTML=getLine;//ここでtext要素と入力された文字列が入れ替わります

            /*span id="line"にonclickを新たに配置します*/
            spanInputTag.onclick=new Function("toText()");//nullにしたものを復活させます
        }
    </script>
</body>
</html>

さて、input-text要素に関してですが、
上記のJavaScriptでは、onblurで入力フォームが消えるようにしていますが、
onkeydownでEnterキーをトリガーにすることもできます。

更に上記のinput-text要素は、
value=""で入力フォームが消えてしまった場合の回避措置がありません。
value=""で消えてしまうとクリックすべき文字列がなくなりますので、次はもうクリックできません。
実際に使う場合は、value=""消えようとする時にアラート出すなりの回避措置が必要です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?