tedshd's DevNote

Develop & Design Note by Ted

Your posts match “ javascript ” tag:

JavaScript function

function

function fun() {
    // do something

}
fun();
var fun = function () {
    // do something

};
fun();

立即函數(建立後立即執行,只執行此次)

var fun = (function () {
    // do something

}());

innerHeight & innerWidth

innerHeight & innerWidth

抓取瀏覽器目前顯示高度與寬度
一般都用

window.innerHeight

window.innerWidth

但唯獨IE6~IE8不行
Google了一下
發現用

window.document.documentElement.clientHeight

window.document.documentElement.clientWidth

便兼容所有瀏覽器

scrollHeight

如要抓 document 的高可用

document.body.scrollHeight

Refer

JavaScript type

JavaScript Type

  • number
  • string
  • boolean
  • null
  • undefind

減少 type 轉換以加快執行速度

Object

var

  • 宣告後即擁有物件的屬性
  • 宣告之後無法刪除
    • 區域變數

function 內宣告

  • 全域變數

小心使用

property

  • 建立在物件中
  • 可刪除

Array

  • method 1
var arr = new Array();

bug

var arr = new Array(10);
arr
// [undefined × 10]
  • method 2
var arr = [];

JavaScript - onbeforeunload

onbeforeunload

onbeforeunload 是在 browser 在轉換頁面時會觸發的事件
當有 return 值時, 會出現 confirm 視窗, 並停住觸發的行為
目前試過會觸發的行為有

  • 上一頁 / 下一頁
  • 重新整理
  • 關閉視窗
  • 前往其它 URL
  • submit 事件
  • URL 改變時

這幾種較常見
用法如下

var fun = function () {
    return 'Exit?';
}
window.onbeforeunload = fun;

return 的值是 confirm 的訊息
可 return string or array
無法 return fuinction

也可以用條件判斷

var fun = function () {
    var value = document.getElementsByTagName('textarea')[0].value;
    if (value) {
        return 'Exit?';
    }
    return;
}
window.onbeforeunload = fun;

上面說明了當 textarea 有值時, 觸發 onbeforeunload 才 return 訊息出來

Issue

當使用 <a href=""></a> 時, 通常會用 <a href="#"></a> or <a href="javascript:void(0)"></a> 來使 href 沒有作用, 但用 # 會在 URL 的最後產生 # , 且頁面會捲動到頂部, 這是因為 # 的特性, 所以通常不會用 <a href="#"></a>

但是當使用 <a href="javascript:void(0)"></a> 時, 再與 onbeforeunload 一起用時就會有問題

demo

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>onbeforeunload_javascript.void(0)</title>
<script>
var fun = function () {
    return 'exit?';
}
window.onbeforeunload = fun;
</script>
</head>
<body>
    <a href="javascript:void(0)">javascript:void(0)</a>
</body>
</html>

上面的 HTML 在執行時都沒問題, 但是在 IE 中, 會把 href="javascript:void(0)" 當成一個無效的連結
所以就觸發了 onbeforeunload 事件
而解決辦法也很簡單, 就是 e.preventDefault()

  • JavaScript(IE9 up)
    demo

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>onbeforeunload_e.preventDefault()</title>
    </head>
    <body>
    by javascript<br>
    <a href="javascript:void(0)">e.preventDefault()</a>
    </body>
    <script>
    var fun = function () {
        return 'exit?';
    }
    window.onbeforeunload = fun;
    var tag = document.getElementsByTagName('a')[0];
    tag.addEventListener('click', function (e) {
        e.preventDefault();
    });
    </script>
    </html>
    
  • jQuery
    demo

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="utf-8">
    <title>onbeforeunload_e.preventDefault()</title>
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
    <script>
    $(function () {
    var fun = function (e) {
        return 'exit?';
    }
    window.onbeforeunload = fun;
    $('a').on('click', function (e) {
        e.preventDefault();
    });
    });
    </script>
    </head>
    <body>
    <a href="javascript:void(0)">e.preventDefault()</a>
    </body>
    </html>
    

Refer
MDN

JavaScript - design pattern

JavaScript - design pattern

避免與減少全域變數(global variable)

全域變數非常方遍使用, 但使用的不好會使 JavaScript 有問題
因為有可能重複使用且有可能別的 library 也有用到該名稱
JavaScript: 優良部分 書中提到可用物件的方式包起來

