このサイトは、只今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

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

フロントエンド開発が捗る JSON Serverについて

2017.07.10

技術書、参考書のしおりには【BOOK DARTS】がオススメ!

2017.07.01

会社で npm Private導入して、1ヶ月で8個ほどパッケージ作成したお話。

2017.06.02

Vue.js が予想以上に良かったので、既存WordPressに導入。Vue.js (vue-class-component) + TypeScript + WordPress で作る、記事読み込み component 「実装編」

2017.03.26

CATEGORY LIST

LATEST NEWS

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

Rails5 gemでmysql2が インストールできない

Ruby

2019.05.05

平成最後のお買い物!!「Logicool MX Master 2 Wireless Mouse」と「K780 マルチデバイス BLUETOOTH® キーボード」で快適PC生活。

ubuntu

2019.04.27

Amazon 87時間のビックセール タイムセール祭りで購入したもの

イベント

2019.04.23

Androidに Linuxを簡単にインストールするアプリ「UserLAnd」

Linux

2019.04.16

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

JavaScript

2019.03.24

CentOS MySQL(MariaDB) を バージョン10.3に yumでアップデート

MySQL

2019.03.22

Ubuntu 開発環境構築まとめ

ubuntu

2019.02.25

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

JavaScript

2019.02.21

HerokuでRailsをビルド buildpack、Rubyバージョンでエラー

エラー

2019.02.13

RANKING

Follow

SPONSOR

現在、掲載募集中です。



Links

About Us

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

Entry Profile

Graphical FrontEnd Engineer
- Daisuke Takayama

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

FOLLOW US