JavaScript/jQuery {Article012}

説明文の表示 ライブデモを見る▶
ようこそ「JavaScript/jQuery」へ...

JavaScriptにC#のString.Format()を組み込む

JavaScriptで文字列を結合するときは「"string1" + "string2"」のように「+」を使用します。 単純な文字列を結合するのであれば特に問題ないのですが複雑な文字列を結合するときはとても不便です。 複雑な文字列を結合したり、文字列に値を代入するときにC#のString.Format()関数がとても便利です。 ここではJavaScript版のString.Format()を紹介します。

String.format()の使い方

  1. AnalogClock()関数のアナログ時計は、HTMLのDIV、H4、UL、LIタグから構成されています。 アナログ時計を実装するには、JavaScriptの「setInterval(event, 1000)」で1秒間隔にイベントを発生させて時計の針を移動させることにより実現します。 デジタル時計に興味のある方は「Article016」で解説しています。

    2021-07-13
    21:16:28

    • 1
      7
    • 2
      8
    • 3
      9
    • 4
      10
    • 5
      11
    • 6
      12


  2. 時計の針を移動させるにはCSSを使用します。具体的には行34が時針、行35が分針、行36が秒針を表示させますのでこれらのDIV要素のCSSを1秒間隔で書き換えます。 アナログ時計の1-12までの数字はペアで6回ループさせることにより表示します。1回目のループでは「1と7」、2回目のループでは「2と8」といった順番に表示させます。

    jQueryでHTMLの要素を生成するには「$.parseHTML()」を使用します。たとえば、H4要素を生成するには「$.parseHTML('<h4>2021/6/12<br />14:35:19</h4>')」のように記述します。 H4タグに「style="width: 100%; text-align: center; font-weight: normal; font-size: 26.667px; margin-top: 240px; color: rgb(0, 0, 0);"」のようなCSSを追加するときは、 固定部分の雛形(テンプレート)を用意して変動する箇所を代入するといったテクニックを使うと便利です。このときに役立つのがString.format()です。 余談ですが、ここではString.format()メソッドをプロトタイプ(prototype)に定義していますがこれはメモリを節約するためです。

    TIP:サンプルコードに行番号を追加する方法については、「Article007」を参照してください。
    
    var h4Tag = '<h4 style="width: 100%; text-align: center; font-weight: normal; font-size: {0}px; margin-top: {1}px; color: {2};"></h4>'
    	.format(this.width / 15, this.width * 0.6, this.foreColor); // テンプレートに値を代入する
    var h4 = $.parseHTML(h4Tag)[0]; // HTMLのH4要素を生成する  
    
    <div id="AnalogClockDemo">
        <div style="border-radius: 50%; background-color: rgb(255,255,255); border: 1px solid rgb(204, 204, 204); width: 400px; height: 400px; position: relative;">
            <h4 style="width: 100%; text-align: center; font-weight: normal; font-size: 26.667px; margin-top: 240px; color: rgb(0, 0, 0);">
                2021-07-05
                <br />
                14:35:19
            </h4>
            <ul style="height: 100%; padding: 0px; margin: 0px; list-style: none; position: absolute; width: 40px; top: 0px; left: 180px; color: rgb(0, 0, 0);">
                <li style="padding: 0px; margin: 0px; position: absolute; text-align: center; width: 40px; height: 400px; font-size: 40px; transform: rotate(30deg);">
                    <div style="width: 100%; position: absolute; text-align: center; transform: rotate(-30deg);">1</div>
                    <div style="width: 100%; position: absolute; text-align: center; bottom: 0px; transform: rotate(-30deg);">7</div>
                </li>
                <li style="padding: 0px; margin: 0px; position: absolute; text-align: center; width: 40px; height: 400px; font-size: 40px; transform: rotate(60deg);">
                    <div style="width: 100%; position: absolute; text-align: center; transform: rotate(-60deg);">2</div>
                    <div style="width: 100%; position: absolute; text-align: center; bottom: 0px; transform: rotate(-60deg);">8</div>
                </li>
                <li style="padding: 0px; margin: 0px; position: absolute; text-align: center; width: 40px; height: 400px; font-size: 40px; transform: rotate(90deg);">
                    <div style="width: 100%; position: absolute; text-align: center; transform: rotate(-90deg);">3</div>
                    <div style="width: 100%; position: absolute; text-align: center; bottom: 0px; transform: rotate(-90deg);">9</div>
                </li>
                <li style="padding: 0px; margin: 0px; position: absolute; text-align: center; width: 40px; height: 400px; font-size: 40px; transform: rotate(120deg);">
                    <div style="width: 100%; position: absolute; text-align: center; transform: rotate(-120deg);">4</div>
                    <div style="width: 100%; position: absolute; text-align: center; bottom: 0px; transform: rotate(-120deg);">10</div>
                </li>
                <li style="padding: 0px; margin: 0px; position: absolute; text-align: center; width: 40px; height: 400px; font-size: 40px; transform: rotate(150deg);">
                    <div style="width: 100%; position: absolute; text-align: center; transform: rotate(-150deg);">5</div>
                    <div style="width: 100%; position: absolute; text-align: center; bottom: 0px; transform: rotate(-150deg);">11</div>
                </li>
                <li style="padding: 0px; margin: 0px; position: absolute; text-align: center; width: 40px; height: 400px; font-size: 40px; transform: rotate(180deg);">
                    <div style="width: 100%; position: absolute; text-align: center; transform: rotate(-180deg);">6</div>
                    <div style="width: 100%; position: absolute; text-align: center; bottom: 0px; transform: rotate(-180deg);">12</div>
                </li>
            </ul>
            <div style="width: 4px; height: 4px; position: absolute; border-width: 162px 0px; border-style: solid; border-color: rgb(0, 153, 255) transparent transparent;  border-image: initial; left: 198px; top: 38px; transform: rotate(144deg);"></div>
            <div style="width: 8px; height: 8px; position: absolute; border-width: 104px 0px; border-style: solid; border-color: rgb(255,102, 0) transparent transparent;  border-image: initial; left: 196px; top: 96px; transform: rotate(193deg);"></div>
            <div style="width: 1px; height: 1px; position: absolute; border-width: 180px 0px; border-style: solid; border-color: rgb(0, 0, 0) transparent transparent;  border-image: initial; left: 199px; top: 20px; transform: rotate(42deg);"></div>
            <div style="width: 20px; height: 20px; position: absolute; background-color: rgb(0,0,0); left: 190px; top: 190px; border-radius: 50%;"></div>
        </div>
    </div>

