原因わからず、半日をつぶす!(iPod Touch & iPad フォーム要素のvalue値の書き換えができない)

WEBアプリ製作中に問題が発生。
スクリプトでフォームの要素の値を書き換えようとしたら、
iPod Touch & iPad2 で、動かない!原因もわからない。
とにかく不要なものを削除して、再現。

外部スタイルシートを外す、もしくは、外部スクリプトを外す、もしくは、input@autofocus を外すと、
正常に書き換えられる。(外部ファイルは、存在するも何も書いていない)

<!DOCTYPE html>
<title></title>
<meta charset="utf-8">
<link rel="stylesheet" type="text/css" href="style2.css">

<body>
<form>
  <input type="text" name="@namae" value="" autofocus>
  <input type="button" value="test" onclick="
    this.form.elements['@namae'].value='abcdefg';
  ">
</form>

<script src="lib2.js"></script>

回帰法要の予定表を、javascriptで、WEBアプリにしてみる(iPod Touch とか、iPad に対応)農協関係者は、使用厳禁!

<!DOCTYPE html>
<html lang="ja" manifest="cache.manifest">
<head>
  <title>回忌法要表</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=640">
  
  <style>
/* 共通 */
  nav ul {
    margin        : 1ex;
  }
  
  nav li
  {
    border-bottom : 1px gray dotted;
    padding       : 0;
    font-size     : 120%;
    line-height   : 190%;
  }
  
  input, select
  {
    font-size     : 100%;
  }

  table
  {
    border-collapse : collapse;
    width           : 100%;
    border          : 1px black solid;
    font-size       : 220%;
  }

  thead th
  {
    font-size       : 120%;
    padding         : .8ex 0 .8ex 0;
    background      : #666;
    color           : #222;
    text-shadow     : -1px -1px 1px white, 1px 1px 1px #000;
  }

  tr:nth-of-type(odd)
  {
    background      : #bbb;
  }

  tr:nth-of-type(even)
  {
    background      : #eee;
  }

  td, th
  {
    font-family   : 'HiraMinProN-W6' ;
    padding       : .4ex;
  }
  
  td:nth-child(1) {
    text-align    : center;
    text-justify  : inter-ideograph;
    font-family   : Georgia,'ヒラギノ角ゴ Pro W3', 'HiraKakuProN-W6', 'Hiragino Kaku Gothic Pro','メイリオ',Meiryo,'MS Pゴシック',sans-serif;
  }


/* PC 画面専用 */
@media screen
{
  body
  {
    width         : 640px;
  }
  
  td, th
  {
    font-size     : 60%;
  }
  table + p {
    display         : none;
  }
}


/* iPod 用 */
@media only screen and (max-device-width:960px)
{
  body {
    margin : 0;
  }
  
  table {
    border        : none;
  }

  td, th
  {
    font-size     : 96%;
  }
}


/* 印刷用 */
@media print
{
  body {
    width: 187mm;
  }
  nav
  {
    display       : none;
  }
  
  th, td
  {
    font-size     : 90%;
    line-height   : 105%;
  }

  table + p {
    font-size        : 120%;
    padding          : 1ex;
    border           : 1px black solid;
    border-radius    : 10px;
    text-align       : center;
  }
}

  </style>
</head>

<body>
  <nav>
    <form action="#" onsubmit="return false">
      <ul>
        <li>
          命日:
          <select name="@DATE">
            <option value="0" selected>西暦
            <option value="1">平成
            <option value="2">昭和
            <option value="3">大正
            <option value="4">明治
          </select>

          <select name="@DATE">
            <option value="1">2000</option>
          </select>
          <select name="@DATE">
            <option value="1" selected>1</option>
          </select>

          <select name="@DATE">
            <option value="1" selected>1</option>
          </select>
        </li>

        <li>
          名前:
          <input type="text" name="@NAMAE" value="" size="16" maxlength="16"> /
          <select name="@RELIGION">
            <option value="0" checked="checked">仏教</option>
            <option value="1">神教</option>
          </select> /
          <input type="button" value="印刷" onclick="window.print ()">
        </li>
      </ul>
    </form>
  </nav>
  
  <section>
    <table id="MEINITI">
      <thead>
        <tr><th colspan="2">法要予定表</th></tr>
      </thead>
      
      <tbody>
      </tbody>
    </table>
    <p>
      葬儀・仏壇・花環・生花・盛篭のご用命は、<br>㈲善光堂 TEL 0194-65-3420
    </p>
  </section>

<script type="text/javascript">
//クッキーの読み出し
function getCookie () {
  if (1 > arguments.length)
    return null;
  
  return (function (name) {
    var doc    = this.document;
    var _name  = encodeURIComponent (name).replace (/\W/g, '\\$&');
    var _value = doc.cookie.match (RegExp (name + '\\s*=\\s*(.*?)(?:[\\s;,]|$)'));
    
    return _value ? decodeURIComponent (_value[1]) : '';
  }).apply (this, arguments);
}


//クッキーの保存
function setCookie () {
  if (2 > arguments.length)
    return false;

  (function (name, value, day, path, domain) {
    var doc = this.document;
    var date = new Date;
    var parm = [];
    
    date.setDate (date.getDate () + (day || 0));
    parm.push (encodeURIComponent (name) + '=' + encodeURIComponent (value));
    parm.push ('expires=' + date.toUTCString ());

    if (path)
      parm.push ('path=' + encodeURIComponent (path));
    if (domain)
      parm.push ('domain=' + encodeURIComponent (domain))

    doc.cookie = parm.join (';') + ';';
  }).apply (this, arguments);
}


//フォームの要素の読み出し
function getFormValue (nameList) { // getFormValue.call (form, nameList /is Array/)
  var result = [];
  var elements = this.elements;
  var r, es, e, n;
  var i, j, k;
  var opt, o, v;

  for (i = 0, I = nameList.length; i < I; i++) {
    es = elements[nameList[i]];
    if (! es.length)
      es = [es];
    r = [];
    
    for (j = 0; e = es[j]; j++) {
      switch (e.nodeName) {
      case 'SELECT' :
        if ('select-multiple' === e.type) {
          for (v =[], opt = e.options, k = 0; o = opt[k++]; )
            if (o.selected)
              v.push (o.value);
        }
        else {
          v = e.value;
        }
        r.push (v);
        break;
          
      case 'INPUT' :
        switch (e.type) {
        case 'checkbox' : case 'radio' :
          if (e.checked)
            r.push (e.value);
          break;
        default :
          r.push (e.value);
        }
        break;
      
      case 'TEXTAREA' :
        r.push (e.value);
        break;
      }
    }
    result[i] = r;
  }
  return result;
}



//フォームの要素の値を設定 setFormValue.call (form, name, value) 
function setFormValue (name, value) {
  var i, j;
  var e;
  var op, ops;
  var es = ('FORM' === this.nodeName)
           ? this.elements[name]
           : document.getElementsByName (name);

  if (! es)
    return false;

  if (es.nodeType == 1)
    es = [].concat (es);
  
  value = String (value);

  for (i = 0; e = es[i]; i++) {
    switch (e.nodeName) {
    case 'SELECT' :
      for (j = 0, ops = e.options; op = ops[j++]; )
        op.selected = (op.value == value);
      break;
    case 'TEXTAREA' :
      e.value = value;
      break;
    case 'INPUT' :
      switch (e.type) {
      case 'checkbox' : case 'radio' :
        if (e.value === value)
          e.checked = true;
        break;
      default :
        e.value = value;
      }
    }
  }
}


(function () { // Ajax
  if ('undefined' === typeof XMLHttpRequest)
    return false;

  var obj2str =
    (function (obj) {
      var p = [], i, ary, t;

      switch (typeof obj) {
      case 'string' :
        for (i = 0, ary = obj.split ('=', 2); t = ary[i++]; )
          p.push (encodeURIComponent (t[0]) + '=' + encodeURIComponent (t[1]));
        break;
      case 'object' :
        for (i in obj)
          if (obj.hasOwnProperty (i))
            p.push (encodeURIComponent (i) + '=' + encodeURIComponent (obj[i]));
      }
      return (p.length) ? '\u0026' + p.join ('\u0026'): '';
    });


  var handleEvent =
    function (event) {
      var req = event.target;
      var result;
      
      if (4 === req.readyState) {
        try {
          if (200 === req.status) {
            result = req.responseText;
            if (0 == result.indexOf ('Error'))
              throw new Error (result);
            this.callbackfn.call (this.callbackobj, result);
          }
        } catch (err) { ; }
        req.abort ();
        req.removeEventListener ('readystatechange', this, false);
        req = null;
      }
    };
  

  var ajax =
    function (uri, method, query, syncFlag, callbackfn, callbackobj) {
      var req = new XMLHttpRequest;
      var obj;
      var result;

      query = obj2str (query);

      switch (method.toUpperCase ()) {
      case 'GET'   : uri += '?' + query;
      case 'POST'  : break;
      default      : throw new Error;
      }

      if (syncFlag) {
        req.addEventListener ('readystatechange', {
          handleEvent : handleEvent,
          callbackfn  : callbackfn,
          callbackobj : callbackobj || null
          }, false);
      }

      req.open (method, uri, syncFlag);
      req.setRequestHeader ('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
      req.setRequestHeader ('Pragma', 'no-cache');
      req.setRequestHeader ('Cache-Control', 'no-cache');
      req.send (query);

      if (! syncFlag) {
        result = req.responseText;
        if (0 == result.indexOf ('Error'))
          throw new Error (result);
        return result;
      }
    };

  this.ajax = ajax;
})();


//_____________________
function getQuery () {
  var doc = this.document;
  var result = {};
  var querys = doc.location.search.substring (1).split (/&|;/g);
  var query;
  var len = querys.length;
  var i, j, J, k;
  var cmp;
  var value;
  var cnt = 0;
  
  if (0 == len)
    return null;
  
  for (i = 0; i < len; i++) {
    if (query = querys[i]) {
      cmp = query.split ('=');
      if (0 === cmp.length) {
        result[ String (cnt) ] = decodeURIComponent (query);
        cnt += 1;
      }
      else {
        value = decodeURIComponent (cmp.pop ()); //最後を値として取り出す a=b=c=valな場合
        for (j = 0, J = cmp.length; j < J; j++)
          if (k = cmp[j])
            result[ decodeURIComponent (k) ] = value;
      }
    }
  }
  return result;
}



var setInnerHTML = function (node, html, cbFunc, thisArg, thisObj) {
  var interval = 1;
  var lastNode = null;
  
  node.innerHTML = html;
  setTimeout (function () {
    var n = node;
    var t;
    var sc;
    var code;
    var i;
    
    while (t = n.lastChild)
      n = t;

    if (n == lastNode) {
      if (sc = node.getElementsByTagName ('script'))
        for (i = 0; code = sc[i++]; )
          eval (code.text);

      return (cbFunc)
        ? cbFunc.apply (thisObj || null, thisArg || [])
        : null;
    }

    interval *= 2;
    lastNode = n;

    setTimeout (arguments.callee, interval);
  }, interval);
};

// サーバーの日時の取得
var getUTCDateByServer = function () {
  if ('undefined' === typeof XMLHttpRequest)
    return null;
    
  var r = new XMLHttpRequest;
  r.open ('HEAD', '#', false);
  r.send (null);
  return new Date (r.getResponseHeader ('Date'));
};

// 時間を文字列にして返す
function toTimeString (date) {
  return [ padding (date.getHours ()),
           padding (date.getMinutes ()),
           padding (date.getSeconds ()) ].join (':');
}

// 日付を文字列にして返す
function toDateString (date) {
  return [ date.getFullYear (),
           padding (date.getMonth () + 1),
           padding (date.getDate ()) ].join ('-');
}

// 2桁の数値のゼロサプレス
function padding (num) {
  num = Number (num);
  return (num < 10) ? '0' + num: num + '';
}

// 子ノードを削除する
function deleteChildNodes (node) {
  while (node.hasChildNodes ())
    node.removeChild (node.firstChild);
}



function createElementsEX () {
  var doc = document;
  var result = doc.createDocumentFragment ();
  var len = arguments.length;
  var idx = 0;
  var arg;
  var name;
  var node;
  
  if (1 > len)
    return null;
  
  for (; idx < len; idx++) {
    arg = arguments[idx];

    if ('string' ===  typeof arg)
      result.appendChild (doc.createTextNode (arg));

    else if (arg instanceof Array)
      for (var i = 0; i < arg.length; i++)
        result.appendChild (arguments.callee (arg[i]));

    else if (arg instanceof Object) {
      if (name = arg.nodeName) {
        node = doc.createElement (name);
        if (! node)
          throw new Error;
        for (var i in arg)
          if (arg.hasOwnProperty (i))
            if ('nodeName' !== i && 'childNodes' !== i)
              node.setAttribute (i, arg[i]);

        if ('childNodes' in arg)
          node.appendChild (arguments.callee (arg.childNodes));

        result.appendChild (node);
      }
      else
        result.appendChild (arguments.callee (arg.text || ''));
    }
  }
  return result;
}



// PHP経由でメールの送信
function sendMail (mailTo, subject, body, from) {
  var mail = {
    'mailTo'  : mailTo,
    'subject' : subject,
    'body'    : body,
    'from'    : from
  };
  
  return ajax ('sendmail.php', 'post', mail);
};


function convertSQLValue (values) {
  var len = values.length;
  var result = [];
  var i, v;
  
  for (i = 0; i < len; i++) {
    if (values[i] == '')
      result.push ('NULL');
    else {
      result.push ("'" + String (values[i]).replace (/('|")/g, '\\$1') + "'");
    }
  }
  
  return result;
}


function validTimeString (e) {
  var n, h, m, s;
  
  if ('' !== e.value)
    if (n = e.value.match (/(\d+)/g)) {
      h = Number (n[1]);
      m = Number (n[2]);
      s = Number (n[3]);
    }
}


// select 要素の options と同じ値を選択する
function setSelectOne (select, value) {
  Array.prototype.forEach.call (select.options,
    (function (op) { op.selected = (op.value === this.value); }),
      { 'value' : String (value) });
}


// select 要素の options を生成する
function replaceOptions (select, aryText, aryValue, defValue) {
  if (2 > arguments.length)
    return false;
  
  var d = select.ownerDocument;
  var v = d.parentWindow || d.defaultView;
  var o = select.options;
  var i, I;
  var s, sw;
  
  o.length = 0;
  if ('undefined' === typeof aryText)
    aryValue = aryText;
  
  for (i = 0, I = aryText.length; i < I; i++) {
    s = String (aryValue[i]);
    sw = (s === String (defValue));
    o[i] = new v.Option (String (aryText[i]), s, sw, sw);
  }
}



// 日付をすべて select 要素で入力する [年号, 年, 月, 日]
(function () {
  function setSelectOption (select, aryText, aryValue, selectedNo) {
    var d = select.ownerDocument;
    var v = d.parentWindow || d.defaultView;
    var o = select.options;
    
    if (3 > arguments.length)
      aryValue = aryText;
    
    o.length = 0;
    
    for (var i = 0, I = aryText.length; i < I; i++)
      o[o.length] = new v.Option (String (aryText[i]), String (aryValue[i]));
    
    select.selectedIndex = selectedNo || 0;
  }

  
  function DateSelect (select, date) {
    this.select = select;
    this.date = date;
    this.change = [];
  }
  
  
  function setDate (date) {
    if (1 > arguments.length)
      return;
    
    this.date = date;
    this.update ();
  }
  
  
  function getDate () {
     var s = this.select;
     return new Date (s[1].value, s[2].value - 1, s[3].value);
  }


  function update (e) {
    if (0 === arguments.length) {
      e = this.select[0];
    }

    var idx = this.select.indexOf (e);
    var max = 120;
    var txt = [], val = [];
    var i, I;
    var y = this.date.getFullYear ();
    var m = this.date.getMonth ();
    var d = this.date.getDate ();
    var mm, yy;

    this.change[idx] = true;
    while (idx < 3) {
      switch (idx) {

      case 0 : //西暦
        switch (Number (e.value)) {
        case 0 :
          for (i = 0, val = [], txt = []; i <= max; i++) {
            txt[i] = (val[i] = y - max + i) + '年';
          }
          replaceOptions (this.select[1], txt, val, y);
          break;
        
        case 1 : //平成
          max = y - 1988;
          val = [];
          txt = [];
          for (i = 0; i < max; i++) {
            val[i] = 1989 + i;
            txt[i] = (i + 1) + ' 年 (' + val[i] + ')';
          }
          setSelectOption (this.select[1], txt, val, max - 1);
          break;
        
        case 2 : //昭和
          max = 64;
          val = [];
          txt = [];
          for (i = 0; i < max; i++) {
            val[i] = 1926 + i;
            txt[i] = (i + 1) + ' 年 (' + val[i] + ')';
          }
          
          setSelectOption (this.select[1], txt, val, max / 2 |0);
          break;
          
        case 3 : //大正
          max = 15;
          val = [];
          txt = [];
          for (i = 0; i < max; i++) {
            val[i] = 1912 + i;
            txt[i] = (i + 1) + ' 年 (' + val[i] + ')';
          }
          
          setSelectOption (this.select[1], txt, val, max / 2 |0);
          break;
          
        case 4 : // 明治
          max = 45;
          val = [];
          txt = [];
          for (i = 0; i < max; i++) {
            val[i] = 1868 + i;
            txt[i] = (i + 1) + ' 年 (' + val[i] + ')';
          }
          
          setSelectOption (this.select[1], txt, val, max / 2 |0);
          break;
          
        }
        break;
      
      case 1 :
        if (this.change[idx]) break;
        max = 12;
        val = [];
        txt = [];
        for (i = 0; i < max; i++) {
          val[i] = i + 1;
          txt[i] = (i + 1) + '月';
        }
        
        setSelectOption (this.select[2], txt, val, this.date.getMonth ());
        break;
        
      case 2 :
        if (this.change[idx])
          break;

        yy = Number (this.select[1].value);
        mm = Number (this.select[2].value) - 1;
        max = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][mm];

        if (1 === mm)
          max += !(yy%4) - !(yy%100) + !(yy%400);// - !y%100 + !y%400;
        val = [];
        txt = [];
        for (i = 0; i < max; i++) {
          val[i] = i + 1;
          txt[i] = (i + 1) + '日';
        }
        
        setSelectOption (this.select[3], txt, val, this.date.getDate () - 1);
        break;
        
      }
      idx++;
    }
  }

  function handler (event) {
    var e = event.target;
    
    if (0 <= this.select.indexOf (e))
      this.update (e);
  }

  // 各 select に、イベントを貼り付ける
  function setEventFunc (select) {
    select.addEventListener ('change', this, false);
  }

  
  // 年号,年,月,日の4つの select 要素を連動させる
  function createDateSelect (selects, defaultDate, type) {
    var obj;
    
    if (1 > arguments.length)
      return null;
    if (4 != selects.length)
      return null;

    if ('undefined' === typeof defaultDate)
      defaultDate = new Date;
    
    selects = Array.prototype.slice.call (selects, 0); //配列に
    obj = new DateSelect (selects, defaultDate, type || 0);
    obj.update ();
    selects.forEach (setEventFunc, obj); // select に、イベントを貼り付け
    
    return obj;
  }
  
  
  // prototype の設定
  DateSelect.prototype.handleEvent = handler;
  DateSelect.prototype.update = update;
  DateSelect.prototype.setDate = setDate;
  DateSelect.prototype.getDate = getDate;
  
  this.collaborateSelectDate = createDateSelect;
})();


//_____________________________________

var addDate = // 日付オブジェクトに、年と日を加算する
  (function (date, year, day) {
    var d = new Date (date.getTime ());

    if (year)
      d.setFullYear (d.getFullYear () + year);

    if (day)
      d.setDate (d.getDate () + day);

    return d;
  });


var toDateString = // 日付オブジェクトを、yyyy年mm月dd日(曜日) 形式の文字列にして返す
  (function (padding) {
    var week = [ '日', '月', '火', '水', '木', '金', '土' ];
    
    return function (date) {
      return [
        date.getFullYear (), '年',
        padding (date.getMonth () + 1), '月',
        padding (date.getDate ()), '日',
        '(' , week[date.getDay ()], '曜)'
      ].join ('');
    };
  })(function (num) { return (num < 10) ? '0' + num: num; });


// 配列を tbody ノードにして返す
var csv2Tbody =
  (function () {
    function insertRow (fields) {
      fields.forEach (insertCell, this.insertRow (-1));
    }
   
    function insertCell (field) {
      this.insertCell (-1).textContent = field;
    }
   
    return function (csv) {
      var doc = this.document;
      var tbody = document.createElement ('tbody');
      
      tbody.insertRow (-1); // dummy
     
      csv.forEach (insertRow, tbody);
      tbody.deleteRow (0); // dummy
     
      return tbody;
    };
  })();


var kaiki = {
  'thead' : document.querySelector ('#MEINITI thead th'),
  'yotei' : [
    [
      ['死亡年月日'    , 0,  0],
      ['初七日法要'    , 0,  6],
      ['二・七日法要'  , 0, 13],
      ['三・七日法要'  , 0, 20],
      ['四・七日法要'  , 0, 27],
      ['五・七日法要'  , 0, 34],
      ['六・七日法要'  , 0, 41],
      ['四十九日法要'  , 0, 48],
      ['百か日法要'    , 0, 99],
      ['一周忌法要'    , 1,  0],
      ['三回忌法要'    , 2,  0],
      ['七回忌法要'    , 6,  0],
      ['十三回忌法要'  ,12,  0],
      ['十七回忌法要'  ,16,  0],
      ['二十三回忌法要',22,  0],
      ['二十七回忌法要',26,  0],
      ['三十三回忌法要',32,  0],
      ['五十回忌法要'  ,49,  0],
      ['百回忌法要'    ,99,  0]
    ],
    [
      ['死亡年月日'    , 0,  0],
      ['十日祭'        , 0,  9],
      ['二十日祭'      , 0, 19],
      ['三十日祭'      , 0, 29],
      ['四十日祭'      , 0, 39],
      ['五十日祭'      , 0, 49],
      ['百十日祭'      , 0, 99],
      ['壱年祭'        , 1,  0],
      ['三年祭'        , 2,  0],
      ['五年祭'        , 4,  0],
      ['十年祭'        , 9,  0],
      ['十五年祭'      ,14,  0],
      ['二十年祭'      ,19,  0],
      ['二十五年祭'    ,24,  0],
      ['三十年祭'      ,29,  0],
      ['三十五年祭 '   ,34,  0],
      ['四十 年祭'     ,39,  0],
      ['四十五年祭'    ,44,  0],
      ['五十年祭'      ,49,  0]
    ]
  ],

  
  'setHeader' :
    (function (name, religion) {
      var hd = [];

      if (name)
        hd.push ('故 ' + name + ' 儀');
      
      switch (religion) {
      case '1' :
        hd.push ('御霊祭予定表');
        break;

      case '0' :
      default :
        hd.push ('法要予定表');
        break;

      }

      this.thead.textContent = hd.join (' ');
    }),

  'setList' :
    (function (date, religion) {
      var tbody = document.querySelector ('#MEINITI tbody');
      var type = Number (religion || 0);
      var csv = this.yotei[type].map (function (ary) {
        return [ary[0], toDateString (addDate (date, ary[1], ary[2]))];
      }, date)
      
      tbody.parentNode.replaceChild (csv2Tbody (csv), tbody);
    })
};

//_________________________
var date = collaborateSelectDate (document.querySelectorAll ('nav form select[name="@DATE"]'));

kaiki.setList (new Date, 0);

document.querySelector ('nav form').addEventListener ('change', function (event) {
  var e = event.target;
  var es = e.form.elements;
  var d;
  
  switch (e.name) {
  case '@DATE' :
  case '@RELIGION' :
    d = date.getDate ();
    kaiki.setList (d, es['@RELIGION'].value);
  case '@NAMAE' :
    kaiki.setHeader (es['@NAMAE'].value, es['@RELIGION'].value);
    break;
  }
}, false);

//_________________________
(function () {
  var doc = document;
  var query = getQuery ();
  var n, r;
  
  if ((n = query.name))
    doc.querySelector ('nav form input[name="@NAMAE"]').value = n;
})();
</script>
</body>
</html>