2014/11/04

網頁阻止IE相容性檢視語法



之前發現自己寫的 jQuery Mobile 網頁在 IE 上會異常。追半天才發現是網站被加入相容性檢視,強制以 IE6 的結果自然是無法呈現 jQuery Mobile 語法了。

解決的方法是在 <head> </head> 中加入這一行程式碼:

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />

意即使用 IE 來到此網頁時,需以實際的版本或 Chrome 檢視。

其餘相關語法,例如強制相容 IE6 ,請參考: 【HTML教學】X-UA-Compatible設置IE兼容模式

2014/10/21

和歌壽司




之前提到公司附近一家偽日式餐廳,開幕不到三個月後關門大吉。 (食記:上田日式定食)

沉寂一段時間後,又開了新的日式餐廳:和歌壽司 (Waka sushi)

以一般上班區域餐廳來說並不平價,但食材用的很好。

手機拍的菜單:






飲料是羅漢果茶。


老婆點的日本綜合魚天丼。


我的天丼,味噌湯裡有不同的魚片,很豐富。中間小碗是醬汁,直接淋在丼飯上。


小方盤是十月底之前,慶開幕送的80元炸蝦,配著盤中的胡椒鹽很不錯。小圓盤應該是岩鹽,口感也很棒!

丼飯很豐富,連干貝也炸下去了。份量很大碗,一碗199塊扣除成本老實說沒賺多少,是一個滿適合請客吃飯的地點。只是單點不要點太多,會大失血!

店名:和歌壽司 (Waka Sushi)
地址:台北市重慶南路一段66號一樓

2014/09/11

Node.js 搜尋目錄裡的所有的.html檔案,是否有某個字串



筆記,原文網址: http://stackoverflow.com/questions/6959462/in-node-js-reading-a-directory-of-html-files-and-searching-for-element-attribu

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
var fs = require('fs');

fs.readdir('/path/to/html/files', function(err, files) {
    files.filter(function(file) { return file.substr(-5) === '.html'; })
         .forEach(function(file) { fs.readFile(file, 'utf-8', function(err, contents) { inspectFile(contents); }); });
});

function inspectFile(contents) {
    if (contents.indexOf('data-template="home"') != -1) {
        // do something
    }
}

2014/08/22

Mac 取消滑鼠右鍵選單 CleanMyMac 項目



CleanMyMac 是一套滿好用的空間整理程式。但平常點選右鍵要編輯檔案時,會多出兩個我不太會去用的功能:Securely Erase with CleanMyMac 、 Erase with CleanMyMac。


剛看到一篇 VICJHT 網友分享的文章:如何取消蘋果電腦右鍵裏頭不需要的服務選單,解決了我的問題,也一併分享給大家!

首先,在點選系統偏好設定,再點選鍵盤

快速鍵頁中,點選服務。將 Erase with CleanMyMac 和 Securely Erase with CleanMyMac 取消勾選即可。

2014/08/20

Node.js 使用網頁更新MongoDB資料



需要安裝下列 module:
npm install express
npm install mongodb
npm install --save body-parser

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
var express = require('express');

var MongoClient = require('mongodb').MongoClient
    , format = require('util').format;    

/*
 * body-parser is a piece of express middleware that 
 *   reads a form's input and stores it as a javascript
 *   object accessible through `req.body` 
 *
 * 'body-parser' must be installed (via `npm install --save body-parser`)
 * For more info see: https://github.com/expressjs/body-parser
 */
var bodyParser = require('body-parser');

// create our app
var app = express();

// instruct the app to use the `bodyParser()` middleware for all routes

//app.use(bodyParser()); // 原寫法會有錯誤訊息,改以下面寫法:
//------------------------------
app.use(bodyParser.urlencoded({
  extended: true
}));

app.use(bodyParser.json())
//------------------------------

// A browser's default method is 'GET', so this
// is the route that express uses when we visit
// our site initially.
app.get('/', function(req, res){
  // The form's action is '/' and its method is 'POST',
  // so the `app.post('/', ...` route will receive the
  // result of our form
  var html = '<form action="/" method="post">' +
               '身份證號:' +
               '<input type="text" name="uid" placeholder="A123456789" />' +
               '<br>' +
               '到期日:' +
               '<input type="text" name="afterDate" placeholder="2014/01/01" />' +
               '<br>' +
               '<button type="submit">送出</button>' +
            '</form>';
               
  res.send(html);
});

// This route receives the posted form.
// As explained above, usage of 'body-parser' means
// that `req.body` will be filled in with the form elements
app.post('/', function(req, res){
  var uid = req.body.uid;
  var afterDate = req.body.afterDate;

  if (uid != '' & afterDate != '') {
    console.log(uid.toUpperCase()); // 加.toUpperCase()強制大寫
    console.log(afterDate);

    MongoClient.connect('mongodb://10.0.1.1:27017/mydb', function(err, db) {
    if(err) throw err;

    db.collection('mycollection').update({name: uid.toUpperCase()}, {$set: {"data1.after": afterDate, "data2.after": afterDate}}, function(err) {
        if (err) console.warn(err.message);
        else console.log('successfully updated');
        db.close();
      });

    });
  };  

  var html = '送出資料如下<br> <br>' + 
             '身分證號: ' + uid.toUpperCase() + '<br>' +
             '到期日: ' + afterDate + '<br>' +
             '<a href="/">回上頁</a>';
  res.send(html);
});

app.listen(80);

在terminal執行這個js程式即可。(80port在mac需要使用sudo才能跑)

畫面:

參考資料:example reading form input with express 4.0 and body parser for node js

2014/08/19

Node.js 使用 FTP 傳送檔案



先安裝 FTP 模組: npm install ftp

node.js程式如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
  var Client = require('ftp');
  var fs = require('fs');

  var c = new Client();

  c.connect({
   host: "10.0.1.1",
   user: "test",
   password: "test"
  });

  c.on('ready', function() {
    c.put('BackupLog.txt', 'Remote/BackupLog.txt', function(err) {
      if (err) throw err;
      c.end();
    });
  });

2014/08/15

使用 Node.js 執行外部壓縮程式與外部指令



4~9: 執行壓縮指令,壓縮完畢跳到 code:11
11~17: 執行 xcopy 指令

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
var exec = require('child_process').exec,
    child; 
 
child = exec('"C:\\Program Files\\7-zip\\7zG.exe" a -r -mx9 "BackupLog.7z" "BackupLog.txt"', function(error, stdout, stderr) {
    console.log('stdout: ' + stdout);
    console.log('stderr: ' + stderr);
    if (error !== null) {
        console.log('exec error: ' + error);
    }
 
    exec('xcopy "BackupLog.7z" \\\\10.0.1.1\\test /y', function(error, stdout, stderr) {
        console.log('stdout: ' + stdout);
        console.log('stderr: ' + stderr);
        if (error !== null) {
            console.log('exec error: ' + error);
        }
    });
});

2014/08/06

Node.js 取得上個月的日期字串



取年份要使用 getFullYear()才會有完整正確的數字。

如果要取當月,因為月份的算法是0~11,需改為(MyDate.getMonth()+1)。
1
2
3
4
5
6
var MyDate = new Date();
var MyDateString;

MyDateString = MyDate.getFullYear() + '/' + ('0' + MyDate.getMonth()).slice(-2);

console.log(MyDateString);

結果:

Ians-MBP:Desktop ian$ node LastMonth.js
2014/07

取前一天:

1
2
3
4
5
6
var MyDate = new Date();
var MyDateString;

MyDate.setDate(MyDate.getDate() - 1); // 取前一日,自行依備份日期調整

MyDateString = MyDate.getFullYear() + '/' + ('0' + (MyDate.getMonth()+1)).slice(-2) + '/' + ('0' + MyDate.getDate()).slice(-2);  //日期補零 2014/08/16

