ChromeとFirefoxでiPad向けの業務WEBアプリを作成しています。
基本的に3ブラウザとも動きが同じで通常は問題ないのですが、
jsonで取ってきた値をselectの選択値に反映させようと
javascriptでselected属性を付けたときにsafariだとうまく反映されずに困ってました。
で、ついに解決策を発見しました。
- デフォルトのoptionにもselected属性をちゃんと付ける
- 異なるoptionにselected属性を付ける前にすべてのoptionからselected属性を削除する
です。
私はjqueryを主に使っているのでサンプルコードとしてはこんな感じです。
1.セレクトボックス作成時(反復処理前提なので無駄が多いです)
//selectオブジェクトのテンプレート作成
var selectObj = $('<select></select>');
selectObj.append('<option value="0"></option>');
selectObj.append('<option value="1">aaaaaa</option>');
selectObj.append('<option value="2">bbbbbb</option>');
selectObj.append('<option value="3">cccccc</option>');
selectObj.append('<option value="4">dddddd</option>');
//親オブジェクト
var divObj = $('<dev/>');
//親オブジェクトにテンプレートをコピー
divObj.append(selectObj.clone(true));
//デフォルトの選択値をセレクト(テンプレート作成時に行ってもいいと思います)
divObj.find('option').eq(0).attr('selected','');
2.書換時
//すべてのopcionからselected属性を削除
divObj.find('option').removeAttr('selected');
//改めてselected属性を追加
divObj.find('option').eq(1).attr('selected','');
※追記
どうやらこれだと手動でセレクトボックスを変更した際に選択値が表示されなくなってしまうみたいです。
そこでサーバから戻ってきた値と現在の選択値を比較して変更されていた場合にだけselected属性を削除追加する様に変更します。
//サーバから戻ってきた選択値(適宜値を代入します)
var server_value = "";
//現在の選択値
var tmp_select_value = divObj.find('select option:selected').val();
//二つの値が異なる場合だけselected属性を付け替え
if(tmp_select_value != server_value){
//すべてのopcionからselected属性を削除
divObj.find('option').removeAttr('selected');
//改めてselected属性を追加
divObj.find('option').eq(1).attr('selected','');
//iOS 10.0.2対策
divObj.find('select').focus();
}
これでiPadでもセレクト値がアップデートされると思います。
※追記
iOS 10.0.2で確認したところ表示がリフレッシュされなくなっていました。
なにかイベントを与えたらリフレッシュされるかもしれないので引き続き調査します。
→セレクトボックスにフォーカスを送れば変更されることを確認しました。ちょっと画面がうるさくなりますが。
ちなみにこれを行っていない状態だと、
一番上のoptionがselected属性なしで選択状態になってしまい、
書換時に追加したselected属性と合わせて2個のoptionが選択された状態になってしまうようです。