このサイトは、只今WEB業界で活躍中のデザイナー、プログラマーの方々の情報を集めたweb統合情報サイトです。

Archives Details

【保存版】スマートフォン制作でよく使うJavaScript まとめ

JavaScript

2013.10.21

この記事は最終更新日から1年以上が経過しています。

今回は、スマートフォンサイト、webビューApp(ハイブリッドApp)等HTML5、CSS3、JavaScript等を用いてコンテンツを制作する際によく使う(使うと便利)JavaScriptをまとめてみました。

ユーザーエージェント

スマートフォンサイトを制作する際に、ユーザーエージェントを取得し端末により表示や関数を実行したりすることが多々あります。

取得方法、振分け方等の詳細は当サイトやその他のweb情報サイトにも多々UPされているかと思いますのでそちらをご参照ください。

それではscript

var ua = navigator.userAgent,
      uaFunc = function(s,h)  { return (h.indexOf(s) > -1)};
var userInfo = {};

if(uaFunc("iPhone", ua)) {
     userInfo.device = "iPhone";
} else if(uaFunc("iPad", ua)) {
     userInfo.device = "iPad";
} else if(uaFunc("Android", ua)) {
     userInfo.device = "Android";
} else {
     userInfo.device = "PC";
}

更に、OSのバージョンによって色々分岐させたい時も発生します。

iPhone、AndroidのOSのバージョンの取得方法は以下となります。

function uaGetVer(myKey,contextEnd) {
  var myStart = ua.indexOf(myKey) + myKey.length,
       myEnd = ua.indexOf(contextEnd, myStart);
  return "Ver." + ua.substring (myStart,myEnd);
}

それぞれバージョンが記載されている文字列を検索し、取得する方法となります。

iPhoneに関しては5_0等、「_」が付く表記となりますので、置換処理等を行うと良いでしょう。

まとめたscriptはこちらとなります。

script

var ua = navigator.userAgent,
    uaFunc = function(s,h)  { return (h.indexOf(s) > -1)};
var userInfo = {};

if(uaFunc("iPhone", ua)) {
  userInfo.device = "iPhone";
} else if(uaFunc("iPad", ua)) {
  userInfo.device = "iPad";
} else if(uaFunc("Android", ua)) {
  userInfo.device = "Android";
} else {
  userInfo.device = "PC";
}

if(userInfo.device == "iPhone") {
  userInfo.ver = uaGetVer("iPhone OS", "like");    
} else if(userInfo.device == "iPad") {
  userInfo.ver = uaGetVer("CPU OS", "like");
} else if(userInfo.device == "Android") {
  userInfo.ver = uaGetVer(userInfo.device, ";");    
} else {
  userInfo.ver = null;
}

function uaGetVer(myKey,contextEnd) {
  var myStart = ua.indexOf(myKey) + myKey.length,
       myEnd = ua.indexOf(contextEnd, myStart);
  return "Ver." + ua.substring (myStart,myEnd);
}

要素位置(座標)取得

特定の要素の座標を取得したい。と言ったとき、div.position 等で取得できそうでできないのがJavaScriptです。w

windowに対する座標を取得する方法は、特定の要素の親要素のoffsetTopを取得し、更にその親要素のoffsetTop..

とscriptの再帰を行い取得していくやり方となります。

var elm = document.getElementById("elm");

var getElmPosition = function(elm) {
      var left = 0,
          top = 0;
      while(elm.parentNode) {
        left += elm.offsetLeft;
        top += elm.offsetTop;
        elm = elm.parentNode;
      }
      return {"left" : left, "top" : top};
    }
var elmPos = getElmPosition(elm);

配列のクローン(ディープコピー)作成

ある配列をコピーしたい。と思い、

var defaultItem = [0,1,2,3,4,5,6,7];
cloneItem = defaultItem;

このように記述してもJavaScriptではオブジェクトを参照しているので途中コピー元の値が変更すると、

defaultItem[0] = 5;

コピー先の値も変更してしまう結果となります。

コピー先の値を変更しない様にするには、さらに配列に格納し再帰を行いコピーするやり方となります。

var cloneItem = new Array();
var defaultItem = [0,1,2,3,4,5,6,7];

//clone
Array.prototype.clone = function() {
  if (this[0].constructor == Array ) {
    var ar, n;
    ar = new Array(this.length);
    for(n = 0; n < ar.length; n++) {
      ar[n] = this[n].clone();
    }
    return ar;
  }
  return Array.apply(null, this);
}
for(var i = 0, il = defaultItem.length; i < il; i++) {
  cloneItem = defaultItem.clone();
}

defaultItem[0] = 5;

translateプロパティ取得

現在適応されているCSS StyleをJavaScriptでstyleを取得する際、

