只在此山中,雲深不知處


聽首歌



© 2018 by Shawn Huang
Last Updated: 2018.5.27

JQuery

JQuery是JavaScript的資料庫,可以讓我們更容易地使用JavaScript。在使用時先下載JQuery檔案,它本身就是一個JavaScript檔案。將下載後的檔案儲存於跟html檔案相同的資料夾內,然後再head標籤內加上以下指令。
<script src="jquery-3.3.1.js"></script>
這樣便可以了。如果不想下載檔案,在head標籤內加上以下兩行中任一行也可以。第一行google host的CDN(Content Delivery Network),第二行是microsoft。
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://ajax.aspnetcdn.com/ajax/jQuery/jquery-3.3.1.min.js"></script>
有了寫好了的jQuery程式碼(e.g. jq1.js),記得在head內加上
<script src="jq1.js"></script>
跟JavaScript一樣,將內容以此方式納入。

JQuery內的函數寫法如下,使用ready()函數:
$(document).ready(function(){
    //code...
});

原則上就是把函數放在$(document).read();read後的小括號內。這樣可以讓函數在document載入完成之後才開始執行。 >>
$(document).ready(function() {
    console.log("Hello, World!");
});
在JavaScript檔案內加上上述函數,按F12看執行結果。
關鍵的$號原則上就是jQuery的簡寫,也就是也可以用jQuery替換掉$號,用$號當然容易些,但在某些$號會與其他內容混淆時可以使用jQuery代替。 >>
jQuery(document).ready(function() {
    console.log("Hello, Again...!");
});
還可以使用更簡潔的寫法,直接省略掉(document).ready。 >>
$(function() {
    console.log("Hello, the third time...!");
});

Selector & Traversing


JQuery可以讓我們快速容易的選擇網頁中的元件或是根據相對關係來選擇元件(類似Javascript DOM),關鍵符號為$()。在小括號內放置CSS selector即可。 >>

Exercise: 設立一html檔案(jq.html),其中包含數個元件(p、button、form、etc),將其在browser開啟,然後在console內練習輸入以下指令:


跟JavaScript DOM類似,JQuery也可以讓我們根據element的相對關係來取得其他element。

Events

由使用者觸發的事件(Event)有以下幾種:
  1. blur
  2. focus
  3. focusin
  4. focusout
  5. load
  6. resize
  7. scroll
  8. unload
  9. click
  10. dblclick
  11. mousedown
  12. mouseup
  13. mousemove
  14. mouseover
  15. mouseout
  16. mouseenter
  17. mouseleave
  18. hover(mouseenter+mouseleave)
  19. change
  20. select
  21. submit
  22. keydown
  23. keypress
  24. keyup
  25. error

選擇了元件之後,直接在其後加上event,便可呼叫函數來執行,語法為$(selector).event(function);,原則上events與JavaScript Events相同,只要去掉前面的on即可。 >>
<p id="jq1_p1" style="background:pink;">這是一個P,按F12然後點一下看結果</p>
設計一個p,再加上函數如下。
$(document).ready(function() {
    $("#jq1_p1").click(function(){
	console.log("點了一下p");
    });
});

這是一個P,按F12然後點一下看結果

JQuery HTML

選擇了element之後,顯然接下來要改變其內容,有以下方法可選擇jq.html(指令底色與底色同色:console輸入、白底:for jq.html):

text(): 設定或傳回element的文字內容,參數可以為callback function。 在console輸入

$("#xxx").text()
來查詢。
$("#xxx").text("NEW TEXT.");

html(): 設定或傳回element的內容,參數可以為callback function。 >>

$("#xxx").html()
console.log($("#xxx").html());
$("#xxx").html("Some <strong><em>HTML</em></strong> text.");
<p id="jq2_p1" class = "p12_7">滑鼠點這裡觸發</p>
$(document).ready(function() {
    $("#jq2_p1").click(function(){
	console.log($("#jq2_p1").text());
	$("#jq2_p1").text("callback()第一個參數是目前element在所選取element的index,第二個參數是原內容");
    });
    $("#jq2_p1").mouseover(function(){
	$("#jq2_p1").text(function(i, ori){
	    $("#jq2_p1").text("index: " + i + " " + ori + "先按F12,然後click or double click");
	});
    });
    $("#jq2_p1").dblclick(function(){
	console.log($("#jq2_p1").html());
	$("#jq2_p1").html(function(i, ori){
            $("#jq2_p1").html(ori + "<strong>html()可設定html內容</strong>");
	});
    });
});

滑鼠點這裡觸發

val(): 設定或傳回form裡面的值,參數可以為callback function。 >>

$(":submit").val()
$(":submit").val("Submit");
new check again.
<input type="button" value="Button1" class="jq2_b2"></input>
<input type="button" value="Button2" class="jq2_b2"></input>
<button class="jq2_b2">Button3</button>	
$(document).ready(function() {
    $(".jq2_b2").click(function(){
	$(".jq2_b2").val(function(i, ori){
            if(i==0){
		return "clicked on 1";
	    }
	    if(i==1){
		return "clicked on 2";
	    }
			
	});
    });
});

data(): element's data

$("p:first")
    .data("alias", "The p number 1")
    .next("p")
    .data("alias", "The p number 2");
console.log("Meta-data: "+$("p:first").data("alias"));
console.log("Meta-data: "+$("p:eq(1)").data("alias"));
$("p:first").data();
$("p").eq(1).data()
使用json語法:
$("p.ooxx").data({
    "alias":"ooxx",
    "content":{
	"sequence":"2nd place",
	"textColor":"black",
	"backgroundColor":"white"
    }
});
console.log("Alias: "+$("p.ooxx").data("alias"));
console.log("Text color: "+$("p.ooxx").data("content").textColor);
$("p.ooxx").data()
$("p.ooxx").data("alias")
$("p.ooxx").data("content")
$("p.ooxx").data("content").backgroundColor

attr(): 設定或傳回屬性值,參數可以為callback function。 >>

取得p:eq(4)的id屬性值
console.log($("p:eq(4)").attr("id"));
設定p:eq(4)的id屬性值
$("#xxx").attr("id", "ooo");
設定多個屬性值
$("p:eq(2)").attr({
    "id":"ooo",
    "title":"A Title"
});
更多例子:
<a href="http://www.yahoo.com" id="ya">Yahoo</a>
<button id="jq2_b3">Redirect to Google</button>	
$(document).ready(function() {
    $("#jq2_b3").click(function(){
	var goo = $("#ya");
	goo.text("Google");
	goo.attr("href", "http://www.google.com");
    });
});

Yahoo

append(): 在element內的內容最後插入內容,可加入多個,使用逗點分開。