var GlobalObj = {};
// 開始定義

GlobalObj.var1 = 'string';
GlobalObj.arr = [1, 2, 3];
...

// or

var GlobalObj = {
        var1: 'string',
        arr: [1, 2, 3]
    };

使用 閉包(Closure) 也是一個避免全域變數的方法

Place on and embed code from internet

Place on and embed code from internet

We can use cdnjs or some library sites embed js or css.
But
How can we embed our code from internet?
I have 2 ways.

GitHub

If you can use GitHub
Push your code to GitHub
Wtach code on GitHub
Find Raw and click it.
open code like

https://raw.github.com/tedshd/jQuery_scroll_to_top/master/javascripts/scroll_to_top.js

and then delete . after raw like

https://rawgithub.com/tedshd/jQuery_scroll_to_top/master/javascripts/scroll_to_top.js

Embed it finally.

Dropbox

Place on code in dropbox.
Share this code
get share link like

https://www.dropbox.com/s/ie4b129u0thjcyw/logdown_theme.css

and replace www as dl

https://dl.dropbox.com/s/ie4b129u0thjcyw/logdown_theme.css

Refer

Coding Style

Coding Style

條件判斷

在 PHP & JavaScript 中有許多邏輯判斷
當有許多條件要去檢查時, 一般來說就是用 if 一直寫下去
最後就造成下面的情況(以 PHP 為例)

if ($a === $b)
{
    if ($c)
    {
        if ($c >= 10)
        {
            if ($d)
            {
                // do something
                // ...
            }
        return;
        }
    return;
    }
}

這樣下去就沒完沒了, 而且縮排會越來越多, 要看 code 也很不方便
所以假如就已作條件檢查來說
可以用以下的做法

// check condition 1
if ($a !== $b)
{
    return;
}

// check condition 2
if (!$c || $c === '')
{
    return;
}

// check condition 3
if ($c < 9)
{
    return;
}

// check condition 4
if (!d)
{
    return;
}

// do something
// ...

做個 反向思考 , 把不適合的條件列出再一一 return or 作處理
剩下的便是所需要的

從巢狀式結構變成區域式
結構也較為清晰
debug 也較容易

有時也會遇到應該用 switch 卻用 if 去一直加下去的情況
所以當 if 用到 3 個 以上時, 就要思考要用什麼敘述來達到目的比較好
也許可以用 switch

function

有時遇到很多 code 重複時, 我們可以抽離這些重複的部分, 把它放到一個 function 中
要用時在再去呼叫那個 function

Refer-代码的抽象三原则

以錯誤為優先處理

JavaScript

function doSomething(data) {
    if (data.status === 'fail') {
        // handle error

    } else {
        // handle ok

    }
}

瀑布流(Pinterest-style) layout

瀑布流(Pinterest-style) layout

目前看見 3 種作法

  • jquery plug in
  • salvattore.js
  • CSS3 column

jquery plug in

Masonry

一款較多人使用的 jQuery plug in, 可向下相容到 IE8
Masonry

Grid-A-Licious

jQuery plug in, 向下相容到 IE9
Grid-A-Licious

salvattore

利用 data attribute 來達到 CSS3 column 的效果
獨立運作的 js 不必依靠其他的 js library
輕巧快速
向下相容到 IE9
salvattore
不過沒 CSS 所以要加入 CSS 以便讓版面順利出來
已修改的 salvattore
CSS source code(可依需求進行修改)

@-webkit-keyframes showsup {
  from { opacity: 0; -webkit-transform: translate(0, -20px); }
  to   { opacity: 1; -webkit-transform: translate(0, 0); }
}
@-moz-keyframes showsup {
  from { opacity: 0; -moz-transform: translate(0, -20px); }
  to   { opacity: 1; -moz-transform: translate(0, 0); }
}
@-o-keyframes showsup {
  from { opacity: 0; -o-transform: translate(0, -20px); }
  to   { opacity: 1; -o-transform: translate(0, 0); }
}
@keyframes showsup {
  from { opacity: 0; transform: translate(0, -20px); }
  to   { opacity: 1; transform: translate(0, 0); }
}

.salvattore-grid-b .item.added {
  -webkit-animation: showsup 0.5s;
  -moz-animation: showsup 0.5s;
  -o-animation: showsup 0.5s;
  animation: showsup 0.5s;
}

.layout-redux {
  width: 75%;
  margin-left: auto;
  margin-right: auto;
}

.column {
  float: left;
  width: 100%;
}

.one-half {
  width: 50%;
}
.one-third {
  width: 33.333%;
}
.one-quarter {
  width: 25%;
}
.hide {
  display: none;
}

@media screen and (max-width: 480px) {
  body {
    padding: 0 20px;
    font-size: 14px;
  }
  .rs-font-alpha, h1 {
    font-size: 36px;
  }

  .rs-font-beta {
    font-size: 24px;
  }

  .rs-font-gamma {
    font-size: 18px;
  }

  .rs-font-delta {
    font-size: 18px;
  }

  .branding {
    font-size: 72px;
  }
  .layout-redux {
    width: inherit;
  }
}
@media screen and (min-width: 481px) and (max-width: 768px) {
  body {
    font-size: 16px;
  }
  .rs-font-alpha, h1 {
    font-size: 48px;
  }

  .rs-font-beta {
    font-size: 36px;
  }

  .rs-font-gamma {
    font-size: 24px;
  }

  .rs-font-delta {
    font-size: 24px;
  }

  .branding {
    font-size: 96px;
  }

  .layout-redux {
    width: inherit;
  }
}

/* Grids */
.salvattore-grid,
.salvattore-grid-b {
  margin: 0 -10px;
}

[data-columns]:before {
  display: none;
}

.salvattore-grid[data-columns]:before {
  content: '4 .column.one-third';
}
.salvattore-grid-b[data-columns]:before {
  content: '3 .column.one-half';
}

@media screen and (max-width: 480px){
  .salvattore-grid[data-columns]:before,
  .salvattore-grid-b[data-columns]:before {
    content: '1';
  }
}

@media screen and (min-width: 481px) and (max-width:819px) {
  .salvattore-grid[data-columns]:before {
    content: '2 .column.one-half';
  }
}
@media screen and (min-width: 820px) and (max-width: 1299px) {
  .salvattore-grid[data-columns]:before {
    content: '3 .column.one-third';
  }
}
@media screen and (min-width: 1300px){
  .salvattore-grid[data-columns]:before {
    content: '4 .column.one-quarter';
  }
}

@media screen and (min-width: 481px) and (max-width: 1099px) {
  .salvattore-grid-b[data-columns]:before {
    content: '2 .column.one-half';
  }
}
@media screen and (min-width: 1100px) {
  .salvattore-grid-b[data-columns]:before {
    content: '3 .column.one-third';
  }
}

CSS3 column

依情況需作 responsive web design
不然 layout 在做縮放會跑掉

CSS 必須調整好

/*--指定分欄數量--*/
.col {
    column-count: 2;
    -webkit-column-count: 2;
    -moz-column-count: 2;
}
/*--指定分欄寬度(預設 auto)--*/
.col {
    column-width: 50px;
    -webkit-column-width: 50px;
    -moz-column-width: 50px;
}

HTML 依照下面的寫法

<ul class="col">
    <li>
        <!-- do something -->
    </li>
    <li>
        <!-- do something -->
    </li>
    <li>
        <!-- do something -->
    </li>
</ul>

Html5(css3)的瀑布流布局的实现

file upload using ajax

File upload using ajax

Use FormData objects
Using FormData Objects

FormData object only IE 10 up
if IE use ajax upload, only use iframe method.

sample

HTML

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>upload_AJAX</title>
</head>
<body>
    <form action="upload_one.php" method="post" enctype="multipart/form-data">
        <label for="file">File:</label>
        <input type="file" name="Upfile" id="select"><br>
        <input type="submit">
    </form>
    <a href="javascript:upload()">AJAX_upload</a>
</body>
</html>

JavaScript

function upload () {
    // init FormData object

    var formData = new FormData();
    // use append method append upload file

    formData.append('Upfile', document.getElementById('select').files[0]);
    // init XMLHttpRequest object

    var xmlHttpRequest = new XMLHttpRequest();
    // init to backend

    xmlHttpRequest.open('POST', 'upload_one.php');
    // check ajax status

    xmlHttpRequest.onreadystatechange = function () {
        if (xmlHttpRequest.readyState == 4) {
            if (xmlHttpRequest.status == 200) {
                alert('upload');
            }
        }
    };
    // post to backend

    xmlHttpRequest.send(formData);
}

AJAX - XMLHttpRequest

AJAX - XMLHttpRequest

Use XMLHttpRequest object handle AJAX

client -> server
Front-end - request -> back-end
client <- server
Front-end <- response - back-end

build XMLHttpRequest(old method)

JavaScript

var httpRequest;
if (window.XMLHttpRequest) {
    //IE7,Mozila,Safari...

    httpRequest = new XMLHttpRequest();
} else if (window.ActiveXObject) {
    //IE5,IE6

    //找出最新版MSXML剖析器

    var msxmls = ["MSXML2.XMLHttp.4.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp","Mircosoft.XMLHttp"];
    for (i = 0; i < msxmls.length; i++) {
        try {
            //建立XMLHttpRequest物件

            httpRequest = new ActiveXObject(msxmls[i]);
            break;
        } catch (e) {
            // do something

        }
    }
}

New browser have XMLHttpRequest object now.
MDN
JavaScript

var xmlHttpRequest = new XMLHttpRequest();

2 type to post data to backend(send request)

1 FormData(if IE, 10 up)

// init FormData

var formData = new FormData();
// add data

formData.append('user', 'Ted_Shiu');
formData.append('password', '123456');
// init XMLHttpRequest

var xmlHttpRequest = new XMLHttpRequest();
// build poet method and backend target

xmlHttpRequest.open('POST', 'ajax.php');
// send request

xmlHttpRequest.send(formData);

2 JSON

// obj is data want to post to backend

var obj = {
        'user': 'ted_shiu',
        'password': '123456'
    },
    jsonData;
// init XMLHttpRequest

var xmlHttpRequest = new XMLHttpRequest();
// build poet method and backend target

xmlHttpRequest.open('POST', 'json.php');
// build content type

xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
// obj to url string

function formUrlEncode(obj) {
    var urlData = '';
    for (var x in obj) {
        urlData = urlData + x + '=' + obj[x] + '&';
    }
    urlData = urlData.substr(0, (urlData.length - 1));
    return urlData;
}
// send request

xmlHttpRequest.send(formUrlEncode(obj));
// if want ajax get data

// use xmlHttpRequest.send();

// xmlHttpRequest.send('user=ted_shiu&password=123456');

Backend(handle request and response browser)

PHP

// ajax.php
<?php
    if (isset($_POST['user'])) {
        // do something
        if ($_POST['password']) {
            // do something
            $output = array(
                'status' => 'ok',
                'message' => 'msg'
            );
            // echo is reponse browser, must use json_encode()
            echo json_encode($output);
        }
    }
?>
// json.php
<?php
var_dump($_POST);
echo '<br>';
echo $_POST['user'];
echo '<br>';
echo $_POST['password'];
?>

Refer - 你不可不知的 JSON 基本介紹
Refer - Ajax and JSON

Response

AJAX handle response from backend
check response state, use XMLHttpRequest properties

xmlHttpRequest.onreadystatechange = function() {
    if (xmlHttpRequest.readyState == 4) {
        // do something

        if (xmlHttpRequest.status == 200) {
            alert(xmlHttpRequest.responseText);
            // parse response to object

            var data = JSON.parse(xmlHttpRequest.responseText);
            alert(data.status);
        }
    }
}

javascript - file upload

javascript - file upload

Introduction

利用 javascript 達到檔案上傳的功能

Skill

  • files API
  • AJAX
  • iframe
  • FormData
  • ...

Develop

  • 單純用 javascript
  • 利用 AJAX 上傳
  • 處理 AJAX 上傳在 IE 的問題(利用 iframe 也許可解, Refer)
  • 處理拖拉
  • 處理拖拉資料夾
  • 處理預設樣式

Issue

  • FormData
    • AJAX 上傳(IE10 以上)
    • IE 利用 iframe 實作

Dseign flow

Attribute
  • inputFileNode(input type file element)
  • fileName(name="")
  • server(the file upload to server url)
  • dropArea(set the drop area)
Method
  • upload
  • cancel
Event

Use CustomEvent (IE 9 up)
Refer - How to Create Custom Events in JavaScript

  • selectFiles
    • e.fileList (Array)
      • name
      • size
      • type
    • e.length (number)
  • uploadError
  • uploadProgress
    • e.bytesLoaded (number)
    • e.bytesTotal (number)
    • e.percentLoaded (number)
  • uploadComplete
  • dragenter
  • dragover
  • drop
  • drag

develop log

How to do?

Use JavaScript no require any library
Use AJAX to upload
Must know how to use XMLHttpRequest and use it upload file
Use FormData handle ajax upload files, but it only for IE 10
So IE maybe use iframe upload
Must easy to use
It has many useful method and event
Must handle custom event(have cross browser problem)
Use File API handle file list, it only for IE10

About code

Use querySelector replace getElementById、getElementsByTagName...etc(IE8 up)
document.querySelector
Use node method to reduce code

var node;
function node (selector) {
    return document.querySelector(selector);
};

// use
node('#id'); // html id
node('.class'); // html class
node('div'); // html element

for IE get upload file name

var fileName = document.querySelector('#uploadfile').value.match(/[^\/\\]+$/);

Refer - PHP Error Messages Explained

JavaScript - handle JSON

handle JSON

先了解 Object & JSON
JavaScript 物件導向的寫法
你不可不知的 JSON 基本介紹

// data can get from AJAX or self

var data;
// init from self

// Object Literal

data = {
    "data_01": {
        "title": "title 01",
        "num": 01,
        "con": {
            "con_01": {
                "name": "news",
                "desc": "about news"
            }
            "con_02": {
                "name": "sport",
                "desc": "sport like NBA"
            }
            "con_03": {
                "name": "tech",
                "desc": "3C info"
            }
        }
    },
    "data_02": {
        "title": "title 02",
        "num": 02,
        "con": {
            "con_01": {
                "name": "life",
                "desc": "people's life"
            }
            "con_02": {
                "name": "movie",
                "desc": "Iron man ..."
            }
            "con_03": {
                "name": "cars",
                "desc": "TOYOTA, Ford..."
            }
        }
    }
};

init a new object array

var x,
    newData = {},
    newDataArr = [];
for (x in data) {
    if (data.hasOwnProperty(x)) {
        newData = {
            data[x].title,
            data[x].num
        };
        newDataArr.push(newData);
    }
}

get object con

var x,
    y,
    desc,
    newDescArr = [],
    newConArr = [];
for (x in data) {
    if (data.hasOwnProperty(x)) {
        for (y in data[x].con) {
            if (data[x].con.hasOwnProperty(y)) {
                desc = data[x].con[y].desc;
                newDescArr.push(desc);
            }
        }
        newConArr.push(newDescArr);
    }
}

search value in Object

var data = {
    'bind': 27,
    user: [
        {
            'id': 12,
            'desc': 'str'
        },
        {
            'id': 34,
            'desc': 'hahaha'
        },
        {
            'id': 27,
            'desc': 'hihihi'
        }
    ]
};
var x;
for (x in data.user) {
  if(data.user[x].uid === data.bind) {
    count = x;
  }
}
console.log(data.user[count]);
alert(JSON.stringify(data.user[count]));

JavaScript - Event

JavaScript - Event

  • event type
    事件名稱

  • event target
    事件發生在哪一個目標上

  • event handler or listener
    處理或回應的 function, 即監聽或註冊事件

  • event object
    與事件關聯的物件

  • event propagation
    氣泡(bubble)現象

  • default actions
    觸發事件時的預設行為, 有時必須取消該行為

GlobalEventHandlers

  • HTML

    <button id="btn">Click</button>
    
  • JavaScript

    var nodeBtn = document.getElementById('btn');
    nodeBtn.onclick = function (e) {
    alert('ok');
    };
    

event

  • HTML
    <button id="btn">Click</button>
    

Use addEventListener(only IE9 up)
addEventListener

  • JavaScript
    var nodeBtn = document.getElementById('btn');
    nodeBtn.addEventListener('click', function () {
    alert('ok');
    });
    

delegate

If use dynamic page the dom maybe not init in the page load
So use delegate

var div = document.createElement('div'),
    prefix = ['moz','webkit','ms','o'].filter(function (prefix) {
        return prefix + 'MatchesSelector' in div;
    })[0] + 'MatchesSelector';

Element.prototype.addDelegateListener = function(type, selector, fn) {
    this.addEventListener( type, function(e) {
        var target = e.target;

        while(target && target !== this && !target[prefix](selector)) {
            target = target.parentNode;
        }
        if(target && target !== this) {
            return fn.call(target, e);
        }
    }, false );
};
  • example
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>javascript - delegate</title>
</head>
<body>

</body>
<script>
var div = document.createElement('div'),
    prefix = ['moz','webkit','ms','o'].filter(function (prefix) {
        return prefix + 'MatchesSelector' in div;
    })[0] + 'MatchesSelector';

Element.prototype.addDelegateListener = function(type, selector, fn) {
    this.addEventListener( type, function(e){
        var target = e.target;

        while(target && target !== this && !target[prefix](selector)) {
            target = target.parentNode;
        }
        if(target && target !== this) {
            return fn.call(target, e);
        }

    }, false );
};

document.querySelector('body').addDelegateListener('click', '#btn', function () {
    alert('ok');
});

document.body.innerHTML = '<button id="btn">Click</button>';
</script>
</html>

Refer - addEventListener for new elements

Refer - 為什麼有時你應該優先考慮 event delegate 而不是 event binding

Refer - An Introduction To DOM Events

Facebook api get UID & AccessToken

Facebook api get UID & AccessToken

  1. Build App in facebook
  2. APP_ID is a facebook App id
  3. Must set facebook App's web url and use code in it's domain
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>fb_oauth</title>
<script src="http://code.jquery.com/jquery-1.10.2.min.js"></script>
</head>
<body>
    <div id="fb-root"></div>
    <p>
        <input id="FBLogin" type="button" value="登入臉書" />
    </p>
    <p>
        <span id="uid"></span>
    <br>
        <span id="accessToken"></span>
    </p>
</body>
<script src="http://connect.facebook.net/zh_TW/all.js"></script>
<script>
    FB.init({
        appId: 'APP_ID',
        status: true,
        cookie: true,
        xfbml: true,
        oauth: true
    });
    $('#FBLogin').click(function () {
        FB.login(function (response) {
            // 登入之後執行的語法

        },
        {
            scope: 'email'
        });
    });
    FB.getLoginStatus(function (response) {
        if (response.status === 'connected') {
            // 程式有連結到 Facebook 帳號

            // 取得 UID

            var uid = response.authResponse.userID;
            // 取得 accessToken

            var accessToken = response.authResponse.accessToken;
            $('#uid').html('UID:' + uid);
            $('#accessToken').html('accessToken:' + accessToken);
        } else if (response.status === 'not_authorized') {
            // 帳號沒有連結到 Facebook 程式

            alert('請允許授權!');
        } else {
            // 帳號沒有登入

        }
    });
</script>
</html>

Demo

Refer - 使用 Facebook JavaScript SDK 來取得使用者 UID 或 AccessToken

Google map api - research log

Google map api - research log

Introduction

使用 Google Maps JavaScript v3
static map 嵌入地圖到網頁中以圖片方式呈現
使用限制 基本上不要一日載超過 25000 次都沒事
區域化 - 語系

Library

Init map

<!DOCTYPE html>
<!--使用 <!DOCTYPE html> 宣告,將應用程式宣告為 HTML5-->
<html>
<head>
<meta charset="utf-8">
<title>Google_map_api_basic</title>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no" />
<!--最新的瀏覽器會將使用此 DOCTYPE 宣告的內容以「標準模式」呈現,也就是說,您的應用程式應更具備跨瀏覽器相容性。此外,DOCTYPE 也設計成會逐漸適應,但無法理解它的瀏覽器將會忽略它,而採用「快速模式」顯示內容。請注意,有些 CSS 在快速模式中可以運作,但在標準模式中卻無效。具體來說,所有百分比的大小都必須繼承父區塊項目,但這些上階中如有任何一個無法指定大小,就會假設為 0 x 0 像素大小。基於這個理由,我們加入了下列 <style> 宣告-->
<style type="text/css">
html {
    height: 100%;
}
body {
    height: 100%;
    margin: 0px;
    padding: 0px;
}
#map_canvas {
    height: 100%;
}
</style>
<!--這個 CSS 宣告表示地圖容器 <div> (名為 map_canvas) 應使用 HTML 主體的 100% 高度。請注意,我們也必須特別宣告 <body> 和 <html> 的這些百分比-->
<script type="text/javascript" src="https://maps.google.com/maps/api/js?sensor=true"></script>
<!--使用 script 標記來涵蓋 Maps API JavaScript-->
<!--請注意,我們也必須設定 sensor 參數,以指出這個應用程式是否有使用感應器來判斷使用者的位置。必須明確地將這個值設為 true 或 false-->
</head>
<body onload="initialize()">
<!--從 body 標記的 onload 事件初始化地圖物件-->
  <div id="map_canvas" style="width:100%; height:100%"></div>
  <!--建立 div 元素 (名稱為「map_canvas」) 來容納「地圖」-->