getComputedStyle(Element, null);

等で取得することが可能となっております。

このように取得することができます。

更にこのようにCSSプロパティを指定することによって、各プロパティの値を取得することができます。

getComputedStyle(Element, null).getPropertyValue("cssプロパティ名");

web技術を用いて、よりリッチなコンテンツを作ろうとした際、CSS3 のtranslateやscale等のtransformプロパティを扱うことが多々あります。

そこでtranslateのプロパティを取得しようと、

window.getComputedStyle(elm, null).getPropertyValue("-webkit-transform");

としても

このような値で帰ってきて思ったように値が取れないかと思います。

これは、transformがmatarix値で設定されている為となります。

matarixはmatrix(a, b, c, d, e, f) との様に6つの値で要素を変化させることが可能です。

1番目の数値は、水平方向の縮尺(a)

2番目の数値は、垂直方向の傾斜率(b)

3番目の数値は、水平方向の傾斜率(c)

4番目の数値は、垂直方向の縮尺(d)

5番目の数値は、水平方向の移動距離(e)

6番目の数値は、垂直方向の移動距離(f)

デフォルトの値はmatrix(1, 0, 0, 1, 0, 0)となっています。

translateの場合だと、 5番目の水平方向の移動距離と、6番目の垂直方向の移動距離を変化します。

つまり、matrix(1, 0, 0, 1, 10, 10)はtranslate(10px,10px)と同じとなります。

このmatrix値を取得するscriptとなります。

var computedStyle,mat,a,b,c,d,e,f,
reMat = /matrix\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\)/;

computedStyle = window.getComputedStyle(elm, null);
mat = computedStyle['-webkit-transform'].match(reMat).slice(1);
a = parseFloat(mat[0], 10);
b = parseFloat(mat[1], 10);
c = parseFloat(mat[2], 10);
d = parseFloat(mat[3], 10);
e = parseFloat(mat[4], 10);
f = parseFloat(mat[5], 10);
使用例:

HTML

<div id="result"></div>
<div id="elm" style="margin:60px 0 0 80px; width:100px; height:100px; background:#f00; -webkit-transform:translate(20px,10px);"></div>

JavaScript

var div = document.getElementById("result"),
    elm = document.getElementById("elm");

var computedStyle,mat,a,b,c,d,e,f,
reMat = /matrix\(\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\,\s*(-?\d+(?:\.\d+)?)\s*,\s*(-?\d+(?:\.\d+)?)\s*\)/; 

computedStyle = window.getComputedStyle(elm, null);
mat = computedStyle['-webkit-transform'].match(reMat).slice(1);
a = parseFloat(mat[0], 10);
b = parseFloat(mat[1], 10);
c = parseFloat(mat[2], 10);
d = parseFloat(mat[3], 10);
e = parseFloat(mat[4], 10);
f = parseFloat(mat[5], 10);

div.innerHTML = "mat:" + mat + "<br>" + "a:" + a + "<br>" + "b:" + b + "<br>" + "c:" + c + "<br>" + "d:" + d + "<br>" + "e:" + e + "<br>" + "f:" + f + "<br>";

二度押し防止

スマートフォンサイトを制作していると、ボタンを押して処理までに時間がかかり、

ユーザーが「押してない」と判断してしまいもう一度ボタンが押されて、二度アクセスが行ってしまいエラーが起きてしまった。

などのトラブルが起こりがちでありますので、コレを防止する処理となります。

最初のtouchendから一定時間経過しないともう一度実行できない様にするやり方となります。

 function noDoubleTap(doubleTapElms) {
    var accessTime = 1500,
        doubleAccess = false,
        doubleTapElms = doubleTapElms;
    var doubleTapController = function() {
      var that = this;
      that.init = function() {
        for(var i = 0;i < doubleTapElms.length;i++) {
          doubleTapElms[i].addEventListener("click", function(e){that.doubleTapFunc(e);}, false);
          doubleTapElms[i].addEventListener("touchstart", function(e){that.doubleTapFunc(e);}, false);
          doubleTapElms[i].addEventListener("touchend", function(e){that.doubleTapFunc(e);}, false);
        }
      }
    };
    doubleTapController.prototype = {
      doubleTapFunc: function(e){
        if(e.type == "touchstart" || e.type == "click"){
          return;
        } else{
          if(doubleAccess == false){
            doubleAccess = true;
            setTimeout(function(){
              doubleAccess = false;
            },accessTime);
          } else{
            e.preventDefault();
            return;
          }
        }
      }
    }
    var doubleTapControll = newdoubleTapController();
        doubleTapControll.init();
  }
  document.addEventListener("DOMContentLoaded", function(){
    var doubleTapElms,
        doubleTapClass =['.js_doubleTap'];
    for(var name in doubleTapClass) {
      if(doubleTapClass.hasOwnProperty(name)){
        doubleTapElms = document.querySelectorAll(doubleTapClass[name]);
        noDoubleTap(doubleTapElms);
      }
    }
  }, false);

Ajax処理

最後にAjax処理となります。

それぞれ、エラーが発生した際、成功した際の処理を追加してください。

var AjaxTime = 10000;
var AjaxPath = {
    requestFile: "ajaxPath"
};

var AjaxController = function(){};
AjaxController.prototype ={
  createHttpRequest: function() {
    try {
      return newXMLHttpRequest();
    } catch(e){}
  },
    
  ajaxError: function() { return; },
      
  requestFile: function() {
    var that = this,
    httpObj = that.createHttpRequest();
    var timeout = false,
        timer =setTimeout(function(){
          timeout = true;
          httpObj.abort();
        }, AjaxTime);

    httpObj.open("POST",AjaxPath.requestFile, true);
    httpObj.onreadystatechange = function() {
      if(httpObj.readyState !== 4){ return; }
      if(timeout) {
        that.ajaxError();
        return;
      };
      clearTimeout(timer);
      if(httpObj.status == 200){ }
    }
    httpObj.send(null);
    return;
  }
}

ではではぁ

Comment

Related Article

あと10日で「jsdo.it」のサービスが終わってしまう!! ソースダウンロードまだの方は急げぇ〜!

2019.10.21

正規表現 先読み後読み 論理積

2019.07.28

「二段階認証?」という方も 5分で覚える パスワードレス WebAuthnのまとめ

2019.07.07

上級者向け JavaScript 問題集 「javascript-questions」日本語翻訳担当してます。

2019.06.22

SPAサイトでの認証認可 JWT✗Rails5✗Nuxt.js

2019.03.24

Nuxt.js と auth-module (@nuxtjs/auth)で、JWT(JSON Web Tokens)& OAuth 認証 ログイン

2019.02.21

ブラウザフィンガープリントは、Cookieの代用となるのか? JSライブラリ Fingerprintjs2など。

2019.02.03

Vue.jsでSPA、Vuex使用するなら Nuxt.jsが超絶便利な件。

2018.12.23

nodeのない環境にnodeを導入(HTML5ゲームも提供)し続け、1年数ヶ月経過後、かなり開発環境が整ってきたお話。

2018.09.26

Vue.js + SSR (Universal JavaScript)環境を、「NUXT.js」でサクッと構築する方法。

2017.10.09

CATEGORY LIST

LATEST NEWS

kindleストア7周年記念セール中!技術書なども40%OFF以上でお買い得!(11/7まで)

イベント

2019.10.28

あと10日で「jsdo.it」のサービスが終わってしまう!! ソースダウンロードまだの方は急げぇ〜!

JavaScript

2019.10.21

Arduino IDEとArduino接続して、サクッと設定。

電子工作

2019.08.15

ついに、M5Stack Gray 購入!! その他諸々、購入したボードの振り返りなど。

電子工作

2019.08.12

正規表現 先読み後読み 論理積

JavaScript

2019.07.28

PythonでGUIアプリ開発「PyQt」を使った感想

Python

2019.07.18

「二段階認証?」という方も 5分で覚える パスワードレス WebAuthnのまとめ

JavaScript

2019.07.07

上級者向け JavaScript 問題集 「javascript-questions」日本語翻訳担当してます。

JavaScript

2019.06.22

Wordpress サイトで、長時間 500 Internal Server Error発生。解決した方法とは。

WordPress

2019.06.18

Ubuntu 18.04 LTSで OpenGL開発

ubuntu

2019.05.20

MacOS Mojave (10.14.4)の Xcode に、過去のMacOSのSDKをインストール

C++

2019.05.19

クローンソフトの「EaseUS Disk Copy」を使って、OSのバックアップを取ってみた。

tool

2019.05.06

RANKING

Follow

SPONSOR

現在、掲載募集中です。



Links

About Us

WEBデザイナーの、WEBデザイナーによる、WEBデザイナーの為のサイト。「みんなで書こう!」と仲間を募ってみたが、結局書くのは自分だけとなってしまいました。日々のメモを綴っていきます。

Entry Profile

Graphical FrontEnd Engineer
- Daisuke Takayama

MAD CITY 北九州市で生まれ育つ。20代はバンド活動に明け暮れ、ふと「webデザイナーになりたい。」と思い、デジタルハリウッド福岡校入学。卒業後、数々の賞を受賞、web業界をざわつかせる。
現在、主に、ゲーム制作中心に港区六本木界隈で活動中。

FOLLOW US