$("p:empty").append("Added by JQuery.");
$("<p>", {
    "text":"A paragraph by appendTo()!",
    "css":{"background":"yellow"}
}).appendTo("body");
<ol id="jq2_ol4">
    <li>CSS</li>
    <li>JavaScript</li>
</ol>
<button id="jq2_b4">Appending</button>	
$(document).ready(function() {
    $("#jq2_b4").click(function(){
	var ol4first = $("#jq2_ol4>li:first");
	ol4first.append("+JavaScript");
	var ol4last = $("#jq2_ol4>li:last");
	ol4last.text("JQuery");
	var ol4 = $("#jq2_ol4");
	ol4.append("<li>Node.js</li>");
	ol4.prepend("<li>HTML5</li>");
    });
});
  1. CSS
  2. JavaScript

prepend(): 在element內的內容一開始插入內容,可加入多個,使用逗點分開。

var par = $("<p>", {"text":"A new paragraph","css":{"background":"blue"}});
$("body").prepend(par);
$("<p>", {
    "text":"A paragraph by prependTo()!",
    "css":{"background":"yellow"}
}).prependTo("body");

after(): 在element後面插入內容,可加入多個,使用逗點分開。

$("p.ooxx").after("<p>A new paragraph.</p>");
$("<p>", {"text":"A new paragraph."}).insertAfter("p.ooxx");

before(): 在element前面插入內容,可加入多個,使用逗點分開。 >>

$(document).ready(function() {
    $("#jq2_b5").click(function(){
	var ol4first = $("#jq2_ol4>li:first");
	ol4first.before("<li>Python</li>");
	var ol4last = $("#jq2_ol4>li:last");
	ol4last.after("<li>Java</li>");
    });
});
$("<p>", {
    "text":"A paragraph inserted by InsertBefore()!",
    "css":{"background":"yellow"}
}).insertBefore("#xxx");

remove(): 移除element(及其child elements),可使用css做有條件移除。

$("p").remove(".ooxx");

detach(): keeps jQuery data for the element intact, which makes it ideal for situations in which an element will be reattached to the DOM at some point.。

$("p:nth-child(2)").data("dataContent","This is some data......");
var p = $("p:nth-child(2)").detach();
console.log("Data stored: "+p.data("dataContent"));

empty(): 移除element之child elements。 >>

$(document).ready(function() {
    $("#jq2_b6").click(function(){
	$("#jq2_ol4>li").remove("#jq2_ol4>li:odd");
    });
    $("#jq2_b7").click(function(){
	$("#jq2_ol4").empty();
    });
});

addClass(): 增加element的classes。

$("#xxx").addClass('newClass');

removeClass(): 移除element的classes。

$("#xxx").removeClass('newClass');

toggleClass(): 開關element的增加與移除classes(若有兩個class交替使用可使用$("selector").toggleClass( "class1 class2");)。

<p id="jq2_p8">Inside p(id=jq2_p8)</p>
<button id="jq2_b8a">addClass Button(id=jq2_b8a)</button>
<button id="jq2_b8r">removeClass Button(id=jq2_b8r)</button>
<button id="jq2_b8t">toggleClass Button(id=jq2_b8t)</button>
p.p12_7{
    background:blue;
    border:1px solid red;
    color: white;
}
$(document).ready(function() {
    $("#jq2_b8a").click(function(){
	$("#jq2_p8").addClass("p12_7");
    });
    $("#jq2_b8r").click(function(){
	$("#jq2_p8").removeClass("p12_7");
    });
    $("#jq2_b8t").click(function(){
	$("#jq2_p8").toggleClass("p12_7");
    });
});

Inside p(id=jq2_p8)


<ul>
    <li>a</li>
    <li>b</li>
    <li>c</li>
    <li>d</li>
    <li>e</li>
</ul>
<style>
    li.liClass{
        background: orange;
    }
</style>
$(document).ready(function(){
    /*
    $("li").click(function(event){
	event.preventDefault();
	$(this).toggleClass("liClass");
    });
    */
    $("li").on("mouseenter mouseleave", function(event){
	$(this).toggleClass("liClass");
    });
});

hasClass(): return boolean

$("#xxx").hasClass('newClass')
let hc = $("#xxx").hasClass('newClass')? "Yes":'No';
console.log(hc);

css(): 設定或傳回css屬性。

<button id="jq2_b9">css Button(id=jq2_b9)</button>
$(document).ready(function() {
    $("#jq2_b9").click(function(){
        console.log($("#jq2_p8").css("background"));
	$("#jq2_p8").css({"background":"green", "border":"1px solid red"});
    });
});
$(".ooxx").css({"color":"red","background-color":"yellow"});
在console中輸入
$(".ooxx").css("background-color")
來查詢background-color。

width(): 設定或傳回element的width。

$("form").width()

height(): 設定或傳回element的height。

$("form").height()
console.log("Form height: "+$("form").height()+"px");
$("p#xxx").height(100).css("background-color","gold");

innerWidth(): 設定或傳回element的innerWidth(指border內邊界)。
innerHeight(): 設定或傳回element的innerHeight(指border內邊界)。
outerWidth(): 設定或傳回element的outerWidth(指margin外邊界)。
outerHeight(): 設定或傳回element的outerHeight(指margin外邊界)。

$(document).ready(function() {
    $("#jq2_b10g").click(function(){
	$("#jq2_p8").css({"background":"green", "border":"5px solid red", "padding":"5px", "margin":"5px"});
	var dim = $("#jq2_p8").width() + "x" + $("#jq2_p8").height() + " " +$("#jq2_p8").innerWidth() + "x" + 
                  $("#jq2_p8").innerHeight() + " " + $("#jq2_p8").outerWidth() + "x" + $("#jq2_p8").outerHeight();
	console.log(dim);
    });
    $("#jq2_b10s").click(function(){
	$("#jq2_p8").width(500).height(100);
    });
});

wrap():

$("span").wrap("<strong />");
$("span").wrap("<strong><em></em></strong>");
$("span").wrap(function(){
	return $(this).is(".ooxx") ? "<strong>" : "<em>";
});

unwrap(): removes the parent elements (but leaves the text nodes intact)

$("span").unwrap();

wrapAll(): If an entire set of elements needs to be wrapped in a new tag

var div = $("<div>", {"css":{"background-color":"gold"}});
$("p").wrapAll(div);

wrapInner(): to wrap the content of an element but not the tag itself.

$("p").wrapInner("<em />");

map() & each(): 分別對每一個元件施展函數(current element index, current DOM element),.map()傳回新物件,.each()傳回被改變的原始物件。所以.each() is chainable, while .map() is not.

