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

2022 VIVA JS World Cup 開幕!! 〜 Vue3で作るサッカーゲーム 〜

2022.12.24

OAuthのフローを可視化できるツールを作ってみました。

2020.05.17

令和の時代に、JavaScriptで Shift-JISファイル作成 全銀データフォーマットに対応する。

2020.03.03

インターネットにて世論調査を行う「世論Web」サービスを始めてみました。

2020.01.31

年末のレトロゲーム熱の際、ファミコンソフト一覧パッケージ作ってました。

2020.01.24

あと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

CATEGORY LIST

LATEST NEWS

Rust - Actix Web mongo ユーザー登録 JWT認証

Rust

2024.03.24

Rust - Actix Web JWT 認証認可 APIの作成

Rust

2024.02.25

Rust - Actix Web × JSON 静的ファイルをAPIで返却

Rust

2024.01.19

Rust - Actix Web × MongoDB環境をサクッと起動

Rust

2024.01.18

5分で学ぶ RustでWave Function Collapse (波動関数崩壊アルゴリズム)

Rust

2024.01.15

LLaMAモデル GGMLフォーマット(llama.cpp)をRustフレームワーク Leptosを用いて M1MacMiniでサクッと動かす。

Rust

2024.01.11

2024年 狙っているモバイルノートPC

tool

2024.01.07

MacOS XcodeにSDL2を追加

tool

2023.12.26

php 7.4にアップデート

PHP

2023.12.24

5分で覚える Flutter Flameで作る Wave Function Collapse - 波動関数崩壊アルゴリズム

AI・Bot・algorithm

2023.12.20

Flutter - Flameでゲーム作成 (キャラクターの移動)

Flutter

2023.07.23

Flutterで作る ChatGPT Prompt Manager

Flutter

2023.07.12

RANKING

Follow

SPONSOR

現在、掲載募集中です。



Links

About Us

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

Entry Profile

Graphical FrontEnd Engineer
- Daisuke Takayama

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

FOLLOW US