原有取得的日期沒有補0,因此才有加0和slice(-2)的轉換,原理如下。(原文網址:http://stackoverflow.com/questions/3605214/javascript-add-leading-zeroes-to-date)

To explain, .slice(-2) gives us the last two characters of the string.
So no matter what, we can add "0" to the day or month, and just ask for the last two since those are always the two we want.
So if the MyDate.getMonth() returns 9, it will be:
("0" + "9") // Giving us "09"
so adding .slice(-2) on that gives us the last two characters which is:
("0" + "9").slice(-2)
"09"
But if MyDate.getMonth() returns 10, it will be:
("0" + "10") // Giving us "010"
so adding .slice(-2) gives us the last two characters, or:
("0" + "10").slice(-2)
"10"

2014/08/05

網址傳送資料給 Node.js (app.get)



Node.js 需安裝 express 模組。 (sudo npm install express)

再撰寫以下程式碼,檔案自訂。

App.js

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var express = require('express');
var app = express();

app.get('/data', function(req, res) {
    console.log(req.query.name);
    console.log(req.query.country);
    res.send('Name:' + req.query.name + '<br />' +'Country:' + req.query.country);
    res.end();

});


app.listen(12345);

Terminal 執行 node app.js

使用瀏覽器,網址輸入 http://127.0.0.1:12345/data?name=Ian&country=Taipei

Terminal 會顯示網址所帶的參數:

Ians-MBP:Desktop ian$ node app.js
Ian
Taipei

網頁顯示如下:

2014/07/29

Robomongo



滿多人推薦的 MongoDB GUI 管理工具:Robomongo

在畫面操作、可跨不同平台(Mac, Linux, Windows)的特點,讓滿多人推薦的。

特色:
  • Full Power of MongoDB Shell. Robomongo embeds the same JavaScript engine (based on Mozilla SpiderMonkey), that powers MongoDB’s mongo shell. It means that you can reuse your existing skills of MongoDB Shell in Robomongo
  • Multiple Shells. Open as many shells as you need. Every tab in Robomongo is a MongoDB shell, fully isolated from each other.
  • Multiple Results. Robomongo executes your code in statement by statement way. That means that you will receive as many result as many statements you have.
  • Autocompletion. Robomongo provides you with autocompletion for all objects (and thus functions) that are known by JavaScript runtime, including autocompletion for databases, collections and even your document objects.
  • Cross-platform, open source.



這篇中文文章亦可參考:
MongoDB Tutorial(2)MongoDB 的 Query Language

2014/07/28

Sublime Text3 改預設開啟頁籤 (取消預設開啟新視窗)



若預設 Sublime Text 來開啟文字檔案,Sublime Text 都會以一個檔案開啟一個新視窗來呈現。半手動方式只能在開啟一個檔案後,後續檔案直接拖曳到 Sublime Text 視窗上。

如果有大量需求的話,可直接更改開啟設定,作法很簡單:

1. 點選上方選單 Sublime Text > Preferences > Settings - User


2. 加入 "open_files_in_new_window": false 這段文字,記得前一段設定要加「,」分隔。


3. 存檔即可。

2014/07/26

Emmet 快速筆記



句法說明:Abbreviations Syntax
詳細句法:Syntax

# id
. class

jQuery Mobile List
Short
ul[data-role="listview"]>li*3>a[]>h2{Headline $}+p>Lorem5
Produce
<ul data-role="listview">
 <li><a href="">
   <h2>Headline 1</h2>
   <p>Lorem ipsum dolor sit amet.</p>
  </a></li>
 <li><a href="">
   <h2>Headline 2</h2>
   <p>Cum, nulla, omnis! Quidem, eaque.</p>
  </a></li>
 <li><a href="">
   <h2>Headline 3</h2>
   <p>Facilis eius ratione alias asperiores.</p>
  </a></li>
</ul>

2014/07/25

Sublime Text 必裝套件



Package Control
在 Sublime Text 中,安裝其他套件。使用方式:
  1. 在 Sublime Text 按 Ctrl + `,啟用 Console 畫面。
  2. 依使用版本貼上語法
  3. 重啟 SubLime Text 。
  4. Ctrl+Shift+P,再輸入 install 即可啟用 Package Control 裡的套件安裝列表。

SublimeAllAutocomplete
自動提示、補足程式碼。使用方式:
  1. 先安裝 Package Contrl。
  2.  Ctrl+Shift+P,再輸入 install 啟用 Package Control 裡的套件安裝列表。
  3. 輸入 all 出來第一項就是 All Autocomplete。
  4. 若要移除,只要按 Ctrl+Shift+P,再輸入 remove 、點選這個套件即可。


Sublime Alignment
按 Ctrl+Alt+A可使程式碼對齊等號或是其他自訂符號。使用方式:
  1. 先安裝 Package Contrl。
  2.  Ctrl+Shift+P,再輸入 install 啟用 Package Control 裡的套件安裝列表。
  3. 輸入 alignment 
  4. 若要移除,只要按 Ctrl+Shift+P,再輸入 remove 、點選這個套件即可。
  5. 詳細使用方式可參考這篇文章


Emmet
輸入簡易程式代碼,自動轉換成一般程式碼。使用方式:
  1. 先安裝 Package Contrl。
  2.  Ctrl+Shift+P,再輸入 install 啟用 Package Control 裡的套件安裝列表。
  3. 輸入 Emmet 
  4. 若要移除,只要按 Ctrl+Shift+P,再輸入 remove 、點選這個套件即可。
  5. 使用方式請參考官網範例: http://docs.emmet.io/abbreviations/syntax/

中文參考資源:Sublime Text 手冊

2014/07/15

Ajax-Loader 測試



在做 jQuery Mobile 時,可能會碰到 mobileinit 事件。以下是模擬 A網頁前往 B網頁,可在B網頁加上載入三秒鐘的資料,藉以得知loading的狀態或圖示。

<script runat="server">
 
  protected void Page_Load(object sender, EventArgs e)
  {
    System.Threading.Thread.Sleep(3000);
  }

</script>

2014/07/12

勾選我同意後,出現「下一步」按鈕,可指往第二頁。



當點選我同意時,顯示「下一步」。按「下一步」時導到第二頁。



<!DOCTYPE html>
<html>
<head>
 <title>Agree check</title>
 
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
 
 <link rel="stylesheet" href="http://code.jquery.com/mobile/1.4.3/jquery.mobile-1.4.3.min.css" />
 <script src="http://code.jquery.com/jquery-1.11.1.min.js"></script>
 <script src="http://code.jquery.com/mobile/1.4.3/jquery.mobile-1.4.3.min.js"></script>
 
 <script type="text/javascript">
  $(document).on("change", "#checkbox-agree", function () {
      if ($(this).prop("checked")) {
          $("#NextPage").button("enable");
      } else {
          $("#NextPage").button("disable");
      }
  });
 </script>
</head>
 
<body>
 
<div data-role="page" id="Page1">
 <div data-role="fieldcontain">
     <fieldset data-role="controlgroup" style="width:150px">
      <input type="checkbox" name="checkbox-agree" id="checkbox-agree" class="custom" />
      <label for="checkbox-agree">我同意</label>
     </fieldset>
     <input type="button" id="NextPage" data-inline="true" onclick="javascript:location.href='#Page2'"  value="下一步" disabled/>
 </div>
</div>
 
<div data-role="page" id="Page2">
 This is Page2.
</div>
 
</body>
</html>

10個 jQuery Mobile 程式片段必備知識



這幾天被幾個 jQuery Mobile語法所困擾。

例如連結導到下一頁時,會將原有的css帶過去,無法讓新網頁的css自動套用。試了兩天才發現在連結中加入 rel="external" 讓瀏覽器視為外部連結即可解決。

還有連結按鈕的文字太多,預設值是截掉多餘的字,無法自動段行。同樣也是找了兩天才發現將.ui-btn-text 設為{ white-space: normal; }就正常了。(原css預設是 nowrap)

有熱心的朋友整理出10個 jQuery Mobile 程式片段必備知識,網址是: http://eisabainyo.net/weblog/2011/01/31/top-10-jquery-mobile-code-snippets-that-you-need-to-know/

為了怕網頁消失,我也稍稍備份一下內容,如下:
--
Followings are some of the most useful code snippets that I’ve used in my recent web app developed using jQuery Mobile framework.
1. Disable truncation for list items and buttons
If your list item or button has a long text, it will be truncated automatically by jQuery Mobile. To disable this truncation, add “white-space: normal;” to the CSS selector in question.
For example, to disable truncation for buttons:
.ui-btn-text {
white-space: normal;
}
To disable truncation for list descriptions:
.ui-li-desc {
white-space: normal;
}
To enable truncation, set it to “white-space: nowrap;“.
2. Display a random background image on page load
jQuery Mobile has a number of page initialization events that you can use to trigger certain methods on page load. The following CSS + Javascript can be used to display a random background image every time a page is loaded.
CSS
.my-page  { background: transparent url(../images/bg.jpg) 0 0 no-repeat; }

.my-page.bg1 { background: transparent url(../images/bg-1.jpg) 0 0 no-repeat; }

.my-page.bg2 { background: transparent url(../images/bg-2.jpg) 0 0 no-repeat; }

.my-page.bg3 { background: transparent url(../images/bg-3.jpg) 0 0 no-repeat; }
Javascript
$('.my-page').live("pagecreate", function() {
 var randombg = Math.floor(Math.random()*4); // 0 to 3
 $('.my-page').removeClass().addClass('bg' + randombg);
});
3. Disable a button action
To disable a button action (for eg: from opening a page), add the following Javascript.
$('#home-button').button("disable");
And to re-enable it:
$('#home-button').button("enable");
4. Disable loading pop-up message
I find the loading pop-up message a bit annoying because it gets triggered everytime you load a different page. To disable this: add the following line of code into your JS file.
$.mobile.pageLoading(true);
By default, it is enabled like so:
$.mobile.pageLoading();
5. Create a custom theme
jQuery Mobile framework comes with 5 themes – Theme A, Theme B, Theme C, Theme D and Theme E. But you can easily create a new theme for your web app.
The steps to create a new theme:
1. Copy CSS for any theme from jQuery Mobile CSS file and paste it into your own CSS file.
2. Give your theme a name and rename the CSS selectors appropriately. Your theme name can be any alphabet character (a to z). So for example, if you copied Theme C, and you want to call your theme Theme Z, rename.ui-btn-up-c to .ui-btn-up-z.ui-body-c to .ui-body-z and so on.
3. Change colors and styles of your custom theme
4. To apply your custom theme z to any element, just set the data-theme attribute to z. For example:
<div data-role="page" data-theme="z">
6. Use a custom font
There are a few font-replacement methods available such as cufon, sIFR, FLIR, @font-face and Google Fonts API. When building a web app using jQuery Mobile, I found that @font-face method is the easiest method to work with and the performance is quite satisfactory. If you are interested in @font-face, here is a helpful tutorial with a demo on how to work with @font-face method.
7. Create an image-only button with no text
Sometimes, you may not want to have any text for your button but still use the rest of the features that comes with a button element. This is usually the case with a home button or an info button. To hide any text associated with the button, set data-iconpos attribute to “notext”. For example:
<a href="../index.html" data-icon="grid" 
class="ui-btn-right" data-iconpos="notext">Home</a>
8. Open a link without using AJAX with page transitions
To open a link without using AJAX with page transitions (ie: reloading the full page the old-school way), set rel attribute to “external”.
<a href="../index.html" data-icon="grid" 
class="ui-btn-right" rel="external">Home</a>
9. Remove an arrow from a list item
By default, jQuery Mobile framework adds an arrow next to every list item. To disable this, set data-icon attribute to “false” on the list item that you’d like the arrow to be removed.
<li data-icon="false"><a href="contact.html">Contact Us</a></li>
10. Set background color of a page
This may sound simple but it took me a few minutes to figure out how to apply a background color to a page without having it overwritten by jQuery Mobile CSS. Normally, you’d set a background color to body element but if you are using jQuery Mobile framework, you need to set it to ui-page class.
.ui-page { 
background: #eee;
}
--
上述第1點補充Code。jquery.mobile-1.4.3.min.css版,使用ol+li的列表式語法,按鈕文字過長需自動截斷,要在style調整成:

<style>
.ui-listview>.ui-li-static,.ui-listview>.ui-li-divider,.ui-listview>li>a.ui-btn{
white-space:normal !important;
}
</style>


上述第3點補充完整Code:
HTML:
1
2
3
4
5
6
7
<div data-role="fieldcontain">
    <fieldset data-role="controlgroup" style="width:294px">
        <input type="checkbox" name="checkbox-1" id="checkbox-1" class="chk" />
        <label for="checkbox-1">I agree</label>
    </fieldset>
</div>
<input type="submit" id="submit" data-inline="true" data-theme="a" data-icon="check" value="&nbsp;Submit&nbsp;" disabled/>
JavaScript:
1
2
3
4
5
6
7
$(document).on("change", "#checkbox-1", function () {
    if ($(this).prop("checked")) {
        $("#submit").button("enable");
    } else {
        $("#submit").button("disable");
    }
});