$(document).ready(function() {
    $("p,.ooxx").map(function(index, ele){
	$(this).append(" "+ele.tagName+" #"+index);
    });
});
$(document).ready(function() {
    $("p,.ooxx")
    .each(function(index, ele){
	$(this).append(" "+ele.tagName+" #"+index)
    })
    .find("span.ooxx")
    .css({
	"color":"red",
	"background":"gold"
    });
});

JQuery Effects

JQuery提供數個效果供我們使用,列舉如下:

hide(speed[, callback()]), show(speed[, callback()]), toggle(speed[, callback()]): 隱藏與顯示element。 >>

$(document).ready(function() {
    $(".bt1").click(function(){
	$("#xxx").css({
	    "background":"yellow",
	    "border":"1px solid black"
  	})
	.hide(2000,function(){
	    console.log("Animation complete!");
	});
    });
});
也可以不要$(".bt1").click(function(){}),如此每次load即執行。
<p id="jq3_p1a" class = "p12_7">滑鼠點這裡</p>
<p id="jq3_p1b" class = "p12_7">也點這裡試試</p>
<button id="jq3_b1">Show</button>
<p id="jq3_p1c" class = "p12_7">Click the toggle button</p>
<button id="jq3_b2">Toggle</button>	
$(document).ready(function() {
    $("#jq3_p1a").click(function(){
	$("#jq3_p1a").hide();
    });
    $("#jq3_p1b").click(function(){
	$("#jq3_p1b").hide(2000);
	console.log("hidden");
    });
    $("#jq3_b1").click(function(){
	$("#jq3_p1a").show();
	$("#jq3_p1b").show(2000, function(){
	    $("#jq3_p1b").append(" Coming back...");
	});
    });
    $("#jq3_b2").click(function(){
	$("#jq3_p1c").toggle(2000, function(){
	    $("#jq3_p1c").append(" Appear again...");
	});
    });
});

滑鼠點這裡

也點這裡試試

Click the toggle button


不使用callback函數也能達到類似效果,不過執行順序不同,callback在show或hide完成後執行。

fadeIn(speed[, callback()]), fadeOut(speed[, callback()]), fadeToggle(speed[, callback()]), fadeTo(speed, opacity[, callback()]): 漸顯與淡出。 >>

$(document).ready(function() {
    $("form")
	.fadeOut(1000, function(){
	console.log("Faded out!");
    })
    .fadeIn(1000, function(){
	console.log("Faded in!");
    });
});
$(document).ready(function() {
    $("form")
	.fadeTo(1000, 0.5, function(){
	console.log("Faded to 50%!");
    });
});
<div class="container">
	<div id = "jq3_d2a" style="width:50px; height:50px; background:green; color:white; text-align:center; line-height:40px">a</div>
	<div id = "jq3_d2b" style="width:50px; height:50px; background:orange;color:white; text-align:center; line-height:40px"">b</div>
	<div id = "jq3_d2c" style="width:50px; height:50px; background:purple;color:white; text-align:center; line-height:40px"">c</div>
	<div id = "jq3_d2d" style="width:50px; height:50px; background:red;color:white; text-align:center; line-height:40px"">T</div>
	<div id = "jq3_d2e" style="width:50px; height:50px; background:blue;color:white; text-align:center; line-height:40px"">O</div>
</div>
<input type="button" value="FadeIn" id="jq3_b2a"></input>
<button id="jq3_b2b">fadeToggle</button>
<button id="jq3_b2c">fadeTo</button>
$(document).ready(function() {
    // fadeIn
    $("#jq3_b2a").click(function(){ 
	console.log("Press......");
	$("#jq3_d2a").fadeIn();
	$("#jq3_d2b").fadeIn(2000);
	$("#jq3_d2c").fadeIn(2000, function(){
	    $("#jq3_d2c").text("X");
	});
    });
    // fadeOut
    $("#jq3_d2a").mouseover(function(){
	$("#jq3_d2a").fadeOut();
    });
    $("#jq3_d2b").mouseover(function(){
	$("#jq3_d2b").fadeOut(2000);
    });
    $("#jq3_d2c").mouseover(function(){
	$("#jq3_d2c").fadeOut(2000, function(){
	    console.log("Press FadeIn Button to Fade in.");
	});
    });
    //fadeToggle
    $("#jq3_b2b").click(function(){
	$("#jq3_d2d").fadeToggle(2000, function(){
	    $("#jq3_d2d").text("X");
	});
    });
    //fadeTo
    $("#jq3_b2c").click(function(){
	$("#jq3_d2e").fadeTo(2000, 0.3, function(){
	    $("#jq3_d2e").text("Z");
	});
    });
});
a
b
c
T
O

slideDown(speed[, callback()]), slideUp(speed[, callback()]), slideToggle(speed[, callback()]): 滑進與滑出。 >>

$("p.ooxx")
    .slideUp(1000, function(){
    console.log("Hidden!");
    })
    .slideDown(1000, function(){
    console.log("Shown!");
    });
$(document).ready(function(){
    $("button.bt1").click(function(){
	$("p#xxx")
	    .slideToggle("slow", function(){
		console.log("Toggled!");
	});
    });
});
<p id="jq3_p3" style="text-align:center; background:#5588ff;margin-bottom:0px;">Move mouse here</p>
<div id="jq3_d3" style="text-align:center; background:#55ff88; height:250px;margin:0px;">Show Area</div>
<button id="jq3_b3">Slide Toggle</button>
$(document).ready(function() {
    $("#jq3_p3").mouseout(function(){ 
	$("#jq3_d3").slideDown(2000);
    });
    $("#jq3_p3").mouseover(function(){ 
	$("#jq3_d3").slideUp(2000, function(){
	    $("#jq3_d3").append("Coming back...");
	});
    });
    $("#jq3_b3").click(function(){ 
	$("#jq3_p3").slideToggle(2000);
    });
});

Move mouse here

Show Area

animate({parameters}[,duration, easing, callback()]): 動畫。

$(document).ready(function(){
    $("#xxx")
    .css({
	"background":"pink",
	"border":"1px solid black"
    })
    .animate({
	"width":"500px",
	"height":"100px"
    }, 5000, "swing", function(){
	console.log("Animation complete!");
    });
});
or
$(document).ready(function(){
    $("#xxx")
    .css({
	"background":"pink",
	"border":"1px solid black"
    })
    .animate({
	"width":"500px",
	"height":"100px"
    }, 
    {
	"duration":5000,
	"easing":"swing",
	"complete":function(){
	    console.log("Animation complete!");
	}
    });
});
or
$(document).ready(function(){
    $("#xxx")
    .css({
	"background":"pink",
	"border":"1px solid black"
    })
    .animate({
	"width":"500px",
	"height":"100px"
    }, 
    {
	"duration":5000,
	"easing":"swing",
	"complete":function(){
	    console.log("Animation complete!");
	},
	"step":function(){
	    console.log("Step completed!");
	},
	"queue":true,
	"specialEasing":{
	    "width":"linear"
	}
    });
});

delay(duration [, queueName ]): 延遲

$(document).ready(function(){
    $("#xxx")
    .css({
	"background":"pink",
	"border":"1px solid blue"
    })
    .slideUp(1000, function(){
	console.log("Animation completed!");
    })
    .delay(3000)
    .slideDown(1000, function(){
	console.log("Animation completed!");
    });
});

stop(stopAll, goToEnd): 停止effects(not only animate),default參數為false, false。 >>

$(document).ready(function(){
    var count = 0; // Keep track of the current step count
    $("#xxx")
    .css({
	"background":"yellow",
	"border":"1px solid black"
    })
    .animate({
	"width":"500px"
    },
    {
	"duration":5000,
	"step":function(){
	    if(count++==200)
	    {
		$(this).stop(true, true);
	    }
	}
    });
});
<div style="height:50px;padding:0px;">				
    <div id="jq3_d4" style="background:lime;width:50px;height:50px;text-align:center;line-height:40px;margin:0px;"></div>
</div>
<button id="jq3_b4">Stop</button>
$(document).ready(function() {
    $("#jq3_d4").click(function(){ 
	$("#jq3_d4").animate({opacity: 0.5, marginLeft: '700px', width: "100px"}, 6000, 'swing', function(){
	    $("#jq3_d4").text("Done");
	}).animate({opacity: 1, marginLeft: '0px', width: "50px"}, 6000, 'linear', function(){
	    $("#jq3_d4").text("");
	});
    });
    $("#jq3_b4").click(function(){ 
	$("#jq3_d4").stop(true, false);
    });
});
兩個animate()連在一起表示先做第一個然後做第二個。

Example

<div id="jq4_d1">
    <ol>
	<li>One</li>
	<li>Two
	    <ul>
		<li>A</li>
		<li class="jq4_c1">B</li>
		<li>C</li>
		<li>D</li>
		<li>E
		    <ol>
			<li>a</li>
			<li id="jq4_li1">b</li>
			<li class="jq4_c1">c</li>
		    </ol>
		</li>
		<li>F</li>
	    </ul>
	</li>
	<li>Three</li>
	<li class="jq4_c2">Four</li>
	<li>Five</li>
    </ol>
</div>

<input type="button" value="Hide&Show" id="jq4_b1a"></input>
<button id="jq4_b1b">slideToggle</button>
<button id="jq4_b1c">Animate</button>
<button id="jq4_b1d">Border</button>
<button id="jq4_b1e">fadeToggle</button>
$(document).ready(function() {
    $(".jq4_c1").css({"color":"red"});
    $("#jq4_li1").parents("ul").children().eq(0).css({"color":"blue"}); // parents()
    //Buttons
    $("#jq4_b1a").click(function(){ //find all children, hide&show
	$("#jq4_d1").children().toggle();
    });
    $(".jq4_c1").click(function(){ //find pre&next, css(background)
	$(".jq4_c1").prev().css({"background":"pink"});
	$(".jq4_c1").next().css({"background":"lime"});
    })
    $("#jq4_b1b").click(function(){ //slideToggle
	$("#jq4_d1").find(".jq4_c1").parent().slideToggle(2000);
    });
    $("#jq4_b1c").click(function(){ //animate
	$("#jq4_d1").animate({opacity:0.3, marginLeft:'500px'}, 2000)
	.animate({opacity:1, marginLeft:'0px'}, 2000);
    });	
    $("#jq4_b1d").click(function(){ //border
	$("#jq4_d1").find('li').not('ul').css({"border":"1px solid blue"});
	$("#jq4_d1").find('ul').children().css({"border":"1px solid red"});	
    });
    $("#jq4_b1e").click(function(){ //fadeToggle
	$("#jq4_d1").children().children().filter("li:even").fadeToggle();
    });
});
  1. One
  2. Two
    • A
    • B
    • C
    • D
    • E
      1. a
      2. b
      3. c
    • F
  3. Three
  4. Four
  5. Five

More Events

scroll(): 捲軸。

$(document).ready(function(){
    $(window)
    .scroll(function(){
	console.log("The window was scrolled!");
    });
});
Either $(window) or $(this) is OK.
$(document).ready(function(){
    $(window)
    .scroll(function(){
        if($(this).scrollTop() > 200){
            console.log("The window was scrolled!");
	}
    });
});

bind()&unbind(): Deprecated. Use on&off instead.

$(document).ready(function(){
    $("p.ooxx")
    .bind("click", function(){
	console.log("You clicked ooxx");
	$(".ooxx").css({"background":"tomato","color":"blue"}).fadeOut(2000);;
    });

    $("p")
    .bind("click mouseover", {msg:"Whatever!"}, function(event){
	console.log(event.data.msg);
    });

    $("p#xxx")
    .bind({
	"click":function(){
	    console.log("You clicked xxx");
	},
	"dblclick":function(){
	    $("p:empty").text("Been double clicked").css({"color":"blue"});
	}
    });

    $("button.bt1").click(function(){
	$("p").unbind();
        //$("p").unbind("click");
    });
});

on()&off(): 取代bind()&unbind()

$(document).ready(function(){
    $("p.ooxx")
    .on("click", function(){
	console.log("You clicked ooxx");
	$(".ooxx").css({"background":"tomato","color":"blue"}).fadeOut(2000);;
    });

    $("p")
    .on("click mouseover", {msg:"Whatever!"}, function(event){
	console.log(event.data.msg);
    });

    $("p#xxx")
    .on({
	"click":function(){
	    console.log("You clicked xxx");
	},
	"dblclick":function(){
	    $("p:empty").text("Been double clicked").css({"color":"blue"});
	}
    });

    $("button.bt1").click(function(){
		//$("p").off();
        $("p").off("click");
    });
});

one(): 僅執行一次。

$(document).ready(function(){
    $("#xxx").one("click", function(){
	console.log("僅執行一次.");
    });
});

trigger(): 即刻觸發

$(document).ready(function(){
   $("#xxx")
   .bind("click", function(){
	console.log("Clicked!");
   }).trigger("click");
});

Applications


jQuery UI


jQuery UI(user interface)是一組快速的介面工具組合,可以讓我們更容易地建立互動應用。它也是基於jQuery javascript來建立,使用前須先加上以下連結:
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
可至jQuery官網查看最新版本。接下來介紹一些應用。

AngularJS Introduction


AngularJS是JavaScripe所延伸出的語言,類似JQuery也是一種JavaScript(Angular與AngularJS似乎名稱相近但不盡相同,使用的基礎語言不同)。在此介紹簡單用法。類似JQuery,使用AngularJS之前須先加上
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular.min.js"></script>
到head標籤內。
AngularJS主要使用directives來延伸HTML,常見的directives例如: 以下分項舉例說明。

Basic Syntax


Basic Syntax範例

使用AngularJS時第一個一定要使用到ng-app這個directive,其意義是指將被套用的範圍,例如我們建立一個div如下:
<div ng-app=""></div>
這表示我們將會應用AngularJS到這個div內,而ng-app在一個網頁通常只能定義一次,所以如果我們有多個地方要應用angularJS,我們可以將ng-app定義到較為外層的容器,例如body:
<body ng-app="">
如此我們可以讓AngularJS應用到整個網頁。若是我們僅要顯示個文字或是簡單計算,也就是沒有控制流程(controller),那麼ng-app=""就可以了。不過沒有控制流程顯然做不出甚麼東西來,所以我們直接完整一點,給個名字如下:
<body ng-app="myApp">
接下來我們在html內設計如下的程式碼:
<script>
    var app = angular.module("myApp", []);
</script>
通常將這段JavaScript放在</body>之前。然後我們在body內寫:
<div>
<h1>{{5+1}}</h1>
</div>
現在你應該會看到顯示6。不過測試了一下,大概僅能做簡單的加減乘除以及mod。不過我們的重點不是要在這裡做計算,現在讓我們加上一個輸入區如下:
Input your name: <input type="text" ng-model="name"><br>
Hello, <span ng-bind="name"></span>
<p>Hello, {{name}}</p>
首先使用input建立一個文字輸入區,在input的標籤內使用ng-model="名稱",自行命名,代表抓取了之後輸入的值。在要顯示的地方,例如span,使用ng-bind="名稱",表示會將名稱的內容與此顯示之內容綁定,所以之後輸入甚麼就會顯示甚麼。第三行表示也可以使用{{名稱}}來表示此變數的內容。若是欲顯示的內容來自超過一個輸入欄,則使用如下方式:
<div>
First name: <input type="text" ng-model="firstname"><br>
Last name: <input type="text" ng-model="lastname"><br>
Hello, <span ng-bind="firstname + ' ' + lastname"></span>
<p>Hello, {{firstname + " " + lastname}}</p>
</div>
再試一下加上以下的的程式碼來計算距離:
<div>
Velocity(km/hr): <input type="text" ng-model="v"><br>
Time(hr): <input type="text" ng-model="t"><br>
Distance(km): <span ng-bind="v*t"></span>
</div>

Module & Controller


Module & Controller範例

前例中在script內我們使用angular.module("myApp", [])來建立一個module,而一個module就是一個應用程式(Application),它本身是一個包含controller的容器,而controller是JavaScript物件,可用來控制資料。現在重新設計前例如下:
<div ng-controller="ctrlOne">
First name: <input type="text" ng-model="firstname"><br>
Last name: <input type="text" ng-model="lastname"><br>
Hello, <span ng-bind="firstname + ' ' + lastname"></span>
</div>
只有加上一個ng-controller="ctrlOne",ctrlOne是任意給的名稱,意思就是此處的內容將由ctrlOne這個controller控制,而我們必須要設計一個名為ctrlOne的controller否則此時無法執行。現在將script修改如下:
<script>
var app = angular.module("myApp",[]);
app.controller("ctrlOne", function($scope){
$scope.firstname = "Tony";
$scope.lastname = "Stark";
});
</script>
使用app.controller()來實現一個controller,第一個參數就是對應的名稱,第二個參數是一個函數,用此函數來定義變數與控制流程,函數的參數$scope是一個物件。當定義$scope.firstname='Tony'時,firstname的初始值被給定,所以在執行網頁時,會看到其中顯示初始值。目前似乎沒有比之前的方法來得簡單,甚至要打較多的程式碼,不過可以想見之後我們可以在此處進行各種設定與計算,開始有較多的靈活度。再將之前計算距離的部分重寫如下:
<div ng-controller="ctrlTwo">
Velociyt(km/hr): <input type="text" ng-model="v"><br>
Time(hr): <input type="text" ng-model="t"><br>
Distance(km): <span ng-bind="dis()"></span>
</div>
此處定義另一個controller(ctrlTwo)來控制,另一個不同處是讓距離的計算成為一個函數dis()。接下來在script處加上新的controller如下:
app.controller("ctrlTwo", function($scope){
$scope.v = 0;
$scope.t = 0;
$scope.dis=function(){
return $scope.v*$scope.t;
}
});
這裡定義dis的值為一個函數。除了使用前述的語法,還可以使用如下的方式來設計controller的函數參數,首先設計HTML程式碼如下:
<div ng-controller="ctrlThree as ctrl">
Velociyt(km/hr): <input type="text" ng-model="ctrl.v"><br>
Time(hr): <input type="text" ng-model="ctrl.t"><br>
Distance(km): <span ng-bind="ctrl.dis()"></span>
</div>
使用as來給controller化名,然後之後的參數都使用此化名為命名空間(Name space)來定義,而在script中再加上一個新的controller如下:
app.controller("ctrlThree", [function(){
this.v = 0;
this.t = 0;
this.dis=function(){
return this.v*this.t;
}
}]);
此處不再使用$scope,而是使用this關鍵字來指代該物件本身,函數沒有參數,而整個函數須放在一個中括號內([])。

Events


Events範例

跟JS類似,可以控制不同的Events,相關的對應directivs有: 例如當滑鼠點擊時觸發事件,這是在設計時常做的設計也是常用的操作,在AngularJS中,此設計的做法如下:
<div>
<button ng-click="item1='Clicked'">
<span ng-bind='item1 || "Click"'></span>
</button>
</div>
執行程式後,點擊按鈕會出現Clicked字樣。當然光是這樣好像沒甚麼,現在設計一個計數器,點一下按鈕就+1,如下:
<div>
{{count || 0}}
<button ng-click="count=count+1">+1</button>
<button ng-click="count=0">>0</button>
</div>
輕鬆愉快!甚至連controller都不需要設計。再做幾個例子,先來個下拉選單:
<div ng-controller="eventCtrler as ctrl">
<button ng-click="ctrl.tog()">Colors</button>
<div ng-show="ctrl.isshow">
<ul class="menu">
<a href="AngularJS1_Basic.html"><li>Red</li></a>
<a href="AngularJS2_ModuleController.html"><li>Green</li></a>
<a href="AngularJS3_Click.html"><li>Blue</li></a>
</ul>
</div>
</div>
還是簡單的使用ng-click,也可以換成ng-mouseover。對應的CSS如下:
.menu{
list-style:none;
width:45px;
position:relative;
top: -15px;
left: 0px;
}
.menu li{
background: olive;
color: white;
padding: 3px;
margin:auto;
text-align:left;
position:relative;
left:-35px;
}
.menu li:hover{
background: orange;
}
.menu>a{
text-decoration: none;
}
可以使用$event作為參數傳入函數,$event是事件物件,例如:
<div ng-controller="eventCtrler2">
<h1 ng-mousemove="loc($event)">隨便內容</h1>
<p>Coordinates: {{x + ', ' + y}}</p>
</div>
接著設計對應的controller:
app.controller('eventCtrler2', function($scope) {
$scope.loc = function(eve) {
$scope.x = eve.clientX;
$scope.y = eve.clientY;
}
});
MouseEvent Object詳情在此