作成手順

  1. VS2019(Visual Studio 2019 or Visual Studio 2022)を起動したら新規のWebフォーム「Article012.aspx」を作成します。

  2. Webフォームのヘッダータグ内「<head>...</head>」にSCRIPTタグを追加してjQueryの最新のライブラリーを取り込みます。 ここではjQuery 3.6.0のライブラリーを取り込んでいます。 さらにSCRIPTタグを追加して、次のようなJavaScript/jQueryのコードを入力します。
    
    Article012.aspx:
    
    <script src="https://code.jquery.com/jquery-3.6.0.slim.min.js" integrity="sha256-u7e5khyithlIdTpu22PHhENmPcRdFiHRjhAuHcs05RI=" crossorigin="anonymous"></script>
    <script type="text/javascript">
    
        // String.format()
        String.prototype.format = String.prototype.f = function () {
            var s = this,
                i = arguments.length;
    
            while (i--) {
                s = s.replace(new RegExp('\\{' + i + '\\}', 'gm'), arguments[i]);
            }
            return s;
        };
    
        // jQuery Document Ready Event...
        $(function () {
            // Analog Clock
            $('#btnClock').click(function () {
                AnalogClockDemo();
            });
    
            $('#selWidth').on('change', function () {
                AnalogClockDemo();
            });
    
            $('#selforeColor').on('change', function () {
                AnalogClockDemo();
            });
    
            $('#selbgColor').on('change', function () {
                AnalogClockDemo();
            });
    
            $('#selBorder').on('change', function () {
                AnalogClockDemo();
            });
    
            function AnalogClockDemo() {
                var clock = $('div#clock');
                $(clock).empty();
                var opt = new AnalogClockOption();
                opt.width = $('#selWidth option:selected').val();
                opt.foreColor = $('#selforeColor option:selected').val();
                opt.bgColor = $('#selbgColor option:selected').val();
                var clock1 = new AnalogClock("clock", opt);
                clock1.panel.style.border = $('#selBorder option:selected').val();
            }
        });
    
        // AnalogClock() Compact Version
        function AnalogClockOption(width, foreColor, bgColor) {
            this.foreColor = foreColor ? foreColor : "#000";
            this.bgColor = bgColor ? bgColor : "#eee";
            this.width = width ? width : 400;
        }
    
        function AnalogClock(id, option) {
    
            var padZero = function(num) {
                if (num < 10) {
                    num = '0' + num;
                }
                else {
                    num = num.toString();
                }
                return num;
            }
    
    
            var dateTimeFormat = function (time) {
                var str = "";
                str += time.getYear() + (time.getYear() > 1900 ? 0 : 1900) + "-";   
                str += padZero(time.getMonth() + 1) + "-";  
                str += padZero(time.getDate()) + "<br/> ";
                str += padZero(time.getHours()) + ":";
                str += padZero(time.getMinutes()) + ":";
                str += padZero(time.getSeconds());
                return str;
            }
    
            if (!option) {
                option = {};
            }                  
    
            this.foreColor = option.foreColor ? option.foreColor : "#000"; 
            this.bgColor = option.bgColor ? option.bgColor : "#eee";
            this.width = option.width ? option.width : 400;                 
    
            this.container = $('#' + id)[0];
            if (!this.container) {
                return;
            }
            this.container.style.fontcolor = this.foreColor;
    
            // the outer panel of the clock, including the background
            var divPanel = '<div style = "border-radius: 50%; background-color: {0}; border: 1px solid #ccc; width: {1}px; height: {2}px; position: relative;" >'
                .format(this.bgColor, this.width, this.width);
            this.panel = $.parseHTML(divPanel)[0];
            this.container.appendChild(this.panel); 
    
            // the digital clock on the panel            
            var h4Tag = '<h4 style="width: 100%; text-align: center; font-weight: normal; font-size: {0}px; margin-top: {1}px; color: {2};"></h4>'
                .format(this.width / 15, this.width * 0.6, this.foreColor);     
            var label = $.parseHTML(h4Tag)[0];
                label.innerHTML = dateTimeFormat(new Date());       
    
            if (this.width >= 100) {
                this.panel.appendChild(label);
            }
    
            // the container of hour numbers on the panel
            var ulTag = '<ul style="height: 100%; padding: 0px; margin: 0px; list-style: none; position: absolute; width: 40px; top: 0px; left: {0}px; color: {1};">'
                .format(this.width / 2 - 20, this.foreColor);
            var ul = $.parseHTML(ulTag)[0];
            this.panel.appendChild(ul);
    
            // the list of hour numbers on the panel
            for (var i = 0; i <= 5; i++) {
    
                if (!localStorage) {
                    break;
                }
    
                // create li element
                var liTag = '<li style="padding: 0px; margin: 0px; position: absolute; text-align: center; width: 40px; height: {0}px; font-size: {1}px; transform: rotate({2}deg);">'
                    .format(this.width, this.width / 10, 360 / 12 * (i + 1));
    
                var list = $.parseHTML(liTag)[0];
                ul.appendChild(list);
    
                // a pair of numbers, such as  1 and 7, 3 and 9, etc.
                var divTop = '<div style="width: 100%; position: absolute; text-align: center; transform: rotate({0}deg);">{1}</div>'
                    .format(-360 / 12 * (i + 1), i + 1);
                var numTop = $.parseHTML(divTop)[0];
    
                if (this.width < 100) {
                    numTop.innerHTML = "●";
                }
    
                list.appendChild(numTop);
    
                var divBottom = '<div style="width: 100%; position: absolute; text-align: center; bottom: 0px; transform: rotate({0}deg);">{1}</div>'
                    .format(-360 / 12 * (i + 1), i + 7);
    
                var numBottom = $.parseHTML(divBottom)[0];
    
                if (this.width < 100) {
                    numBottom.innerHTML = "●";
                }
    
                list.appendChild(numBottom);
            }
    
            // hour hand
            var hourWidth = this.width * 0.02;
            var hourTop = this.width * 0.25 - (hourWidth * 0.5);
            var hourleft = this.width * 0.5 - hourWidth * 0.5;
    
            var divHour = '<div style="width: {0}px; height: {1}px; position: absolute; border-width: {2}px 0px; border-style: solid; border-color: #f60 transparent transparent;  border-image: initial; left: {3}px; top: {4}px;"></div>'
                .format(hourWidth, hourWidth, this.width * 0.5 - hourTop, hourleft, hourTop);
    
            var hour = $.parseHTML(divHour)[0];
    
            if (localStorage) {
                this.panel.appendChild(hour);
            }
    
            // minute hand
            var minWidth = this.width * 0.01;
            var minTop = this.width * 0.1 - (minWidth * 0.5);
            var minleft = this.width * 0.5 - minWidth * 0.5;
    
            var divMin = '<div style="width: {0}px; height: {1}px; position: absolute; border-width: {2}px 0px; border-style: solid; border-color: #09f transparent transparent;  border-image: initial; left: {3}px; top: {4}px;"></div>'
                .format(minWidth, minWidth, this.width * 0.5 - minTop, minleft, minTop);
    
            var min = $.parseHTML(divMin)[0];
    
            if (localStorage) {
                this.panel.appendChild(min);
            }
    
            // second hand
            var secWidth = 1;
            var secTop = this.width * 0.05;
    
            var divSec = '<div style="width: {0}px; height: {1}px; position: absolute; border-width: {2}px 0px; border-style: solid; border-color: {3} transparent transparent;  border-image: initial; left: {4}px; top: {5}px;"></div>'
                .format(secWidth, secWidth, this.width * 0.5 - secTop, this.foreColor, this.width * 0.5 - secWidth, secTop);
    
            var sec = $.parseHTML(divSec)[0];
    
            if (localStorage) {
                this.panel.appendChild(sec);
            }
    
            // the center point
            var pointWidth = this.width * 0.05;
            var divPoint = '<div style="width: {0}px; height: {1}px; position: absolute; background-color: {2}; left: {3}px; top: {4}px; border-radius: 50%;"></div>'
                .format(pointWidth, pointWidth, this.foreColor, this.width * 0.5 - (pointWidth * 0.5), this.width * 0.5 - (pointWidth * 0.5));
    
            var point = $.parseHTML(divPoint)[0];
    
            if (localStorage) {
                this.panel.appendChild(point);
            }
    
            // start the clock (the animation part)
            this.loop = setInterval(function () {
                var now = new Date();
                label.innerHTML = dateTimeFormat(now);          
    
                sec.style.transform = 'rotate({0}deg)'.format(1.0 * 360 / 60 * now.getSeconds());
                min.style.transform = 'rotate({0}deg)'.format(1.0 * 360 / 60 * now.getMinutes());
                hour.style.transform = 'rotate({0}deg)'.format(1.0 * 360 / 12 * (now.getHours() % 12) + 1.0 * 360 / 12 * (now.getMinutes() / 60)); 
            }, 1000);
        }
    </script>
    
  3. Webフォームにアナログ時計を表示するために、HTMLのINPUT(type="button")、DIV、HRタグを追加します。 さらにアナログ時計の幅(Width)、前景色(foreColor)、背景色(bgColor)、ボーダー(border)をカスタマイズできるようにSELECTタグを追加します。
    
    Article012.aspx:
    
    <input id="btnClock" type="button" value="Show/Change Analog Clock" />
    Width:
    <select id="selWidth">
        <option label="100px" value="100" />
        <option label="200px" value="200" />
        <option label="300px" value="300" selected />
        <option label="400px" value="400" />
        <option label="500px" value="500" />
    </select>
    
    foreColor:
    <select id="selforeColor">
        <option label="red" value="red" />
        <option label="white" value="white" selected />
        <option label="blue" value="blue" />
    
    </select>
    
    bgColor:
    <select id="selbgColor">
        <option label="darkcyan" value="darkcyan" />
        <option label="black" value="black" selected />
        <option label="gray" value="gray" />
    </select>
    
    border:
    <select id="selBorder">
        <option label="solid 5px red" value="solid 5px red" />
        <option label="double 5px red" value="double 5px red" selected />
        <option label="dotted 5px red" value="dotted 5px red" />
    </select>
    
    <div id="clock"></div>   
    

操作手順

  1. Webページが表示されたら[Show/Change Analog Clock]のボタンをクリックします。

  2. アナログ時計は、ドロップダウンリストから時計の「幅」「前景色」「背景色」「ボーダー」を選択してカスタマイズすることができます。

Live DEMO

Width: foreColor: bgColor: border: