iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 7
4
Modern Web

Half-Stack Developer 養成計畫系列 第 7

我不是程式語言:jQuery

我不是程式語言:jQuery

還記得我們在上一章裡面寫了一大堆的 JavaScript 嗎?其實只要掌握了幾個步驟,你就會發現十分輕鬆寫意。

  1. 用 JavaScript 抓到你想要的元素
  2. 開始對他做你想做的事...嘿嘿嘿

舉我們上一次的例子來說,你要幫一個按鈕加上點擊時候的事件:

var btn = document.querySelector('#btn');
btn.addEventListener('click', function() {
  alert('click!');
});

如果你寫多了你就會知道,document.querySelector或是document.getElementById這些函式名稱你不用特別去記就會背起來了,因為實在是用太多太多次了。

身為一個懶惰的工程師,碰到這種情形的時候,你應該知道怎麼做:「既然一直都會用到,乾脆就抽出來寫一個 function 吧!」

function getElement(elem) {
  return document.querySelector(elem);
}
var btn = getElement('#btn');
btn.addEventListener('click', function() {
  alert('click!');
});

從此以後你就可以忘記那一長串的程式碼,只要用getElement就可以達成所有的事情,很棒吧!

但儘管程式碼看起來是更好維護了,可是你還是得面對剩下的addEventListener那一段,怎麼辦呢?

我知道我知道!就跟剛剛一樣獨立出來一個 function 就好啦!

function getElement(elem) {
  return document.querySelector(elem);
}
function addListener(elem, event, func) {
  elem.addEventListener(event, func);
}

var btn = getElement('#btn');
addListener(btn, 'click', function() {
  alert('click!');
});

有一種畫虎不成反類犬的感覺,完全沒有幫助。整個程式碼的架構還是看起來差不多,有沒有其他更好的方法呢?或是說,能不能先退而求其次,只針對click這個事件怎麼樣?反正就這一個事件最常用到了。

再者,我們剛剛寫的addListener要接收三個參數,現在如果少了 click 就剩兩個,有沒有可能把btn這個參數也拿掉,變成只有一個呢?

function onClick (func) {
  btn.addEventListener('click', func);
}
var btn = getElement('#btn');
onClick(function() {
  alert('click!');
})

目的是達到了啦,程式碼看起來也比較清爽一點,可是缺點就是btnonClick裡面是寫死的,你只要換一個元素就完全行不通了,有沒有其他方法呢?

其實我在很多思考怎麼簡化的時候,都不是先想過程,而是先想「結果」。你可以想想你最後一步想要寫出來的程式碼長什麼樣子,你再慢慢回推、去想辦法實現它。我在腦海中,想到最簡化的可以變成這樣:

getElement('#btn').onClick(function () {
  alert('click!');
})

這樣子使用起來的感覺還不錯吧!而且程式碼又乾淨簡單,想要換一個新的元素也很容易,簡直就是完美。一旦你成功想到最後一步以後,剩下的就是想辦法去實現它。

下面的程式碼對初學者可能會有些困難,如果你發現你看不懂的話,可以再去練一下 JavaScript 基礎。

function getElement(selector) {
  var element = document.querySelector(selector);
  return {
    onClick: function(func) {
      element.addEventListener('click', func);
    }
  }
}

這個函式會回傳的是一個 Object,然後onClick會對應到一個 function。所以如果你想加上其他事件,都可以直接加在上面。當我們改寫成這樣以後,就可以用我們剛剛講的方式來呼叫了!

可是getElement這個名稱有一點長,而且如果我們會一直用到,打那麼多字實在是很累。我們把它簡化一下好了

function get(selector) {
  var element = document.querySelector(selector);
  return {
    click: function(func) {
      element.addEventListener('click', func);
    }
  }
}
get('#btn').click(function () {
  alert('click!');
})

好了,當你跟著脈絡這樣子讀下來,你可能會有一個疑問:「今天不是要講 jQuery 嗎?我鍵盤都打一半了你給我看這個?」。有志者事竟成,既然你都願意花時間看到這裡了,我就不囉唆立刻附上 jQuery 的範例給你看:

$('#btn').click(function () {
  alert('click!');
})

「別騙我啊,你這不就是把你的範例的get改成$嗎?唬爛也不是這樣的吧!」

沒錯,這就是 jQuery,而且你已經掌握到 jQuery 是什麼以及 jQuery 的精髓了。為什麼會有 jQuery?就是因為有工程師一直不斷寫一堆重複的程式碼(跟我們剛剛一樣)覺得非常厭煩,所以下定決心要寫出一個 library(就是一堆 function 的集合體)徹底解決問題。jQuery 不是一個程式語言,只是一個 library 而已。你就算沒有 jQuery 你也可以寫程式,但就是比較麻煩就是了。

有沒有發現跟我們剛剛做的事情很像?所以呢,我們剛寫出來的get跟 jQuery 相同的地方就在,都是想要解決一樣的問題。不同的地方則是在於,jQuery 它包含的層面更廣、實做出來的 function 多更多。我們的get只有click這一個 function,jQuery可是有千千萬萬個不同的 function 呢。

想要用 jQuery 的時候,你只要在 head 裡面引入 jQuery 的檔案就好了

<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<script>
  $(document).ready(function() {
    //....
  })
</script>

那這個$是什麼東西呢?阿這個超級簡單啦,你看下面這個範例就知道了:

function $(selector) {
  var element = document.querySelector(selector);
  return {
    click: function(func) {
      element.addEventListener('click', func);
    }
  }
}
$('#btn').click(function () {
  alert('click!');
})

$這個字可以拿來當作變數或是函式的名稱,因為如果打全名jQuery太長了,所以懶惰的工程師們就想說:那我打一個 $ 不就簡單多了?所以就變成用$來代替jQuery了。你開心的話你要用其他符號也可以。

如果你有把這篇從頭開始跟著做,那你看到現在一定知道jQuery到底在做什麼,簡單來說就是幫你把複雜的事情變簡單,就這樣而已。而你在日常開發之中其實會用到的 function 大概就那幾個,我示範給你看:

var count = 3;
$(document).ready(function() {
  $('#btn').click(function() {
    $('<div class="post">' +
        '<h2>文章' + count + '</h2>' +
        '<p>這是我的第' + count + '篇文章</p>' +
      '</div>').appendTo('.posts').hide().fadeIn(2000);
    count++;
  })
})

效果會是這樣:
Imgur

jQuery 的優點就是簡單好懂然後寫起來很快,而且這樣一直串連,程式碼看起來也滿清爽的,以上面那個例子來說,就是「把(那一長串 html)加入到 .posts 這個元素所在的地方然後隱藏然後兩秒內淡入」,應該很好理解吧。所以很多人寫 JavaScript 的起手式就是先引入 jQuery,因為實在是太好用了。

如果你想學更多與 jQuery 有關的東西,可以參考jQuery Tutorial。不過這也是我隨便 Google 找來的。之前有講過了,這種入門的教學其實都可以透過 Google 很多就找到還不錯的資源。因此之後的內容,就要麻煩大家自己去找更多教學了,我只會推薦我自己實際看過,真的覺得不錯的。

突然想到有一個系列的書籍我覺得很適合初學者,叫做Head First,台灣翻叫深入淺出,是歐萊禮出的一系列的書籍,其中有一本就是深入淺出 jQuery (Head First jQuery),這一個系列的書都很適合初學者觀看,風格比較生動活潑一點,也有很多範例讓你做練習。

最後,我們以一個可以新增/刪除文章的範例來做總結,只要你可以看得懂下面的程式碼,你就可以繼續往後學習了

<html>
<head>
  <link rel="stylesheet" type="text/css" href="cool.css">
  <script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
  <script src="my.js"></script>
</head>
<body>
  <h1 id="title">This is my blog</h1>
  <div>
    文章標題:<input type="text" name="title" />
  </div>
  <button id="btn">新增</button>
  <div class="posts">

  </div>
  
</body>
</html>
var count = 1;
$(document).ready(function() {

  $(document).on('click', '.delete' ,function() {
    $(this).parent().remove();
  })
  $('#btn').click(function() {
    var title = $('input[name=title]').val();
    if(title == '') {
      alert('標題不能空白');
      return;
    }
    $('<div class="post">' +
        '<h2>' + title + '</h2>' +
        '<p>這是我的第' + count + '篇文章</p>' +
        '<button class="delete">刪除</button>' +
      '</div>').appendTo('.posts').hide().fadeIn(2000);
    count++;
  })
})

這邊你可能會有一個小疑問,會什麼要用$(document).on('click', '.delete' ,function(){}而不是$('.delete').click(..)

這是因為我們的.delete元素是動態新增的,如果你用後面那種寫法的話,因為addEventListener的時候還沒有「你之後才會新增」的那個元素,所以當你新增完畢以後,點下去會沒有反應。因此要用前面那種on的方法,才能夠順利幫之後才會新增的元素加上點擊事件。

詳情可參考:[筆記] 使用 jQuery 改變 DOM 元素後 Click Event 失效問題的解決方法


上一篇
我跟 Java 真的沒關係:JavaScript
下一篇
一直改來改去,你改夠了沒:SCSS
系列文
Half-Stack Developer 養成計畫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

1
牛哥
iT邦好手 1 級 ‧ 2017-01-09 00:21:27

以前我剛懂HTML時,就把它當成程式碼來研究了~
後來才知道它(HTML)真的不算是程式語言?!

看了這篇文的題目?!
http://ithelp.ithome.com.tw/upload/images/20170109/20022541Wtnylu19ds.jpg

牛哥 iT邦好手 1 級 ‧ 2017-01-09 00:22:19 檢舉

開開玩笑!
實作內容很棒的~
/images/emoticon/emoticon12.gif

huli iT邦新手 3 級 ‧ 2017-01-09 00:26:08 檢舉

HTML 跟 jQuery 都不算是程式語言
在前端的世界裡面,只有 javascript 是

我要留言

立即登入留言