ng-show & ng-hide & ng-disabled


ng-show & ng-hide & ng-disabled範例

很明顯是要控制元素物件的顯示或是隱藏,舉例如下:
<div>
<span ng-hide="ishide">顯示內容</span>
<button ng-click="ishide=true">Hide</button>
</div>

<div>
<span ng-show="isshow">顯示內容</span>
<button ng-click="isshow=true">Show</button>
</div>
直接設計兩個部分,當無論是ng-show或是ng-hide的名稱為何(isshow或ishide),初始的值皆為false。在點擊之後再讓其值變成true,此時該隱藏的隱藏,該顯示的顯示。把兩者合併設計成toggle形式如下:
<div ng-controller="ctrl_1">
<button ng-click="toshow()">Toggle</button>
<span ng-hide="show">顯示內容</span>
</div>
首先設計一個按鈕跟一個內容,預計點擊按鈕後顯示與隱藏交錯發生,因此設計其controller如下:
<script>
var app = angular.module("myApp",[]);

app.controller("ctrl_1", function($scope){
$scope.count = 0;
$scope.show = false;
$scope.toshow=function(){
if($scope.count%2==0)
$scope.show=true
else
$scope.show=false
$scope.count++;
}
});
</script>
利用這個形式可以產生toggle的效果。那若是有兩個元素交互出現呢?其實只要設計元件變成兩個並各由ng-show與ng-hide來控制即可,如下:
<div ng-controller="ctrl_1">
<button ng-click="toshow()">Toggle</button>
<span ng-hide="show">顯示內容一</span>
<span ng-show="show">顯示內容二</span>
</div>
使用同一個controller,此時按鈕會讓兩個元素內容交錯出現。
順便提一下ng-disabled,這可以讓元件失去作用,例如:
<div ng-init="isdisabled=true">
<br>
<button ng-disabled="isdisabled">Button</button>
<br>
<input type="checkbox" ng-model="isdisabled">Disable button?
</div>

ng-class & ng-style


ng-class & ng-style範例

ng-class是用來控制元件的class,如此可以改變CSS設定,舉個例子,假定我們有如下的style:
<style>
.redfont{
color: red;
}
</style>
接下來設計個元件如下:
<div>
<span ng-class="'redfont'">內容</span>
</div>
網頁顯示文字為紅色,要注意ng-class之值的quote,須將class的名稱(單引號內)放入雙引號內。不過這不就是跟直接使用CSS的class效果完全相同?當然我們可以有進一步的變化,例如:
<div>
<input id='setbtn' type='button' value='set' ng-click="classx='fontsize'">
<input id='clearbtn' type='button' value='clear' ng-click="classx=''">
<br><br>
<span class="bgcolor" ng-class="classx">Sample</span>
</div>
如此方式可以讓我們控制元件的class。對應的CSS碼(bgcolor與fontsize)如下:
.bgcolor{
background: #a1f1ff;
}

.fontsize{
font-size: 3em;
}
一般來說,控制class應使用ng-class,比較不建議使用class然後讓名稱當作變數,例如:
<div ng-init="className='redfont'">
<div ng-click="className='bgcolor'" class="{{className}}">顯示內容</div>
</div>
現在在文字上點擊便會改變style,當然還是可以使用,不過使用ng-class應該比較正統。
相對於class,我們也可以使用ng-style來直接改變style,舉例如下:
<div>
<p ng-click='stylex={"background":"pink"}' ng-style='stylex'>background color</span></p>
</div>
一樣點擊文字來改變style。不過似乎使用ng-class會比較靈活一點,而且class可以重複利用。當然還可以更細節的將屬性變成變數,例如下例,不過應該還是使用ng-class較好操控。
<div>
<input type="text" ng-model="colorx"><br>
<p style="background:{{colorx}};">background color is {{colorx}}</p>
</div>
嗯,就這樣。

Control Flow


Control Flow範例

通常程式設計中的Control Flow指的是像if...else、while loop、for loop、switch等控制程式進行的指令,AngularJS內也有類似的指令,不過有點點不同,此處略作介紹。首先先看ng-if,舉下例說明:
<div>
    <input type="checkbox" ng-model="checked">Check?

    <div ng-show='checked'>
        <span>show內容</span>
    </div>
		
    <div ng-if='checked'>
        <em>if內容</em>
    </div>
</div>
此處設計一個選項,當選擇之後,true的值pass到checked變數供之後兩處使用。在此設計一個ng-show與一個ng-if,這兩者會有相同的結果,不過涵義不同,我們知道ng-show是顯示與不顯示,也就是說元件還在,只是有否顯示。但是ng-if為false意思是將元件刪去,true的時候才加上去。
接著看ng-switch,當選擇對應的值時,執行該值所對應的內容。例如:
<select ng-model="whichone">
    <option value="iron"> Iron Man
    <option value="spider"> Spider Man
    <option value="super"> Super Man
</select>

<section ng-switch="whichone">
    <article ng-switch-when="iron">
	<h1>Iron Man</h1>
	<p>Tony Stark</p>
    </article>
	
    <article ng-switch-when="spider">
	<h1>Spider Man</h1>
	<p>Peter Parker</p>
    </article>
	
    <article ng-switch-when="super">
	<h1>Super Man</h1>
	<p>Clark Kent</p>
    </article>

</section>
使用ng-switch-when關鍵字,當ng-switch對應的值與其相同時,執行該項內容。
這沒甚麼好說的,no-repeat就是for loop,如下例:
<div ng-repeat="x in [1,2,3,4,5]">
{{x}}
</div>
可以看到印出陣列中所有元素。不過如果將陣列改為[1,2,3,2,1]的話,你將會看到甚麼都印不出來,按F12會看到錯誤訊息。因為ng-repeat會瀏覽陣列中的值,用來產生新的DOM,每個元素都會加上$$hashKey的值,與產生的DOM對應才知道是否應重新產生DOM。因為陣列元素的key就是陣列元素本身,所以重複內容無法產生新的DOM,所以應變的作法是加上track by $index,如此可讓$index作為key,這樣就不會重複了。如下:
<div ng-repeat="x in [1,2,3,2,1] track by $index">
{{x}}
</div>
接下來再看下一個例子,首先在script內設計以下的controller:
app.controller('repeatCtrler',[function(){
this.person={
"tom":{
"age":19,
"weight": 55
},
"mary":{
"age":22,
"weight": 45
},
"adam":{
"age":17,
"weight": 65
},
"helen":{
"age":20,
"weight": 46
}
}
}]);
在這個controller內定義了一個物件(person),其內有人名及其屬性。接下來設計如下的HTML:
<div ng-controller="repeatCtrler as ctrl">
<div ng-repeat="(k,v) in ctrl.person" ng-class="{'redfont': $first, 'bgcolor': $middle, 'fontsize': $last}">
{{$index+1}}<br>
Name: {{k}}<br>
Age:{{v.age}}<br>
Weigth:{{v.weight}} kg<br><br>
</div>
</div>
首先內層的div使用ng-repeat,因為person內元素是含有key與value之物件,所以每一次都得到key(k)與value(v)的值。之後的ng-class顯然是要定義class,而$first、$middle、與$last則分別表示第一個元素、中間的元素、以及最後一個元素(可以搭配!來表示非,e.g. !$first表示不是第一個)。$index則表示陣列的索引值。每一迴圈皆會建立一個新的div,其內包含一個物件的內容值。除此之外,還可以使用$odd與$even來表示單數個與偶數個,如下:
<div ng-controller="repeatCtrler as ctrl">
<div ng-repeat="(k,v) in ctrl.person track by $index" ng-class="{'redfont': $even, 'bgcolor': $odd}">
{{$index+1}}<br>
Name: {{k}}<br>
Age:{{v.age}}<br>
Weigth:{{v.weight}} kg<br><br>
</div>
</div>
換成使用table顯示:
<div ng-controller="repeatCtrler as ctrl">
<table class="table">
<tr ng-repeat="(k,v) in ctrl.person" ng-class="{'redfont': $even, 'bgcolor': $odd}">
<td>Name: {{k}}</td>
<td>Age:{{v.age}}</td>
<td>Weigth:{{v.weight}} kg</td>
</tr>
</table>
</div>
為了讓顯示更明顯,加上table這個class,對應的CSS為:
.table td{
border:1px solid blue;
}
若是想要讓資料分布在兩個table row,此時無法僅使用np-repeat,倒是可以使用np-repeat-start搭配np-repeat-end使用,如下:
<div ng-controller="repeatCtrler as ctrl">
<table class="table">
<tr ng-repeat-start="(k,v) in ctrl.person" ng-class="{'redfont': !$first, 'bgcolor': $first}">
<td class="table orange">Name: {{k}}</td>
<td>Age:{{v.age}}</td>
</tr>
<tr ng-repeat-end>
<td>Weigth:{{v.weight}} kg</td>
</tr>
</table>
</div>
最後再來個搭配排序的作法,使用orderBy語法,舉例如下,一樣先設計controller內容:
app.controller('orderByCtrler',[function(){
this.node=[
{id:'one'},{id:'two'},{id:'three'},{id:'four'},{id:'five'},{id:'six'},{id:'seven'}
]
}]);
其中的元件node是一個array,而orderBy正是可用來排序array內元素。如下:
<div ng-controller="orderByCtrler as ctrl">

<div ng-repeat="n in ctrl.node | orderBy:'id'" ng-bind="n.id"></div><br>

<div ng-repeat="n in ctrl.node | orderBy:'-id' | limitTo:3" ng-bind="n.id"></div><br>

<div ng-repeat="n in ctrl.node | orderBy:'id':false | limitTo:-5" ng-bind="n.id"></div><br>

<div ng-repeat="n in ctrl.node | orderBy:'id':true" ng-bind="n.id"></div><br>

</div>
orderBy: 'id'或是orderBy:'id':false都是升冪排列,反之都是降冪排列。limitTo:3表示取前三個,limitTo:-5則表示後面五個。就這樣。
順便介紹一下ng-options,主要是製作select box,看起來類似ng-repeat,不過不大相同,例如先設計個controller:
app.controller('selectCtrler',[function(){
this.colors=['red','green','blue'];
}]);
接下來設計HTML的部分:
<div ng-controller="selectCtrler as ctrl">
<select ng-model="selectedColor" ng-options="x for x in ctrl.colors"></select>
<span style="color:{{selectedColor}}">{{selectedColor}}的內容-</span>
</div>
現在可以選擇其中的選項。

Validation


Validation範例

確認表格內的資料格式是否符合要求是JavaScript的重要功能之一,AngularJS提供便利的方式讓我們可以達到此目的,在使用AngularJS之前,先看HTML5的做法,舉例如下:
<div>
    <form name="formx">

        First name: <input name="firstname" ng-model="firstname" required>
        <span style="color:red;" ng-hide="formx.firstname.$valid">* Required</span>
        <br><br>

        Email: <input name="email" ng-model="email" type="email">
        <span style="color:red;" ng-hide="formx.email.$valid">* Invalid</span>

    </form>

        <h5>{{formx.firstname.$valid}}</h5>
        <h5>{{formx.email.$valid}}</h5>

</div>
當使用required關鍵字在input標籤內,表示此欄必填。當指定type="email",表示須符合email的寫法格式(注意沒填算格式對)。我們同時使用ng-hide語法來顯示文字以警示需填寫或格式正確語法。AngularJS會持續的更新form跟input欄位的狀態(state),對於輸入欄(input fields),狀態包含以下幾種: 而form的狀態則包含以下幾種: 而根據上述的狀態,可以使用對應的CSS classes,對於輸入欄來說有以下class可供選擇: 應該可以望文生義,所以不多解釋。對於form來說則有以下的class供選擇: 當對應的值為false時,對應的這些class會被移除。現在看個例子馬上可以心領神會。首先加上以下的CSS碼:
<style>
    input.ng-invalid{
        background: tomato;
    }
    input.ng-valid{
        background: lightgreen;
    }
    form.ng-pristine{
	background: lightblue;
    }
    form.ng-dirty{
	background: pink;
    }
</style>
其實加上這個CSS之後,應該已經影響到上一個例子,不過此處還是再製作個Form如下:
<div>
    <form name="formy">
        <input name="namey" ng-model="namey" required>
    </form>