</body>
<!--建立 JavaScript 物件實字以存放多個地圖屬性-->
<!--JavaScript 函式以建立「地圖」物件-->
<script type="text/javascript">
function initialize() {
    var myOptions = {
        center: new google.maps.LatLng(25.05060, 121.51870),
        zoom: 8,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    var map = new google.maps.Map(
        document.getElementById("map_canvas"),
        myOptions
    );
}

</script>
</html>

JavaScript map object

先建立地圖的設定
地圖選項

var myOptions = {
    center: new google.maps.LatLng(25.05060, 121.51870),
    zoom: 8,
    mapTypeId: google.maps.MapTypeId.ROADMAP
};
  • center 表示一開始地圖的中心位置
  • zoom 地圖縮放(0 ~ 18)
  • mapTypeId 地圖類型
    • ROADMAP 顯示 Google 地圖的正常、預設 2D 地圖方塊。
    • SATELLITE 可顯示攝影地圖方塊。
    • HYBRID 可顯示混合攝影地圖方塊與重要地圖項 (道路、城市名稱) 的地圖方塊圖層。
    • TERRAIN 可顯示實際起伏的地圖方塊,以呈現海拔高度和水域圖徵 (山嶽、河流等)。

初始化地圖
地圖物件

var map = new google.maps.Map(
    document.getElementById("map_canvas"),
    myOptions
);

Mark Google map

標記
標記在地圖上的位置

// list marks

var arr = new Array(
    {
        position: new google.maps.LatLng(25.05060, 121.51870),
        title: 'Hello World!'
    },
    {
        position: new google.maps.LatLng(25.056304, 121.522079),
        title: '春漾咖啡'
    }
);

// put marks in map

for (var i = 0; arr.length-1 >= i; i++) {
    var marker = new google.maps.Marker(arr[i]);
    marker.setMap(map);
};

Info windows

infowindows

標記上的 pop tooltip

var infowindow = new google.maps.InfoWindow();
Method
  • setContent()
  • open()
  • close()
Properties
  • content
  • disableAutoPan
  • maxWidth
  • pixelOffset
  • position
  • zIndex

Event

事件
Google map api 提供許多與 map 有關的事件

Style

樣式標記地圖

Detect mobile device

Detect mobile device

Use PHP or JavaScript detect mobile device like iPhone, iPad, iPod or Android...

Android

PHP
<?php
$ua = strtolower($_SERVER['HTTP_USER_AGENT']);
if(stripos($ua, 'android') !== false) {
    echo 'Android!!';
    exit;
}
?>
JavaScript
var ua = navigator.userAgent.toLowerCase();
if(ua.indexOf("android") > -1) {
    document.write('Android!!');
}

Refer - Android Detection with JavaScript or PHP

Apple mobile device

Refer - How to detect iPhone, iPod and iPad with PHP
Refer - How to Identify an Apple iPhone, iPod or iPad Visitor to Your Website

JavaScript - Easy to get DOM

JavaScript - Easy to get DOM

It is old way to use getElementById, getElementsByTagName ...

New method is use querySelector and querySelectorAll

If use IE, it only for IE8 up.

Make them as a method

var node;
function node(selector) {
    if (selector.indexOf('.') === -1) {
        if (document.querySelectorAll(selector).length === 1) {
            return document.querySelector(selector);
        }
        return document.querySelectorAll(selector);
    }
    return document.querySelectorAll(selector);
}

And then use it

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>querySelector</title>
</head>
<body>
    <div id="box" class="area">
        test
    </div>
    <div class="area">
        test2
    </div>
    <div id="selector" class="area">
        <p class="con">
            content
        </p>
    </div>
</body>
<script>
var node;
function node(selector) {
    if (selector.indexOf('.') === -1) {
        if (document.querySelectorAll(selector).length === 1) {
            return document.querySelector(selector);
        }
        return document.querySelectorAll(selector);
    }
    return document.querySelectorAll(selector);
}

console.log('ID', node('#box'));
console.log('CLASS', node('.area'));
console.log('SELECTOR_1', node('#selector p'));
console.log('SELECTOR_2', node('.area .con'));
</script>
</html>