#分数の入力ができない
算数のWeb教材を作成したとき、整数と小数はキーボードから入力できるが、「分数は入力できない」という問題にぶつかりました。このような場合には、「選択肢を用意する」という方法で対処を行うのが普通です。でも、小学生のプリント問題で、分数でしか回答できない場合に「選択肢から選ぶ」というのは、あまりに不自然な感じがします。そこで「分数を入力する」ために、数学用ソフトウェアキーボードをJavaScriptで作ってみました。
分数に加えて、「ルート √ 累乗 23 パイ π」も入力できるようにして、中学校数学のWeb教材に対応するソフトウェアキーボードの作成を目標としました。
#サンプルサイト
今回のサンプルサイトはこちらです。
http://iwate-manabi-net.sakura.ne.jp/math_software_keyboard/
ソフトウェアキーボードを利用した教材サンプルはこちらです。
http://www1.iwate-ed.jp/tantou/joho/material/g-tablet-m/index.html
#MathJax を使って数式を表示
数式の表示にはMathJaxをJavaScriptライブラリとして利用しました。
https://www.mathjax.org/
最新版のMathJax3が公開になっていますが、今回は古いバージョンを使用します。WARNINGが表示されますが、気にせず使っていきましょう。
使い方についてはこちらのページを参照願います。
http://www.eng.niigata-u.ac.jp/~nomoto/download/mathjax.pdf
#HTMLソース
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script type="text/x-mathjax-config">
MathJax.Hub.Config({ tex2jax: { inlineMath: [['$','$'], ["\\(","\\)"]] } });
</script>
<script type="text/javascript"
src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS_HTML">
</script>
<script src="js/jquery.min.js"></script>
<script src="js/jquery-ui.min.js"></script>
<script src="js/jquery.ui.touch-punch.js"></script>
<script src="math_software_keyboard.js"></script>
<link rel="stylesheet" href="math_software_keyboard.css">
<title>数学用ソフトウェアキーボード</title>
</head>
<body>
<h1>数学用ソフトウェアキーボード</h1><br>
<div id="setumei">
1 次の計算をしなさい。<br>
※ 例: <span class='siki'>\(2\sqrt{3}\)</span> の入力→ 「2」「ルート」「3」
</div><br>
<div style='float:left'>
(1) <span class='siki'>\(3\sqrt{5}+6\sqrt{5}\)</span><br>
<span id='buttonShow1' class='buttonShowClass'>クリックして答えを入力</span>
答 <span id='kotae1' class='siki'><font size='3'></font></span>
<span id='maru1' class='maru'>○</span>
</div>
<div id='kaisetu1' class='kaisetu'></div>
<div style='clear: both'></div>
<div id='inputButton1'></div><br><br>
</body>
</html>
#CSSソース
/* math_software_keyboard.css */
#setumei{
font-weight: bold;
color: #060;
}
.buttonShowClass{
background-color: #cff;
padding: 10px 10px 10px 10px;
border-radius:4px;
border:1px solid #bbd;
box-shadow:2px 2px 2px 2px rgba(200, 200, 200, 0.4);
margin: 0px 5px;
cursor:pointer;
}
.waku{
user-select: none; /* CSS3 単語を選択させない */
-moz-user-select: none; /* Firefox */
-webkit-user-select: none; /* Safari、Chromeなど */
-ms-user-select: none; /* IE10かららしい */
-webkit-tap-highlight-color:#fff;
background-color: #eef;
padding: 10px 5px 5px 5px;
border-radius:4px;
border:1px solid #888;
box-shadow:2px 2px 2px 2px rgba(200, 200, 200, 0.4);
margin: 0px 5px;
width:800px;
}
.bs{
user-select: none; /* CSS3 単語を選択させない */
-moz-user-select: none; /* Firefox */
-webkit-user-select: none; /* Safari、Chromeなど */
-ms-user-select: none; /* IE10かららしい */
-webkit-tap-highlight-color:#fff;
background-color: #ccf;
padding: 10px 10px 10px 10px;
border-radius:4px;
border:1px solid #999;
box-shadow:2px 2px 2px 2px rgba(200, 200, 200, 0.6);
margin: 0px 5px;
cursor:pointer;
font-weight:bold;
}
.bc{
user-select: none; /* CSS3 単語を選択させない */
-moz-user-select: none; /* Firefox */
-webkit-user-select: none; /* Safari、Chromeなど */
-ms-user-select: none; /* IE10かららしい */
-webkit-tap-highlight-color:#fff;
background-color: #ffa;
padding: 10px 5px 10px 5px;
border-radius:4px;
border:1px solid #aaa;
box-shadow:2px 2px 2px 2px rgba(200, 200, 200, 0.6);
margin: 0px 5px;
cursor:pointer;
}
.maru{
user-select: none; /* CSS3 単語を選択させない */
-moz-user-select: none; /* Firefox */
-webkit-user-select: none; /* Safari、Chromeなど */
-ms-user-select: none; /* IE10かららしい */
-webkit-tap-highlight-color:#fff;
vertical-align: middle;
color: red;
opacity:0;
font-size: 500%;
}
.siki{
font-size: 130%;
}
.kaisetu{
user-select: none; /* CSS3 単語を選択させない */
-moz-user-select: none; /* Firefox */
-webkit-user-select: none; /* Safari、Chromeなど */
-ms-user-select: none; /* IE10かららしい */
-webkit-tap-highlight-color:#fff;
color: blue;
font-size: 120%;
}
#JavaScriptソース
var mondaiMax= 1; // 問題数
var kaitouNumber=0;
var kaitouText = new Array();
var buttonText = new Array();
for(var i=0; i<= mondaiMax ; i++){ //問題数
buttonText[i] = [];
for(var j=0; j<20; j++){
buttonText[i][j] = '';
}
}
var buttonCheckText ="";
var buttonMax = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]; // 初期値 0
var kaisetuText = "";
// 入力用のボタン表示
var bData ="";
bData = bData + "<div id='inputNow' class='waku'><br>";
//bData = bData + "<br>";
bData = bData + "<span id='bbb' class='bs'>分母入力</span><span id='bbe' class='bs'>分数おわり</span>";
bData = bData + "<span id='brs' class='bs'>ルート</span><span id='bre' class='bs'>ルートおわり</span>";
bData = bData + "<span id='bpi' class='bs'>π</span><span id='bpw' class='bs'>累乗</span>";
bData = bData + "<span id='bpm' class='bs'>±</span>";
bData = bData + " <span id='bal' class='bc'>すべて消す</span><br><br><br>";
bData = bData + "<span id='bt' class='bs'>+</span><span id='bh' class='bs'>-</span><span id='bk' class='bs'>×</span>";
bData = bData + "<span id='bw' class='bs'>÷</span><span id='bi' class='bs'>=</span>";
bData = bData + "<span id='bks' class='bs'>(</span><span id='bke' class='bs'>)</span>";
bData = bData + "<span id='ma' class='bs'>a</span><span id='mb' class='bs'>b</span><span id='mc' class='bs'>c</span>";
// bData = bData + "<span id='md' class='bs'>d</span>";
bData = bData + "<span id='mx' class='bs'>χ</span><span id='my' class='bs'>y</span><span id='mz' class='bs'>z</span>";
bData = bData + "<span id='bba' class='bc'>←1つもどる</span><br><br><br>";
bData = bData + "<span id='b1' class='bs'>1</span><span id='b2' class='bs'>2</span><span id='b3' class='bs'>3</span>";
bData = bData + "<span id='b4' class='bs'>4</span><span id='b5' class='bs'>5</span><span id='b6' class='bs'>6</span>";
bData = bData + "<span id='b7' class='bs'>7</span><span id='b8' class='bs'>8</span><span id='b9' class='bs'>9</span>";
bData = bData + "<span id='b0' class='bs'>0</span><span id='bd' class='bs'>.</span>";
bData = bData + "<span id='bhide' class='bc'>閉じる</span> <span id='bcheck' class='bc'>解答する</span><br><br><br>";
bData = bData + "</div>";
$(function() { // jQuery を実行
$('#inputButton1').hide(); // キーボードの表示を消しておく
$('#buttonShow1').on('click', function () {
funcButtonHide();
kaitouNumber = 1; // 問題番号
$('#inputButton' +kaitouNumber).html(bData); // キーボードの表示
$('#inputButton' +kaitouNumber).show('normal');// アニメーション表示
buttonReload(); // ボタンを作動させる
$('#buttonShow' +kaitouNumber).hide(); //「クリックして答えを入力」ボタンを隠す
});
function funcKaitou(){
switch (kaitouNumber){
case 1: //問題番号1 の場合
// 計算式の表示
kaisetuText = ' \\(3\\sqrt{5}+6\\sqrt{5}\\) ';
kaisetuText = kaisetuText+ '=\\((3+6)\\sqrt{5}\\) ';
kaisetuText = kaisetuText+ '=\\(9\\sqrt{5}\\)<br>';
$('#kaisetu' + kaitouNumber).html(kaisetuText);
// 答え合わせ
if((kaitouText[kaitouNumber] == '\\({9}\\sqrt{5}\\)') //9ルート5
||(kaitouText[kaitouNumber] == '\\({9}\\sqrt{5}\\)\\({}\\)')){ //9ルート5 ルートおわり
$('#maru' + kaitouNumber ).css('opacity',1); //正解の場合
}else{
funcBatu(); //不正解の場合
}
break;
};
MathJax.Hub.Queue(["Typeset",MathJax.Hub,('kaisetu' + kaitouNumber)]); //数式を表示
$('#buttonShow'+ kaitouNumber ).hide(); //キーボード表示ボタンを消します
$('#inputNow').remove();
$('#inputNow').html("<div id='inputButton" + kaitouNumber + "'></div>");
$('#inputButton' + kaitouNumber).hide();
$(('#buttonShow'+ kaitouNumber)).remove();
};
function funcBatu(){ // 不正解の場合、バッテンを表示
$('#maru' + kaitouNumber).text('×');
$('#maru' + kaitouNumber).css('opacity',1);
$('#maru' + kaitouNumber).css('color','blue');
};
function funcButtonHide() { //キーボードを消す
$('#inputNow').remove();
$('#inputNow').html("<div id='inputButton" + kaitouNumber + "'></div>");
$('#inputButton' + kaitouNumber).hide();
$(('#buttonShow'+ kaitouNumber)).show();
}
function buttonReload(){ // 数学用ソフトウェアキーボードが押されたとき
$('#b1' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="1"; buttonMax[kaitouNumber]++ ; display(); });
$('#b2' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="2"; buttonMax[kaitouNumber]++ ; display(); });
$('#b3' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="3"; buttonMax[kaitouNumber]++ ; display(); });
$('#b4' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="4"; buttonMax[kaitouNumber]++ ; display(); });
$('#b5' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="5"; buttonMax[kaitouNumber]++ ; display(); });
$('#b6' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="6"; buttonMax[kaitouNumber]++ ; display(); });
$('#b7' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="7"; buttonMax[kaitouNumber]++ ; display(); });
$('#b8' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="8"; buttonMax[kaitouNumber]++ ; display(); });
$('#b9' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="9"; buttonMax[kaitouNumber]++ ; display(); });
$('#b0' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="0"; buttonMax[kaitouNumber]++ ; display(); });
$('#bd' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="."; buttonMax[kaitouNumber]++ ; display(); });
$('#ma' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="a"; buttonMax[kaitouNumber]++ ; display(); });
$('#mb' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="b"; buttonMax[kaitouNumber]++ ; display(); });
$('#mc' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="c"; buttonMax[kaitouNumber]++ ; display(); });
$('#md' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="d"; buttonMax[kaitouNumber]++ ; display(); });
$('#mx' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="x"; buttonMax[kaitouNumber]++ ; display(); });
$('#my' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="y"; buttonMax[kaitouNumber]++ ; display(); });
$('#mz' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="z"; buttonMax[kaitouNumber]++ ; display(); });
$('#bt' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="+"; buttonMax[kaitouNumber]++ ; display(); });
$('#bh' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="-"; buttonMax[kaitouNumber]++ ; display(); });
$('#bk' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="×"; buttonMax[kaitouNumber]++ ; display(); });
$('#bw' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="÷"; buttonMax[kaitouNumber]++ ; display(); });
$('#bi' ).on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="="; buttonMax[kaitouNumber]++ ; display(); });
$('#bks').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="("; buttonMax[kaitouNumber]++ ; display(); });
$('#bke').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]=")"; buttonMax[kaitouNumber]++ ; display(); });
$('#bpi').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="π"; buttonMax[kaitouNumber]++ ; display(); });
$('#bpm').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="±"; buttonMax[kaitouNumber]++ ; display(); });
$('#bbb').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="分母入力"; buttonMax[kaitouNumber]++ ; display(); });
$('#bbe').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="分数おわり"; buttonMax[kaitouNumber]++ ; display(); });
$('#brs').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="ルートはじめ"; buttonMax[kaitouNumber]++ ; display(); });
$('#bre').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="ルートおわり"; buttonMax[kaitouNumber]++ ; display(); });
$('#bpw').on('click', function () { buttonText[kaitouNumber][buttonMax[kaitouNumber]]="累乗"; buttonMax[kaitouNumber]++ ; display(); });
$('#bba').on('click', function () { buttonMax[kaitouNumber]-- ; if( buttonMax[kaitouNumber] <0 ){ buttonMax[kaitouNumber] =0 }display(); });
$('#bal').on('click', function () { buttonMax[kaitouNumber] =0; display(); });
$('#bhide').on('click', function () {funcButtonHide();});
$('#bcheck').on('click', function () {funcKaitou();});
};
buttonReload(); // ボタンを使えるようにする
function display() {
buttonCheckText ="";
var myText="\\({"; //\を表示するには2回\\
for ( var k=0; k <buttonMax[kaitouNumber] ;k++){
switch (buttonText[kaitouNumber][k]){
case "1": myText = myText + "1" ;break;
case "2": myText = myText + "2" ;break;
case "3": myText = myText + "3" ;break;
case "4": myText = myText + "4" ;break;
case "5": myText = myText + "5" ;break;
case "6": myText = myText + "6" ;break;
case "7": myText = myText + "7" ;break;
case "8": myText = myText + "8" ;break;
case "9": myText = myText + "9" ;break;
case "0": myText = myText + "0" ;break;
case ".": myText = myText + "." ;break;
case "a": myText = myText + "a" ;break;
case "b": myText = myText + "b" ;break;
case "c": myText = myText + "c" ;break;
case "d": myText = myText + "d" ;break;
case "x": myText = myText + "x" ;break;
case "y": myText = myText + "y" ;break;
case "z": myText = myText + "z" ;break;
case "+": myText = myText + "+" ;break;
case "-": myText = myText + "-" ;break;
case "×": myText = myText + "×" ;break;
case "÷": myText = myText + "÷" ;break;
case "=": myText = myText + "=" ;break;
case "(": myText = myText + "(" ;break;
case ")": myText = myText + ")" ;break;
case "π": myText = myText + "\\pi" ;break;
case "±": myText = myText + "\\pm" ;break;
case "分母入力": myText = myText + "}\\over{" ;break;
case "分数おわり": myText = myText + "}\\)\\({" ;break;
case "ルートはじめ": myText = myText + "}\\sqrt{" ;break;
case "ルートおわり": myText = myText + "}\\)\\({" ;break;
case "累乗": myText = myText + "\^" ;break;
};
buttonCheckText = buttonCheckText +buttonText[kaitouNumber][k];
};
if(buttonMax[kaitouNumber] > 0){
if(buttonText[kaitouNumber][buttonMax[kaitouNumber] -1] == "累乗"){ //累乗入力の時に表示が変になるを防ぐ
myText = myText + "□";
};
};
myText = myText + "}\\)";
//MathJax表示
$(("#kotae" + kaitouNumber)).html(myText);
MathJax.Hub.Queue(["Typeset",MathJax.Hub,("kotae" + kaitouNumber)]);
kaitouText[kaitouNumber]= myText;
};
$('body').bind('updated',function(){display()});
});
非表示にしたいボタン(キー)があるときには、
// 入力用のボタン表示
の下の部分で
// bData = bData + <span id='brs' class='bs'>ルート・・・
↑このように//を使ってコメントアウトすると、「ルート」ボタンが非表示になります。