</div>
現在的效果是輸入欄內容正確與否,會顯示不同底色,整個form在未填寫與填寫也有不同對應的底色。這些都是因為對應的class的作用。現在根據這些,重寫第一個例子如下:
<div ng-controller="validateCtrler">
    <form name="formz" novalidate>
        <p>
            Your name: <br><input name="yourname" ng-model="yourname" required> 
	    <span style="color:red;" ng-show="formz.yourname.$dirty && formz.yourname.$invalid">
	        <span ng-show="formz.yourname.$error.required">* Required</span>
	    </span>
	</p>

	<p>
            Email: <br><input name="emailz" ng-model="emailz" type="email" required>
				
	    <span style="color:red;" ng-show="formz.emailz.$dirty && formz.emailz.$invalid">
	        <span ng-show="formz.emailz.$error.required">* Required</span>
		<span ng-show="formz.emailz.$error.email">* Invalid</span>
	    </span>	
	</p>
	
        <p>
	    <input type="submit" ng-disabled="formz.yourname.$dirty && formz.yourname.$invalid ||
		formz.emailz.$dirty && formz.emailz.$invalid">
	</p>
    </form>
		
</div>
此處多增加了submit按鈕,需再之前欄位完全正確之後方能使用。使用emailz或是yourname等名稱是避免與之前的名稱衝突。

Filter


Filter範例

Filter就是用來過濾資料然後修改資料格式,有些之前介紹過了,此處一併整理,下列為可用之filter: 其中limitTo、orderBy都是老面孔了,其他的也不困難,舉例說明如下:
<div  ng-controller="aCtrler">
    <p>Name: {{firstname|lowercase}} {{lastname|uppercase}}</p>
    <p>Assets: more than {{assets|currency}}<p>

    <p>Find the employees with:
        <input type="text" ng-model="alphabet"> 
	orderBy: 
	<button ng-click="orderby('name')">Name</button>  
	<button ng-click="orderby('country')">Country</button>
    </p>

    <ul>
        <li ng-repeat="x in employees | orderBy: odby | filter:alphabet">
	    name: {{x.name}}, country: {{x.country}}
	</li>
    </ul>

</div>
改變成大小寫或是貨幣格式應該不成問題,將陣列內物件排列並根據相關輸入的字母搜尋,對應的controller如下:
<script>
	
    var app = angular.module("myApp",[]);
		
    app.controller('aCtrler', function($scope){
	$scope.firstname = 'Tony';
	$scope.lastname = 'Stark';
	$scope.assets = 99999999999;
	$scope.employees = [
       	    {name:'Abilene', country:'Norway'},
	    {name:'Albert', country:'Sweden'},
            {name:'Barnett', country:'England'},
	    {name:'Beck', country:'Norway'},
	    {name:'Carol', country:'Denmark'},
	    {name:'Cliff', country:'Sweden'},
	    {name:'Dena', country:'Denmark'},
	    {name:'Darton', country:'England'},
            {name:'Emily', country:'England'},
	    {name:'Edward', country:'Norway'}
	];
			
	$scope.orderby = function(x) {
	    $scope.odby = x;
	}
    });

</script>

關於轉換成大小寫等,AngularJS也提供相關的JavaScript函數稱為API(Application Programming Interface)供我們使用,譬如:angular.lowercase()、angular.uppercase()、angular.isString()、或angular.isNumber()等。舉例如下,先設計個controller:
app.controller('bCtrler', function($scope){
    $scope.firstname = angular.lowercase("CLARK");
    $scope.lastname = angular.uppercase("kent");
    $scope.isS = angular.isString($scope.firstname);
    $scope.isN = angular.isNumber($scope.firstname);
});
沒甚麼特別的,只是幾個數值,現在將這些內容顯示:
<div ng-controller="bCtrler">
    <p>{{lastname}}, {{firstname}}</p>
    <p>{{isS}}, {{isN}}</p>
</div>
就這樣。

Animation


Animation範例

AngularJS提供一些動態的元件變化,可以搭配CSS使用。要使用這些動畫效果,首先必須額外導入另一個js檔案,所以需加上以下指令:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.9/angular-animate.js"></script>
此外,需定義ng-app="ngAnimate",也就是特定的ng-app名稱。或者還是使用自訂的名稱,但是在angular.module()內將ngAnimate做為第二個引數,如下:
var app = angular.module('myApp', ['ngAnimate']);
接著就可以搭配directives來增刪CSS classes以產生動畫效果,可能用到的directives有以下幾種。 現在來看個例子:
<input type="checkbox" ng-model="checked"> Hide div

<div class="divx" ng-hide="checked">
    div內的內容
</div>
這個設計是當我們點選check box選項後,div就hide起來。不過hide起來的方式是根據對應的CSS內容,如下:
<style>
    
    .divx{
	transition: all linear 0.5s;
	background: aliceblue;
	height: 100px;
    }
    
    .ng-hide{
	height: 0;
    }
	
</style>
原則上只是控制其對應的class。

Application


Application範例

一個小應用做為結尾:
<div ng-controller="arrayCtrler">

    <table class="tablex">
	<tr ng-repeat="x in arr">
            <td>{{x}}</td>
	    <td ng-click="removeItem($index)">x</td>
	</tr>
    </table>

    <input ng-model="item">
    <button ng-click="addItem()">Add</button>
    <p ng-bind="error"></p>

</div>
先設計這些元件,原則上是一個table,裡面的資料第一欄來自一個array。第二欄就打一個x,且點擊後會觸發removeItem()方法。之後有一個input位置,顯示文字部分為一個按鈕。點擊後觸發addItem()方法。先加上CSS稍微整理一下外觀:
<style>
    .tablex td:first-child{
        background: lightgreen;
	border: 1px solid blue;
	min-width: 50px;
    }
    
    .tablex td:last-child{
	background: aliceblue;
	border: 1px solid blue;
	min-width: 10px;
	cursor: pointer;
    }
</style>
最後設計controller如下:
<script>

    var app = angular.module("myApp",[]);

    app.controller("arrayCtrler",function($scope){
	$scope.arr = ['a','b','c'];
		
	$scope.addItem = ()=>{
	    $scope.error="";
	    if($scope.arr.indexOf($scope.item)==-1){
		$scope.arr.push($scope.item);
	    }else{
		$scope.error="Existed."
	    }
	}
		
	$scope.removeItem = (y)=>{
	    $scope.error="";
	    $scope.arr.splice(y,1);
	}
		
    });

</script>

此中有兩個方法addItem()與removeItem()分別對應之前元件內可能觸發的方法。在addItem()內,本來有push()即可將元素加入到arr中,不過若是輸入的元素已存在arr內,則會出現錯誤,所以先判斷不在arr內($scope.arr.indexOf($scope.item)==-1)才push,否則顯示錯誤訊息。removeItem()之前先清除錯誤訊息,然後可以使用splice()方法刪除。