jQuery によるCSSの操作

今回は、jQuery のライブラリの eachメソッドを使ってループをかけ、DOM(Document Object Model)の Class を操作してリストのバックグラウンドのCSSを変更する方法をご紹介します。

 

<head>
<style type="text/css">
  .even { background-color: #ffffff; }
  .odd { background-color: #cccccc; }
 </style>
<script src="./jquery-1.6.4.js" type="text/javascript"></script>
<script type="text/javascript">
  (function ($) {
    $(document).ready(function() {
        $("ul > li").each(function(i) {
        if (i % 2 ==1) {
        $(this).addClass("odd");
          }
          else {
            $(this).addClass("even");
          }
        });
      });
  }) (jQuery);
</script>
</head>
<body>
  <h2>Plainswalker</h2>
    <ul>
      <li>Ajani</li>
      <li>Jace</li>
      <li>Liliana</li>
      <li>Chandra</li>
      <li>Garruk</li>
      <li>Elspeth</li>
      <li>Tezzeret</li>
      <li>Sorin</li>
      <li>Nahiri</li>
      <li>Nissa</li>
    </ul>
</body>

jQuery からDOM を操作する方法として応用できるのではと思いました。
訂正)Plainswalker のスペルミスを訂正

jQuery のアコーディオン

今回は、フロントエンドで頻繁に使われる、jQuery のパーツ、アコーディオンのパターンをおさらいしました。

https://stuffy.mydns.jp/~gusachan/javascript/accordion.html

アコーディオンも項目を複数展開できるものから、閉じるボタンが付いたものなどヴァリエーションが豊富なんですね。

まだ、CSS を勉強していない自分は「いや~キツイっす。」

jQueryクックブック 大型本 – 2010/8/18
jQuery Community Experts (著),‎株式会社クイープ (翻訳) -Amazon.co.jp

訂正)アコーディオンの高さを変える、accordion.css のプロパティ、height を訂正して再送しています。

.accordion.dd {
        color: #666;
        font-size: 11px;
        overflow: hidden;
        height: 70px; ← 270pxから70px に

Windows10 ログイン画面の壁紙

Windows10 のログイン画面の壁紙は、

ASCII.jp:Windowsの起動時に表示される「きれいな写真」は何?

にあるとおり、「%USERPROFILE%\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets」に450kB以上のファイルに拡張子なしで .jpg ファイルとして保存されています。[このファイルを開く方法を選んでください。] でInternet Explorerなどのアプリでファイルを開くと綺麗な写真が閲覧できます。

「名古屋城」(画像をクリックするとスライドショーが閲覧できます。)

小学校の先生を忖度した掛け算

ポイントは、足し算のループを使って乗算の演算子を使わずに掛け算の結果を格納する点です。

for (k=1; k <= j; k += 1) {     // i+i+・・・+i をj回繰り返すループ
    mat[i][j] += i;        // 配列に格納
}

https://stuffy.mydns.jp/~gusachan/javascript/multiplicativeMatrix.html

// (m x n)の2次元配列を定義

Array.matrix = function (m, n, initial) {
    var a, i, j, mat = [];
      for (i=1; i < m; i += 1) {
        a = [];
        for (j = 0; j < n; j += 1) {
          a[j] = initial;
        }
        mat[i] = a;
      }
      return mat;
}

// ゼロで埋められた 10 X 10 の行列を生成する

var myMatrix = Array.matrix(10, 10, 0);

// 配列にループで九九の計算結果を入力する

Array.multiplicative = function (n) {
    var i, j, mat = Array.matrix(n, n, 0);
    for (i=1; i < n; i += 1) {
      for (j=1; j < n; j += 1) {
        for (k=1; k <= j; k += 1) {        // i+i+・・・+i をj回繰り返すループ
          mat[i][j] += i;        // 配列に格納
        }
        mat[i][j] = i +" ×" +  j + " =" + mat[i][j]  kループ外で出力
      }
    }
    return mat;
};

myMatrix = Array.multiplicative(10);

// 生成された行列を書き出すメソッド

Array.output = function (m, n) {
  window.onload = function() {
    var mat = Array.multiplicative(n);
    var divId = document.getElementById('result');
    var table = document.createElement('table');
    divId.appendChild(table);
    var tbody = document.createElement('tbody');
    table.appendChild(tbody);
    for (var i = 1; i < m; i++) {
      var tr = document.createElement('tr');
      for (var j = 1; j < n; j++) {
        var td = document.createElement('td');
        td.innerHTML = myMatrix[i][j];
        tr.appendChild(td);
      }
      tbody.appendChild(tr);
    }
    return mat;
  }
};

printMatrix = Array.output(10,10);

プログラムのバグ修正

過去のエントリーのJavaScriptの連立一次方程式の解の分数表示のバグの件でしばらく放置状態だったことをお詫び申し上げます。詳細は以下の通りで、

分数の表示

分子と分母の絶対値をとってからユークリッド互除法で最大公約数を求めて、分母がプラスかマイナスかで条件分岐して、分母と最大公約数が等しいとき(分母=1のとき非表示)、分母と最大公約数が等しくないときを、解(x とy)でそれぞれで条件分岐して、分母にマイナスがあれば符号変換するフローに考え違いがあった模様。(ちょっと考えれば自明だったんですけどね。

[pmath]z=ad-bc<0[/pmath]のとき

[pmath]x=-{dp-bq}/{delim{|}{ad-bc}{|}}[/pmath]

[pmath]y=-{aq-cp}/{delim{|}{ad-bc}{|}}[/pmath]

var x1= d1*p1-b1*q1, y1 = a1*q1-c1*p1, z1 = a1*d1-b1*c1, x2 = Math.abs(x1), y2 = Math.abs(y1), z2 = Math.abs(z1);

if(z1 > 0) {
 if(gcdmemo(x2,z2) == z2) {
  document.getElementById('x').innerHTML = "x = " + x1/gcdmemo(x2,z1);
  if(gcdmemo(y2,z2) == z2) {
   document.getElementById('y').innerHTML = "y = " + y1/gcdmemo(y2,z1);
  }
  else {
   document.getElementById('y').innerHTML = "y = " + y1/gcdmemo(y2,z1) + "/" + z1/gcdmemo(y2,z1) + " = " + y1/z1;
  }
 }
 else {
  document.getElementById('x').innerHTML = "x = " + x1/gcdmemo(x2,z1) + "/" + z1/gcdmemo(x2,z1) + " = " + x1/z1;
  if(gcdmemo(y2,z2) == z2) {
   document.getElementById('y').innerHTML = "y = " + y1/gcdmemo(y2,z1);
  }
  else {
   document.getElementById('y').innerHTML = "y = " + y1/gcdmemo(y2,z1) + "/" + z1/gcdmemo(y2,z1) + " = " + y1/z1;
  }
 }
}
else {
 if(gcdmemo(x2,z2) == z2) {
  document.getElementById('x').innerHTML = "x = " + (-1)*x1/gcdmemo(x2,z2);
  if(gcdmemo(y2,z2) == z2) {
   document.getElementById('y').innerHTML = "y = " + (-1)*y1/gcdmemo(y2,z2);
  }
  else {
   document.getElementById('y').innerHTML = "y = " + (-1)*y1/gcdmemo(y2,z2) + "/" + z2/gcdmemo(y2,z2) + " = " + y1/z1;
  }
 }
 else {
  document.getElementById('x').innerHTML = "x = " + (-1)*x1/gcdmemo(x2,z2) + "/" + z2/gcdmemo(x2,z2) + " = " + x1/z1;
  if(gcdmemo(y2,z2) == z2) {
   document.getElementById('y').innerHTML = "y = " + (-1)*y1/gcdmemo(y2,z2);
  }
  else {
   document.getElementById('y').innerHTML = "y = " + (-1)*y1/gcdmemo(y2,z2) + "/" + z2/gcdmemo(y2,z2) + " = " + y1/z1;
  }
 }
}

JavaScript のカレンダー例

こちらのサイトでJavaScriptのカレンダーの作り方が載っていたので年間カレンダーを作ってみました。

コピペでスミマセン。センセンシャル。

http://cya.sakura.ne.jp/java/calendar.htm

window.onload = function() {
  createMonth = function(thisMonth) {
    var myDate = new Date();
    var arrWeek = new Array("日","月","火","水","木","金","土");
    var monthNum = new Array(31,28,31,30,31,30,31,31,30,31,30,31);
    myYear = myDate.getFullYear();
    if ((myYear%4 == 0 && myYear%100 != 0) || myYear%400 == 0){
      monthNum[1] = 29;
    }
    myMonth = myDate.getMonth();
    today = myDate.getDate();
    myDate.setMonth(thisMonth);
    myDate.setDate(1);
    weekDay = myDate.getDay();
    tblLine = Math.ceil((weekDay + monthNum[thisMonth])/7);
    var tblArr = new Array(7*tblLine);
    for (i = 0; i < 7*tblLine; i++) tblArr[i] = " ";
    for (i = 0; i < monthNum[thisMonth]; i++) tblArr[i + weekDay] = i + 1;
    var title = document.createElement('caption' + thisMonth);
    var divId = document.getElementById('result' + thisMonth);
    title.innerHTML = myYear + "年" + (thisMonth+1) + "月 ";
    var table = document.createElement('table');
    divId.appendChild(title);
    divId.appendChild(table);
    table.id = 'data' + (thisMonth);
   var tbody = document.createElement('tbody');
    tbody.id = 'tbodyID';
    table.appendChild(tbody);
    var tr0 = document.createElement('tr');
    for (var i = 0; i < 7; i++) {
      var td0 = document.createElement('td');
      td0.innerHTML = arrWeek[i];
      tr0.appendChild(td0);
    }
    tbody.appendChild(tr0);
    for (var i = 0; i < tblLine; i++) {
      var tr = document.createElement('tr');
      for (var j = 0; j < 7; j++) {
        var td = document.createElement('td');
        td.innerHTML = tblArr[j + i*7];
        if (myMonth == thisMonth && tblArr[j + i*7] == today) {
          td.style.backgroundColor = 'black';
          td.style.color = 'white';
        }
        tr.appendChild(td);
      }
      tbody.appendChild(tr);
    }
  }
  for (var i = 0; i < 12; i++) {
    createMonth(i);
  }  
}
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
  <meta http-equiv="Content-Style-Type" content="text/css" />
  <meta http-equiv="Content-Script-Type" content="text/javascript" />
  <script type="text/javascript" src="./calendar.js"></script>
</head>
<body>
<div class="box">
<div id="result0" style="position:absolute;top:20px;left:50px"></div>
<div id="result1" style="position:absolute;top:20px;left:250px"></div>
<div id="result2" style="position:absolute;top:20px;left:450px;"></div>
<div id="result3" style="position:absolute;top:20px;left:650px;"></div>
<div id="result4" style="position:absolute;top:220px;left:50px"></div>
<div id="result5" style="position:absolute;top:220px;left:250px;"></div>
<div id="result6" style="position:absolute;top:220px;left:450px;"></div>
<div id="result7" style="position:absolute;top:220px;left:650px;"></div>
<div id="result8" style="position:absolute;top:440px;left:50px;"></div>
<div id="result9" style="position:absolute;top:440px;left:250px;"></div>
<div id="result10" style="position:absolute;top:440px;left:450px;"></div>
<div id="result11" style="position:absolute;top:440px;left:650px;"></div>
</div>
</body>
</html>

tableに九九を表示するメソッド

以前のエントリーで javascriptの2次元配列の生成 についてwriteln()メソッドを用いて単位行列を表示するスクリプトをアップしました。

今回はその応用でcreateElement() メソッドを用いてtableに九九を表示するスクリプトを作ってみました。

Array.matrix = function (m, n, initial) {
    var a, i, j, mat = [];
      for (i=0; i < m; i += 1) {
        a = [];
        for (j = 0; j < n; j += 1) {
          a[j] = initial;
        }
        mat[i] = a;
      }
      return mat;
}

// ゼロで埋められた 10 X 10 の行列を生成する

var myMatrix = Array.matrix(10, 10, 0);

Array.multiplicative = function (n) {
    var i, j, mat = Array.matrix(n, n, 0);
    for (i=1; i < n; i += 1) {
      for (j=1; j < n; j += 1) {
        mat[i][j] = i + " x " + j + " = " + i*j;
      }
    }
    return mat;
};

// 九九が入力された配列を生成する

myMatrix = Array.multiplicative(10);

// 生成された行列を書き出すメソッド

Array.output = function (m, n) {
  window.onload = function() {
    var mat = Array.multiplicative(n);
    var divId = document.getElementById('result');
    var table = document.createElement('table');
    divId.appendChild(table);
    var tbody = document.createElement('tbody');
    table.appendChild(tbody);
    for (var i = 1; i < m; i++) {
      var tr = document.createElement('tr');
      for (var j = 1; j < n; j++) {
        var td = document.createElement('td');
        td.innerHTML = myMatrix[i][j];
        tr.appendChild(td);
      }
      tbody.appendChild(tr);
    }
    return mat;
  }
};

printMatrix = Array.output(10,10);

スタイルシートでテーブル制御

JavaScript でHTMLタグのテーブル行<tr id=”foo”>の表示、非表示を切り替えるスクリプト

document.getElementById('foo').style.display = "none";  // 非表示
document.getElementById('foo').style.display = "";      // 表示

テーブル制御するには、同じページのリンクにリロードせずに動的に(onclick)イベント処理をする関数を実装する必要がありますね。本来はPHPが得意な分野だと思った。(粉みかん

jQuery の fullcalendar

jQuery カレンダーfullcalendarを使ってみました。

参考URL: 多機能のカレンダーを実装するjQueryプラグインのFullCalendar

リンク先 Download|FullCalender からzip ファイルをダウンロード、解凍。最新版は、fullcalendar-3.2.0.zip (2017年3月7日現在)

カレントディレクトリに./fullcalendar.min.css, ./fullcalender.js, ./lib/moment.min.js, ./lib/jquery.min.js, ./lib/jquery-ui.min.js, ./fullcalendar.js, ./locale/ja.js を以下の配置でindex.html を作ります。

<html>
<head>
<meta charset='utf-8' />
<link href="./fullcalendar.min.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="./lib/moment.min.js"></script>
<script type="text/javascript" src="./lib/jquery.min.js"></script>
<script type="text/javascript" src="./lib/jquery-ui.min.js"></script>
<script type="text/javascript" src="./fullcalendar.min.js"></script>
<script type="text/javascript" src="./locale/ja.js"></script>
<script type="text/javascript">
$(document).ready(function() {
  $('#calendar').fullCalendar();
});
</script>
</head>
<body>
<div id="calendar"></div>
</body>
</html>

demos ディレクトリの selectable.html ではイベントを書き加えることができます。しかし、データとして保存するにはPHPと連携してJsonデータの受け渡しを実装しないといけないので難易度高めに感じました。
Google カレンダー、使おう!(直球)

ちなみにシェルスクリプトでは、

$ cal [-y] month year

参考URL: http://webcache.googleusercontent.com/search?q=cache:Ui3UAAmc3nMJ:sookibizviz.blog81.fc2.com/blog-entry-344.html+&cd=3&hl=ja&ct=clnk&gl=jp

小数係数の処理

前回のエントリーでは連立1次方程式の解の分数表示、分母の符号処理について冗長なコードを書いてみました。(エレガントな方法ではありませんが・・・。)

https://stuffy.mydns.jp/~gusachan/javascript/SimultaneousEquations.html

今回は、小数係数の取り扱いについて考えてみたいと思います。

  function isInteger(w) {
    w = parseFloat(w);
    return Math.round(w) === w;
  }
  var getDecimalPointLength = function(number) {
    var numbers = String(number).split('.'),
        result  = 0;
    if (numbers[1]) {
        result = numbers[1].length;
    }
    return result;
  };
  if(!(isInteger(a1) && isInteger(b1) && isInteger(p1))) {
    var s1 = getDecimalPointLength(a1);
    var t1 = getDecimalPointLength(b1);
    var u1 = getDecimalPointLength(p1);
    var v1 = Math.max(s1, t1, u1);
    var a1 = a1*Math.pow(10, v1);
    var b1 = b1*Math.pow(10, v1);
    var p1 = p1*Math.pow(10, v1);
  }
  if(!(isInteger(c1) && isInteger(d1) && isInteger(q1))) {
    var s2 = getDecimalPointLength(c1);
    var t2 = getDecimalPointLength(d1);
    var u2 = getDecimalPointLength(q1);
    var v2 = Math.max(s2, t2, u2);
    var c1 = c1*Math.pow(10, v2);
    var d1 = d1*Math.pow(10, v2);
    var q1 = q1*Math.pow(10, v2);
  }
  var x1= d1*p1-b1*q1, y1 = a1*q1-c1*p1;
  var z = a1*d1-b1*c1, z1 = Math.abs(z);

連立方程式の片方、または両方に小数係数が含まれている場合、小数点以下の桁数を取得し、方程式を10の最大桁数のべき乗倍して係数を宣言し直す方法を採りました。

また割り切れない分数の定量化として小数表示併記を追加しました。

参考URL: http://shanabrian.com/web/javascript/get-decimal-point-length.php

http://blog.at-human.com/2016/02/10/js%E6%95%B4%E6%95%B0%E3%81%8B%E3%81%A9%E3%81%86%E3%81%8B%E3%82%92%E5%88%A4%E5%88%A5%E3%81%99%E3%82%8B%E9%96%A2%E6%95%B0%EF%BC%88isinteger%EF%BC%89/