iOS8のsafariだとmaterializeのmaterial_selectを使うとキャレットが出てダサいので直してみた

投稿日:

ちょっとしたツールを作る時bootstrapを多用しているんだけど、いつまでもbootstrapに頼っていてはダメだ、己を磨くのだ、というわけでmaterializeというものを試してみました。(えっへん)

materializeとは

Materialize – マテリアルデザインのためのCSSフレームワーク

こちらの記事にある通りマテリアルなデザインを作るためのCSSフレームワークだそうです。
僕もマテリアルしてみたいなと思ったので試してみました。

material_selectを使ってみたら???

試してみると感覚的にbootstrapとそんな変わりないので深い所まで行かなければサクッと書ける感じ。
いやぁこれで俺もマテリアれるわ〜。
なんて思っていたのも束の間、セレクトボックスを無駄にカッコ良くしてくれるmaterial_select()を使ってみると、、iOSのsafariでだけ(かは分からないけど)セレクトボックスを選択するとキャレットが出てダサい。とにかくダサい。
※ しかも僕は実機でしか確認出来なかった
※ 実機はiPhone5、iOS8です

これをiPhoneのsafariで見て頂きたいのですが、
material_selectのテスト
ほらダサい。
ちなみに、本家のhttp://materializecss.com/forms.htmlも同様。※Selectの所

いやぁこれはマテリアれないかな〜。
って思いながらも、ちょっと調べてみた事を記しておきます。

尚、試してみたmaterializeのバージョンは0.95.3です。

ちょっと調べてみた

material_select()を使ったセレクトボックスのソースはこうなるようです。

<div class="select-wrapper">
  <input type="text" class="select-dropdown" readonly="true" data-activates="select-options-c2f63bb2-881f-07be-6d17-2c03d94d7931" value="あれ">
  <i class="mdi-navigation-arrow-drop-down active"></i>
  <select name="" id="sample" class="initialized">
    <option value="a" selected="">あれ</option>
    <option value="b">iOSのsafariで</option>
    <option value="c">キャレットが</option>
    <option value="d">でてい</option>
    <option value="e">るんでないかい?</option>
  </select
</div>

なるほど、テキストボックスが作られて、それが表示されるみたいです。
で、セレクトボックスの裏に出てくるキャレットはこいつにフォーカスがあたっているのでしょう。
だってreadonly="true"してるもん (要素を読み取り専用にする)。
多分、作者もそれを意識(テキストボックスにフォーカスが当たらないように)しているんだと思う。

試しに以下の様に書いた

<input type="text" readonly="true" value="">

テキストボックスは選択もされないしキャレットも出ない。
※ iOSのsafariでも

でもなんで今回の場合、キャレットが出るんかなぁ。
なんかフォーカスが当たっちゃっているっぽい。

もうちょっと調べてみるとreadonly="true"した要素に対してonFocus="this.blur()"するとフォーカスも当たらないらしい。

ちょっとソースを見てみる

この辺り試してみようかなぁという事で、ソースを見てみる。

materialize.jsの2405行目らへんで

$.fn.material_select = function (callback) {

material_select()は定義されている。

そして2460行目らへんで

$newSelect.on('focus', function(){
  $(this).trigger('open');
  label = $(this).val();
  selectedOption = options.find('li').filter(function() {
    return $(this).text().toLowerCase() === label.toLowerCase();
  })[0];
  activateOption(options, selectedOption);
});

$newSelect.on('blur', function(){
  $(this).trigger('close');
});

focusとblurのイベントをリッスンしてゴニョゴニョしている。
ちょっとこの辺を修正したら、試せそう。

ちょっとソースをいじってみる

というわけでソースを弄ってみましたよ。

$newSelect.on('focus', function(){
  $(this).trigger('open');
  label = $(this).val();
  selectedOption = options.find('li').filter(function() {
    return $(this).text().toLowerCase() === label.toLowerCase();
  })[0];
  activateOption(options, selectedOption);
  this.blur(); // フォーカスを外す
});

// blurでは何もしない
// $newSelect.on('blur', function(){
//   $(this).trigger('close');
// });

こんな感じでfocusの中でblurを呼ぶようにして、blurでは何もしないようにします。

ただしこのままだと、セレクトボックスが閉じなくなっちゃうので($(this).trigger('close')でcloseイベントを呼んでないからね)、他の箇所も修正します。2432行目らへんです。

options.find('li').each(function (i) {
  var $curr_select = $select;
  $(this).click(function () {
    // Check if option element is disabled
    if (!$(this).hasClass('disabled')) {
      $curr_select.find('option').eq(i).prop('selected', true);
      // Trigger onchange() event
      $curr_select.trigger('change');
      $curr_select.siblings('input.select-dropdown').val($(this).text());
      $('.select-dropdown').trigger('close'); // ここでcloseイベントをtrigger
      if (typeof callback !== 'undefined') callback();
    }
  });
});

こんな感じ。

試してみる

material_selectのテスト2

むむっ。ムムムッ。成功っぽい。

他にもやり方はあると思うけど、とりあえずこんな感じでやってみたらキャレットが出なくなりました。

ソース

修正したソースはこちら。

参考程度にどうぞです。

作成者: shimabox

Web系のプログラマをやっています。 なるべく楽しく生きていきたい。

コメントする

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください