ch3 Bringing pages to life with jQuery

3.1 Manipulating element properties and attributes
<img id="myImage" src="image.gif" alt="An image" class="someClass" title="This is an image"/>

img是tag name
其他id、src、alt、class、title是attributes
而瀏覽器會將這些轉變成DOM中的element
而且會建立一個NodeList object並指派一組properties給這個element
這個element的attributes跟properties是可以動態變化的
而且通常也會保持一致
不過有時候也會不一樣
像是當給定src的attribute為image.gif
而property則會給完整的路徑 如http://localhost/image.gif

attributes跟properties的名字大部分也是一樣的
少部份如attributes中的class 在properties中則是稱為className

3.1.1 Manipulating element properties
each()

在each()中 會依序操作selectors所取得的elements,會由零開始(zero-based)
在裡面可以使用this這個property來表示這個element並操作

$('img').each(function(n){
  this.alt='This is image['+n+'] with an id of '+this.id;
});

依序修改每個<img>的alt值

而如果只是要取得其中一個的值 可以使用array的index方式取得(因為selectors所取得的elements也可以當作array來使用)

var altValue = $('#myImage')[0].alt;
3.1.2 Fetching attribute values
attr(name)

獲得element的屬性值

<img id="myImage" src="image.gif" alt="An image" class="someClass" title="This is an image" custom="some value"/>

這裡以這個img作為例子 可以看到他的屬性有一項為custom="some value"

$("#myImage").attr("custom")

可以使用attr()來取得屬性的值(這裡會取得"some value")
不過要注意的是 如果使用不是標準的屬性名稱(也就是這裡的custom) 可能會導致網頁無法正確解析或是無法取得該值

3.1.3 Setting attribute values
attr(name,value)

設定element的屬性值

$('*').attr('title',function(index) {
  return 'I am element ' + index + ' and my name is ' +
         (this.id ? this.id : 'unset');
});

除了可以在第二個參數直接填入要放的值
也可以填入一個function 再將這個function的返回值填入

attr(attributes)

attr()也可以一次設定多個屬性值

$('input').attr(
  { value: 'v', title: 'Please enter a value' }
);

裡面放的是一個object
這樣就可以一次設定element的value值跟title值了
這邊要注意的是IE沒辦法改變<input>的name值
所以要在IE中改變的話 要直接建立一個新的<input> 並取代原本的

3.1.4 Removing attributes
removeAttr(name)

移除element的屬性
使用的方式跟attr()一樣 不過這邊就是移除這個屬性
要注意的是 這邊移除的是attribute 而property仍然會存在的(但是值可能會變)
例如將readonly attribute移除
那這個element的property可能會由true變為false 但是他仍然會存在

3.1.5 Fun with attributes

這小節舉了兩個運用attr()的例子

$("a[href^=http://]").attr("target","_blank");

將頁面中所有的連結加上開啟在新頁面的功能

$("form").submit(function() {
  $(":submit",this).attr("disabled", "disabled");
});

對於頁面上所有表單的送出鍵 當他們被按下第一次之後 便變成disabled
(也就是只能按一次送出)

3.2 Changing element styling

要改變一個element的外觀(style)有兩個方式
增加或拿掉css class
或是直接更改這個element的style

3.2.1 Adding and removing class names
addClass(names)

很容易可以瞭解這個method的用法
就是對取得的elements加上一個class
如果一次要加上多個 就以空格區隔開各class

removeClass(names)

拿掉這個class
如果一次要拿掉多個 就以空格區隔開各class

還有一個有用的method就是可以切換class

toggleClass(names)

如果已經有這個class了 就拿掉這個class
如果尚未有 則是加上這個class
(在一組取得的elements裡 有可能有些element有這個class 有些沒有)

function swap(){
  $('tr').toggleClass('striped');
}

這樣可以對table中單數雙數的tr給予不同的class 來達到明顯各row區隔的效果

3.2.2 Getting and setting styles
css(name,value)

只改變一種(或是某幾種)style需要用到css()這個method
例如將所有<div>裡面的字都變成黑色

$('div').css('color','#000000');

第二個參數除了可以擺string、number 也可以擺一個function
例如將所有class=expandable的<div>的寬度都再加20px

$("div.expandable").css("width",function(){
   return $(this).width() + 20 + "px";
});

就如同attr()一樣 css()也可以一次設定多個style

$("p").css({color:"#ff0011","background-color":"blue"});

name如果有 – 的話要加引號(ex: background-color)

如果要取得element的style值則是如下
取得class=title的<div>的寬度

$("div.title").css("width");

這個返回值永遠是string型態
所以如果是要其他如number型態的就還要再轉換

jQuery也提供了兩個方便的method

width(value)
height(value)

顧名思義 這就是設定element的寬度跟高度

$("div.title").width(500);
$("div.title").css("width","500px");

這兩行的意義是一樣的

而沒加參數的則是取得寬度及高度

$("div.title").width();
$("div.title").height();
3.2.3 More useful style-related commands
hasClass(name)

另外還有一個method是可以取得elements是否有這個class
如果有的話會返回true 反之則是false

$("p:first").hasClass("surpriseMe");

其實就等同於ch2提到的is()的一個用法

$("p:first").is(".surpriseMe");

不過就字面上來講 hasClass()可以較清楚的知道這個method的意義

如果要取得elements的所有class 在書中有提供了一個寫法

$.fn.getClassNames = function() {
  if (name = this.attr("className")) {
  	return name.split(" ");
  }
  else {
    return [];
  }
};

新增一個名叫getClassNames的method
他會返回一個包含所有class的array
如果沒有class的話 則是一個空的array

3.3 Setting element content
3.3.1 Replacing HTML or text content
html(text)

取得或是改變elements中的內容
如果有參數的話就是改變內容
沒有參數的話就是取得內容
這個用法跟innerHTML是一樣的

text(content)

另一個可以獲得內容的method是text()
同樣的 有參數是改變內容 沒有的話則是取得內容
而這個取得的內容會將tag都去掉
下面是範例

<ul id="theList">
  <li>One</li>
  <li>Two</li>
  <li>Three</li>
  <li>Four</li>
</ul>
var text = $('#theList').text();
//這會取得將tag都去掉的字串:OneTwoThreeFour

如果是要改變內容
會將新內容中的<跟>轉換成&lt;跟&gt;
這樣就會將內容都顯示出來

3.3.2 Moving and copying elements
append(content)

將字串、element或是object加到elements的後面(tag裡內容的後面 不是tag的後面)
下面是個簡單的例子 將一段html碼加到每個<p>內容的後面

$('p').append('<b>some text<b>');

而將其他的element加到elements的後面則是下面這樣

$("p.appendToMe").append($("a.appendMe"));

對於append()中的elements的處理有一點要注意的是
如果目標elements( 在這裡是$("p.appendToMe") )只有一個element
則會把append()中取得的elements整個搬過去(也就是move過去)
而如果有多個elements的話 則是每個目標element都複製一個
而且原本的elements還是會留著

appendTo(target)

還有另一個跟append()相反用法的method
這是將elements加到目標elements的後面
可以對照append()來看

$("a.appendMe").appendTo($("p.appendToMe"));

同樣的 如果目標只有一個 就會move過去
目標有很多個的話 就會各複製一個 並且原本的也會留著

有將內容加到後面 當然也有加到前面的

prepend()

這個則是加到內容的前面 其餘用法跟append()一樣

prependTo()

這個則是加到內容的前面 其餘用法跟appendTo()一樣

前面4個method說的是在目標tag中的內容
而要放置在tag之外前面或後面也有另外的method可以使用

before()

將內容加到目標elements的tag前面

insertBefore()

就跟append()與appendTo()的關係一樣
這是跟before()相反

after()

將內容加到目標elements的tag後面

insertAfter()

就跟append()與appendTo()的關係一樣
這是跟after()相反

3.3.3 Wrapping elements
wrap(wrapper)

在elements外再包一層tag(前後都加上tag)

$("a.surprise").wrap("<div class='hello'></div>");

將class=surprise的<a>的外面包一層<div>

<a class="surprise" href="#">here</a>
會變成
<div class='hello'><a class="surprise" href="#">here</a></div>
wrapAll(wrapper)

wrap()是將elements中每個element都包一層
而wrapAll()則是對整個elements包一層

wrapInner(wrapper)

將elements中的內容包一層

3.3.4 Removing elements
remove()

將elements從DOM中移除
但是之後還是可以拿來使用(例如利用appendTo(),prependTo()來繼續使用這組elements)

empty()

將elements中的內容清除

3.3.5 Cloning elements
clone(copyHandlers)

複製這組elements來使用
參數copyHandlers是個boolean
如果這個參數為true的話 那就會連操作事件也一起複製
如果為false或是省略 則是只有複製elements

3.4 Dealing with form element values
val(value)

當value省略時 是取得form中elements的值
而有值是設定這個element的值

val(values)

還有另一個用法是
將所有符合的elements選取(也就是設定為checked或selected)

$('input,select').val(['one','two','three']);

搜尋頁面上所有的<input> (即type=checkbox或type=radio)跟<select>
如果他們的值為one、two或是three
則將他們選取