新手村
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Versions and GitHub Sync Note Insights Sharing URL Help
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       owned this note    owned this note      
    Published Linked with GitHub
    Subscribed
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Subscribe
    # Web學習筆記(Javascirpt 一) # Javascript ## 數字尋找 Binary Search + Selection Sort ``` JavaScript <script> debugger var lines = [] function solve(lines){ let [n, m] = lines[0].split(' ') let arr = [] let k = 0 for (i=0; i<n; i++) { arr[i] = Number(lines[i+1]) } n = Number(n) // Selection Sort for (i=0; i<arr.length; i++) { for(j=i+1; j<arr.length; j++) { if (Number(arr[i]) > Number(arr[j])) { k = Number(arr[i]) arr[i] = arr[j] arr[j] = k } } } console.log(arr) for(let i=n+1; i<lines.length; i++) { let q = Number(lines[i]) console.log(search(arr, q)) } } function search(arr, q){ let num = -1, low = 0, high = arr.length - 1, midNum = 0 while(low <= high) { midNum = Math.floor((low + high) / 2) if(arr[midNum] === q) { num = midNum break } if(arr[midNum] > q) { high = midNum - 1 }else { low = midNum + 1 } } if(num === -1) { return "找不到資料!" }else { return num } } solve(['10 3','1', '4', '3', '5', '2', '6', '8', '7', '9', '10', '5', '11', '100', '10']) //console.log(solve('5','A','B','B','A','B')) </script> ``` ## DOM ### toggle ### 結構 ```HTML <!DOCTYPE html> <html> <head> <title>Color Toggle</title> <style type="text/css"> .purple { background: purple; } </style> </head> <body> <button>CLICK ME</button> <script type="text/javascript" src="toggle.js"></script> </body> </html> ``` ```javascript //document.querySelector("")搜索第一個元素 var button = document.querySelector("button"); var isPurple = false //監聽物件,第一個是監聽事件的類型第二個是希望事件發生時執行的指令 /*button.addEventListener("click", function(){ if(isPurple){ document.body.style.background = "white" }else { document.body.style.background = "purple" } })*/ button.addEventListener("click", function(){ //document.body.classList.toggle切換類 //檢查當元素上沒有這個CSS類時就新增這個CSS類 //如果已有就把她刪除 document.body.classList.toggle("purple"); }); ``` ![](https://i.imgur.com/f6XQPU3.gif) ## 圖片預覽練習 ### 結構 **imgExercise.html** ```HTML <!DOCTYPE html> <html> <head> <title>imgExercise</title> </head> <body> <form runat="server"> <input onchange="showimg()" accept="image/*" type='file' id="imgInp"> <img id="blah" src="#" alt="your image" style= "display:none"> <button onclick="closeimg" id="imgclose">close</button> </form> </body> <script type="text/javascript" src="imgExercise.js"></script> </html> ``` **imgExercise.js** ```javascript let showimg = document.getElementById("imgInp") let img = document.getElementById("blah") let button = document.getElementById("imgclose") imgclose.addEventListener("click", function() { document.getElementById('imgInp').style.display='none' }) showimg.addEventListener("change" , function() { const [file] = showimg.files if (file) { blah.src = URL.createObjectURL(file) img.style.display='inline-block' } }) ``` ### 成品 ![](https://i.imgur.com/Js8oCzu.gif) ## ScoreKeeper ### 結構 ```HTML <!DOCTYPE html> <html> <head> <title>Score Keeper</title> <link rel="stylesheet" type="text/css" href="scorekeeper.css"> </head> <body> <h1><span id="p1Display">0</span> to <span id="p2Display">0</span></h1> <p>Playing to: <span>5</span></p> <input type="number"> <button id="p1">Player One</button> <button id="p2">Player Two</button> <button id="reset">Reset</button> <script type="text/javascript" src="scorekeeper.js"></script> </body> </html> ``` ```javascript var p1Button = document.querySelector("#p1"); var p2Button = document.getElementById("p2"); var resetButton = document.getElementById("reset"); var p1Display = document.querySelector("#p1Display"); var p2Display = document.querySelector("#p2Display"); var numInput = document.querySelector("input"); var winningScoreDisplay = document.querySelector("p span"); var p1Score = 0; var p2Score = 0; var gameOver = false; var winningScore = 5; p1Button.addEventListener("click", function(){ if(!gameOver){ p1Score++; if(p1Score === winningScore){ p1Display.classList.add("winner"); gameOver = true; } p1Display.textContent = p1Score; } }); p2Button.addEventListener("click", function(){ if(!gameOver){ p2Score++; if(p2Score === winningScore){ p2Display.classList.add("winner"); gameOver = true; } p2Display.textContent = p2Score; } }); resetButton.addEventListener("click", function(){ reset(); }); function reset(){ p1Score = 0; p2Score = 0; p1Display.textContent = 0; p2Display.textContent = 0; //重製CSS狀態 p1Display.classList.remove("winner"); p2Display.classList.remove("winner"); gameOver = false; } //change屬性:當內容變更才會有反應 numInput.addEventListener("change", function(){ //使用this只接受這個事件的輸入 winningScoreDisplay.textContent = this.value; winningScore = Number(this.value); reset(); }); ``` ```CSS .winner { color:green; } ``` ### 成品 ![](https://i.imgur.com/DpRTqWT.gif) ## Todo ### 結構 ```HTML <!DOCTYPE html> <html> <head> <title>Todo List Demo</title> <link rel="stylesheet" type="text/css" href="todos.css"> </head> <body> <ul> <li>Wash Cat</li> <li>Feed Cat</li> <li>Feed Cat to Dog</li> </ul> <script type="text/javascript" src="todos.js"></script> </body> </html> ``` ```javascript var lis = document.querySelectorAll("li"); for(var i = 0; i < lis.length; i++){ //mouseover當鼠標指向目標 lis[i].addEventListener("mouseover", function(){ //加入selected CSS類型 this.classList.add("selected"); }); //mouseout當鼠標離開目標 lis[i].addEventListener("mouseout", function(){ //重製selected CSS類 this.classList.remove("selected"); }); lis[i].addEventListener("click", function(){ this.classList.toggle("done"); }); } ``` ```CSS .done { text-decoration: line-through; opacity: 0.5; } .selected { color: green; } ``` ### 成品 ![](https://i.imgur.com/eVjrvNs.gif) ## colorGame ### 結構 ```HTML <!DOCTYPE html> <html> <head> <title>Color Game</title> <link rel="stylesheet" type="text/css" href="colorGame.css"> </head> <body> <h1> The Great <br> <span id="colorDisplay">RGB</span> <br> Color Game </h1> <div id="stripe"> <button id="reset">New Colors</button> <span id="message"></span> <button class="mode">Easy</button> <button class="mode selected">Hard</button> </div> <div id="container"> <div class="square"></div> <div class="square"></div> <div class="square"></div> <div class="square"></div> <div class="square"></div> <div class="square"></div> </div> <script type="text/javascript" src="colorGame.js"></script> </body> </html> ``` ```CSS body { background-color: #232323; margin: 0; font-family: "Montserrat", "Avenir"; } .square { width: 30%; background: purple; padding-bottom: 30%; float: left; margin: 1.66%; border-radius: 15%; transition: background 0.6s; -webkit-transition: background 0.6s; -moz-transition: background 0.6s; } #container { margin: 20px auto; max-width: 600px; } h1 { text-align: center; line-height: 1.1; font-weight: normal; color: white; background: steelblue; margin: 0; text-transform: uppercase; padding: 20px 0; } #colorDisplay { font-size: 200%; } #message { display: inline-block; width: 20%; } #stripe { background: white; height: 30px; text-align: center; color: black; } .selected { color: white; background: steelblue; } button { border: none; background: none; text-transform: uppercase; height: 100%; font-weight: 700; color: steelblue; letter-spacing: 1px; font-size: inherit; transition: all 0.3s; -webkit-transition: all 0.3s; -moz-transition: all 0.3s; outline: none; } button:hover { color: white; background: steelblue; } ``` ```javascript var numSquares = 6; var colors = []; var pickedColor; var squares = document.querySelectorAll(".square"); var colorDisplay = document.getElementById("colorDisplay"); var messageDisplay = document.querySelector("#message"); var h1 = document.querySelector("h1"); var resetButton = document.querySelector("#reset"); var modeButtons = document.querySelectorAll(".mode"); init(); function init(){ setupModeButtons(); setupSquares(); reset(); } function setupModeButtons(){ for(var i = 0; i < modeButtons.length; i++){ modeButtons[i].addEventListener("click", function(){ modeButtons[0].classList.remove("selected"); modeButtons[1].classList.remove("selected"); this.classList.add("selected"); this.textContent === "Easy" ? numSquares = 3: numSquares = 6; reset(); }); } } function setupSquares(){ for(var i = 0; i < squares.length; i++){ //add click listeners to squares squares[i].addEventListener("click", function(){ //讓clickedColor變成現在所選的方塊顏色 var clickedColor = this.style.background; //compare color to pickedColor //如果選的顏色跟答案相同 if(clickedColor === pickedColor){ messageDisplay.textContent = "Correct!"; resetButton.textContent = "Play Again?" changeColors(clickedColor); h1.style.background = clickedColor; } else { //錯誤的話就將該方塊變成背景色 this.style.background = "#232323"; messageDisplay.textContent = "Try Again" } }); } } function reset(){ colors = generateRandomColors(numSquares); //pick a new random color from array pickedColor = pickColor(); //change colorDisplay to match picked Color colorDisplay.textContent = pickedColor; resetButton.textContent = "New Colors" messageDisplay.textContent = ""; //change colors of squares for(var i = 0; i < squares.length; i++){ if(colors[i]){ squares[i].style.display = "block" squares[i].style.background = colors[i]; } else { squares[i].style.display = "none"; } } h1.style.background = "steelblue"; } resetButton.addEventListener("click", function(){ reset(); }) //讓所有方塊顏色變成選中的顏色 function changeColors(color){ //loop through all squares for(var i = 0; i < squares.length; i++){ //change each color to match given color squares[i].style.background = color; } } function pickColor(){ var random = Math.floor(Math.random() * colors.length); return colors[random]; } //隨機產生顏色 function generateRandomColors(num){ //make an array var arr = [] //repeat num times for(var i = 0; i < num; i++){ //get random color and push into arr arr.push(randomColor()) } //return that array return arr; } //隨機顏色 function randomColor(){ //pick a "red" from 0 - 255 var r = Math.floor(Math.random() * 256); //pick a "green" from 0 -255 var g = Math.floor(Math.random() * 256); //pick a "blue" from 0 -255 var b = Math.floor(Math.random() * 256); return "rgb(" + r + ", " + g + ", " + b + ")"; } ``` ### 成品 ![](https://i.imgur.com/7zZKTqP.gif) ![](https://i.imgur.com/5MDJzLD.gif) # JQuery ## To-Do List ### 結構 ```HTML <!DOCTYPE html> <html> <head> <title>Todo List</title> <link rel="stylesheet" type="text/css" href="todoslist.css"> <link href='https://fonts.googleapis.com/css?family=Roboto:400,700,500' rel='stylesheet' type='text/css'> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.css"> <script type="text/javascript" src="jquery-2.1.4.min.js"></script> </head> <body> <div id="container"> <h1>To-Do List</h1> <input type="text" placeholder="Add New Todo"> <ul> <li><span>X</span> Go To Potions Class</li> <li><span>X</span> Buy New Robes</li> <li><span>X</span> Visit Hagrid</li> </ul> </div> <script type="text/javascript" src="todoslist.js"></script> </body> </html> ``` ```CSS #container { width: 360px; margin: 0 auto; border: 2px solid; } .completed { color: gray; text-decoration: line-through; } ``` ```javascript //on適用於當前以及未來的元素 //監聽ul裡面的li //如果只使用click之後新增的元素就不會被監聽 $("ul").on("click","li", function(){ $(this).toggleClass("completed"); }); $("ul").on("click", "span", function(event){ //.parent()父元素 //指向span標籤的父元素做出淡出效果 $(this).parent().fadeOut(500,function(){ //延遲500毫秒後再做動作 //對現在指向的物件做刪除 $(this).remove(); }); //event.stopPropagation阻止click事件冒泡到父元素 //也就是說當我典籍span的內容時他不會觸發除了span標籤以外的事件 event.stopPropagation(); }) //將input的輸入型態都轉成text //keypress只針對能夠輸出文字符號的按鍵有效如ESC這種是無效的 //keydown的話就是只要是鍵盤案下的瞬間無論任何按鍵都能取得對應的鍵盤代碼 //keyup功能與keydown相同只是觸發時間是在放開鍵盤的瞬間所以不會連續觸發 $("input[type='text']").keypress(function(event){ //event.which回傳該事件下哪個按鍵被按下 if(event.which === 13){ //取得輸入的資料 var todotext = $(this).val(); $(this).val(""); //.append()被選中的元素結尾插入指定內容 $("ul").append("<li><span>X</span>" + todotext + "</li>"); } }) ``` ### 成品 ![](https://i.imgur.com/rDrmXsG.gif) ## To-Do List改良 ### 結構 ```HTML <!DOCTYPE html> <html> <head> <title>Todo List</title> <link rel="stylesheet" type="text/css" href="todoslist.css"> <link href='https://fonts.googleapis.com/css?family=Roboto:400,700,500' rel='stylesheet' type='text/css'> <link rel="stylesheet" type="text/css" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.4.0/css/font-awesome.css"> <script type="text/javascript" src="jquery-2.1.4.min.js"></script> </head> <body> <div id="container"> <h1>To-Do List <i class="fa fa-plus"></i></h1> <input type="text" placeholder="Add New Todo"> <ul> <li><span><i class="fa fa-trash"></i></span> Go To Potions Class</li> <li><span><i class="fa fa-trash"></i></span> Buy New Robes</li> <li><span><i class="fa fa-trash"></i></span> Visit Hagrid</li> </ul> </div> <script type="text/javascript" src="todoslist.js"></script> </body> </html> ``` ```CSS h1 { background: #2980b9; color: white; margin: 0; padding: 10px 20px; text-transform: uppercase; font-size: 24px; font-weight: normal; } ul { list-style: none; margin: 0; padding: 0; } .fa-plus { float: right; } body { font-family: Roboto; background: -webkit-linear-gradient(90deg, #2BC0E4 10%, #EAECC6 90%); /* Chrome 10+, Saf5.1+ */ background: -moz-linear-gradient(90deg, #2BC0E4 10%, #EAECC6 90%); /* FF3.6+ */ background: -ms-linear-gradient(90deg, #2BC0E4 10%, #EAECC6 90%); /* IE10 */ background: -o-linear-gradient(90deg, #2BC0E4 10%, #EAECC6 90%); /* Opera 11.10+ */ background: linear-gradient(90deg, #2BC0E4 10%, #EAECC6 90%); /* W3C */ } li { background: #fff; height: 40px; /*設定行高*/ line-height: 40px; color: #666; } /*nth-child(2n)選擇li這個表格的第2個換顏色*/ li:nth-child(2n){ background: #f7f7f7; } span { background: #e74c3c; height: 40px; margin-right: 20px; text-align: center; color: white; width: 0; /*display: inline-block填滿空間*/ display: inline-block; /*做0.2秒的線性轉場*/ transition: 0.2s linear; /*元素透明度*/ opacity: 0; } /*:hover屬性就是當滑鼠移至某元件時某元件該如何反應*/ li:hover span { width: 40px; opacity: 1.0; } input { font-size: 18px; color: #2980b9; background-color: #f7f7f7; width: 100%; padding: 13px 13px 13px 20px; /*自動調整填充padding*/ box-sizing: border-box; border: 3px solid rgba(0,0,0,0); } input:focus{ background: #fff; border: 3px solid #2980b9; } #container { width: 360px; margin: 100px auto; background: #f7f7f7; box-shadow: 0 0 3px rgba(0,0,0,0.1); } .completed { color: gray; text-decoration: line-through; } ``` ```javascript //on適用於當前以及未來的元素 //監聽ul裡面的li //如果只使用click之後新增的元素就不會被監聽 $("ul").on("click","li", function(){ //切換css類別 $(this).toggleClass("completed"); }); $("ul").on("click", "span", function(event){ //.parent()父元素 //指向span標籤的父元素做出淡出效果 $(this).parent().fadeOut(500,function(){ //延遲500毫秒後再做動作 //對現在指向的物件做刪除 $(this).remove(); }); //event.stopPropagation阻止click事件冒泡到父元素 //也就是說當我典籍span的內容時他不會觸發除了span標籤以外的事件 event.stopPropagation(); }) //將input的輸入型態都轉成text //keypress只針對能夠輸出文字符號的按鍵有效如ESC這種是無效的 //keydown的話就是只要是鍵盤案下的瞬間無論任何按鍵都能取得對應的鍵盤代碼 //keyup功能與keydown相同只是觸發時間是在放開鍵盤的瞬間所以不會連續觸發 $("input[type='text']").keypress(function(event){ //event.which回傳該事件下哪個按鍵被按下 if(event.which === 13){ //取得輸入的資料 var todotext = $(this).val(); $(this).val(""); //.append()被選中的元素結尾插入指定內容 $("ul").append("<li><span><i class='fa fa-trash'></i></span>" + todotext + "</li>"); } }) $(".fa-plus").click(function(){ //fadeToggle淡出動畫切換 $("input[type='text']").fadeToggle(); }); ``` ### 成品 ![](https://i.imgur.com/gKS2THk.gif) # Paperjs ## Exercise ### 結構 ```HTML <!DOCTYPE html> <html> <head> <title>Circles</title> <script type="text/javascript" src="paper-full.js"></script> <link rel="stylesheet" type="text/css" href="circles.css"> <script type="text/paperscript" canvas="myCanvas"> for(var x = 0; x < 1000; x+=100){ for(var y = 0; y < 1000; y+=100){ //new Point(x,0),10)設定point的x座標以及y座標還有圓半徑 new Path.Circle(new Point(x,y),10).fillColor = "purple"; } } </script> </head> <body> <canvas id="myCanvas" resize></canvas> </body> </html> ``` ```CSS canvas { width: 100%; height: 100%; background: black; } body, html { height: 100%; margin: 0; } ``` * JS內容就是使用Paper.js內的物件 * ### 成品 ![](https://i.imgur.com/oX4MFs4.png) ## circle ### 結構 ```html <!DOCTYPE html> <html> <head> <title>Circles</title> <script type="text/javascript" src="paper-full.js"></script> <link rel="stylesheet" type="text/css" href="circles.css"> <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/howler/1.1.28/howler.js"></script> <script type="text/paperscript" canvas="myCanvas"> //建立keyData物件 var keyData = { q: { //new一個Howl的物件 sound: new Howl({ urls: ['sounds/bubbles.mp3'] }), color: '#1abc9c' }, w: { sound: new Howl({ urls: ['sounds/clay.mp3'] }), color: '#2ecc71' }, e: { sound: new Howl({ urls: ['sounds/confetti.mp3'] }), color: '#3498db' }, r: { sound: new Howl({ urls: ['sounds/corona.mp3'] }), color: '#9b59b6' }, t: { sound: new Howl({ urls: ['sounds/dotted-spiral.mp3'] }), color: '#34495e' }, y: { sound: new Howl({ urls: ['sounds/flash-1.mp3'] }), color: '#16a085' }, u: { sound: new Howl({ urls: ['sounds/flash-2.mp3'] }), color: '#27ae60' }, i: { sound: new Howl({ urls: ['sounds/flash-3.mp3'] }), color: '#2980b9' }, o: { sound: new Howl({ urls: ['sounds/glimmer.mp3'] }), color: '#8e44ad' }, p: { sound: new Howl({ urls: ['sounds/moon.mp3'] }), color: '#2c3e50' }, a: { sound: new Howl({ urls: ['sounds/pinwheel.mp3'] }), color: '#f1c40f' }, s: { sound: new Howl({ urls: ['sounds/piston-1.mp3'] }), color: '#e67e22' }, d: { sound: new Howl({ urls: ['sounds/piston-2.mp3'] }), color: '#e74c3c' }, f: { sound: new Howl({ urls: ['sounds/prism-1.mp3'] }), color: '#95a5a6' }, g: { sound: new Howl({ urls: ['sounds/prism-2.mp3'] }), color: '#f39c12' }, h: { sound: new Howl({ urls: ['sounds/prism-3.mp3'] }), color: '#d35400' }, j: { sound: new Howl({ urls: ['sounds/splits.mp3'] }), color: '#1abc9c' }, k: { sound: new Howl({ urls: ['sounds/squiggle.mp3'] }), color: '#2ecc71' }, l: { sound: new Howl({ urls: ['sounds/strike.mp3'] }), color: '#3498db' }, z: { sound: new Howl({ urls: ['sounds/suspension.mp3'] }), color: '#9b59b6' }, x: { sound: new Howl({ urls: ['sounds/timer.mp3'] }), color: '#34495e' }, c: { sound: new Howl({ urls: ['sounds/ufo.mp3'] }), color: '#16a085' }, v: { sound: new Howl({ urls: ['sounds/veil.mp3'] }), color: '#27ae60' }, b: { sound: new Howl({ urls: ['sounds/wipe.mp3'] }), color: '#2980b9' }, n: { sound: new Howl({ urls: ['sounds/zig-zag.mp3'] }), color: '#8e44ad' }, m: { sound: new Howl({ urls: ['sounds/moon.mp3'] }), color: '#2c3e50' } } var circles = [] //onKeyDown當鍵盤按下就執行... //這是內建在paper.js下的方程式 function onKeyDown(event){ //建立視窗最邊緣的點 var maxPoint = new Point(view.size.width, view.size.height); //建立一個隨機座標 var randomPoint = Point.random(); //將最大座標與隨機座標相乘得到在範圍內隨機座標 var point = maxPoint * randomPoint; //設定newCircle為隨機座標半徑為10的圓 var newCircle = new Path.Circle(point,500) //對keyData物件裡面的按鍵顏色做改變 newCircle.fillColor = keyData[event.key].color //播放keyData物件裡的音樂 keyData[event.key].sound.play(); //將newCircle加進circles陣列裡面 circles.push(newCircle); } //在座標300,300的地方顯示一個半徑100的圓型顏色為紅色 var animatedCircle = new Path.Circle(new Point(300,300), 100); animatedCircle.fillColor = "red"; //onFrame每偵執行 function onFrame(event){ for(var i = 0; i < circles.length; i++){ //更改顏色 circles[i].fillColor.hue += 1; //設定圓的縮小速度為.9 circles[i].scale(.9) } } </script> </head> <body> <canvas id="myCanvas" resize></canvas> </body> </html> ``` ```css canvas { width: 100%; height: 100%; background: black; } body, html { height: 100%; margin: 0; } ``` * js文黨的部分是引用paper.js裡面下載的paper-full.js * ### 成品 * GIF無聲音內容實際有聲 * ![](https://i.imgur.com/TLHVtDI.gif) # Node.Js ## Express * 使用前要先安裝Express模組 * ### 結構 ```javascript //這是在Node.js裡的物件 //使用require功能取得express物件 var express = require("express"); var app = express(); //使用get請求 req == require, res == response app.get("/", function(req, res){ res.send("Hi there"); }); //process.env.PORT讀取當前目錄下的PORT app.listen(process.env.PORT, process.env.IP, function(){ console.log("Server gas started!!") }); //res.send伺服器端將資料返回到用戶端 app.get("/dog", function(req, res){ console.log("SOMEONE MADE A REQUEST TO /DOGE!!!") res.send("MEOW"); }); app.get("/bye", function(req, res){ res.send("Goodbye!!"); }); //加入":"讓她變成一個變量這樣就不是固定位置 app.get("/r/:subredditName/comments/:id/:title/", function(req, res){ res.send("WELCOME TO THE COMMENT PAGE!"); }); app.get("/r/:subredditName", function(req, res){ //req.params將命名過的參數以字串的形式存放 var subreddit = req.params.subredditName //.toUpperCase將字變成大寫 res.send("WELCOME TO THE !" + subreddit.toUpperCase() + " SUBREDDIT"); }); ``` ### 成品 ![](https://i.imgur.com/kUPKXzj.gif) ## Express作業 ### 結構 ```javascript var express = require("express"); var app = express(); app.get("/", function(req, res){ res.send("Hi there, welcome to my assignmenti!"); }); app.listen(process.env.PORT, process.env.IP, function(){ console.log("Server gas started!!") }); app.get("/spseak/:animal", function(req, res){ //建立sounds物件 var sounds = { pig: "Oink", cow: "Moo", dog: "Woof Woof!", cat: "I haave you human", goldfish: "..." }; //toLowerCase轉換成小寫 var animal = req.params.animal.toLowerCase(); var sound = sounds[animal]; res.send("The " + animal + " says " + sound); }); app.get("/repeat/:message/:times", function(req, res){ var message = req.params.message; //將他數字化 var times = Number(req.params.times); var result = ""; for(let i = 0; i < times; i++){ result += message + " "; } res.send(result); }); //"*"將不存在的路徑導向這裡 app.get("*", function(req, res){ res.send("Sorry ,page not found...What are you doing wuth your life?") }); ``` ### 成品 ![](https://i.imgur.com/DphylwN.gif) # EJS * EJS 的全名是「Embedded Javascript」,顧名思義就是內嵌式的樣板引擎,可以將邏輯與內容直接嵌入到 HTML 頁面上,也就是 EJS 可以讓我們利用 JavaScript 生成 HTML 頁面 。而 EJS 學習上相對簡單,因為它沒有如何組織内容的教條;也没有再造一套迭代和控制流語法。我們只要本身會 HTML 和 JavaScript 即可上手! * - 在使用EJS以及EXPRESS之前都要先安裝相關的檔案 - npm install express --save - npm install ejs --save ## EJS範例 ### 結構 ```javascript var express = require("express"); var app = express(); app.get("/", function(req, res){ res.render("home.ejs"); }) app.get("/fallinlovewith/:thing", function(req, res){ var thing = req.params.thing; //將views裡面的love.ejs的thing存放這裡的thing的資料 res.render("love.ejs", {thing: thing}); }) app.listen(process.env.PORT, process.env.IP, function(){ console.log("Server is listening!!!"); }); ``` ```ejs <h1>This is the Home page!!</h1> ``` ```ejs <!--<%= %>被它包含地被視為javascript--> <!--接收app.js的資料--> <h1>You fell in love with: <%=thing.toUpperCase()%></h1> <p>P.S. this is the love.ejs</p> ``` ### 成品 ![](https://i.imgur.com/QgnsS0Q.gif) ## Post ## 結構 ```javascript var express = require("express"); var app = express(); app.get("/", function(req, res){ res.render("home.ejs"); }) app.get("/fallinlovewith/:thing", function(req, res){ var thing = req.params.thing; //將views裡面的love.ejs的thing存放這裡的thing的資料 res.render("love.ejs", {thing: thing}); }) app.get("/post", function(req, res){ var posts = [ {title: "Post 1", author: "Susy"}, {title: "My adorable pet bunny", author: "Charlie"}, {title: "Can you believe this pomsky?", author: "Colt"}, ] res.render("posts.ejs", {posts: posts}); }) app.listen(process.env.PORT, process.env.IP, function(){ console.log("Server is listening!!!"); }); ``` ```EJS <!--<%= %>被它包含地被視為javascript--> <!--接收app.js的資料--> <h1>You fell in love with: <%=thing.toUpperCase()%></h1> <!--<%= %>是將裡面的js內容直接傳回到html 但是如果只是要做邏輯指令就不要加等於改成<% %>--> <%if(thing.toLowerCase() === "rusty"){ %> <p>GOOD CHICE! RUSTY IS THE BEST!</p> <% } else { %> <p>Bad choice! You should have said Rusty!</p> <% } %> <p>P.S. this is the love.ejs</p> ``` ```EJS <h1>The Posts Page</h1> <% for(var i = 0; i < posts.length; i++){%> <li><%= posts[i].title %> - <strong><%= posts[i].author %></strong></li> <% } %> <% posts.forEach(function(post){ %> <li><%= post.title %> - <strong><%= post.author %></strong></li> <% }) %> ``` ### 成品 ![](https://i.imgur.com/yK0bfHm.gif) ## 練習 ### 結構 **app.js** ```javascript var express = require("express"); var app = express(); //app.use傳遞一個包含靜態資源的目錄給express.static //也就是說在public目錄下的檔案都可以使用 app.use(express.static("public")); //宣告view engine的模板庫為ejs //當設定好了之後我在eres.render就可以直接輸出檔名不用加.ejs app.set('view engine', 'ejs'); app.get("/", function(req, res){ res.render("home"); }) app.get("/fallinlovewith/:thing", function(req, res){ var thing = req.params.thing; //將views裡面的love.ejs的thing存放這裡的thing的資料 res.render("love", {thing: thing}); }) app.get("/post", function(req, res){ var posts = [ {title: "Post 1", author: "Susy"}, {title: "My adorable pet bunny", author: "Charlie"}, {title: "Can you believe this pomsky?", author: "Colt"}, ] res.render("posts", {posts: posts}); }) app.listen(process.env.PORT, process.env.IP, function(){ console.log("Server is listening!!!"); }); ``` * home.js ```ejs <link rel="stylesheet" href="app.css"> <h1>This is the Home page!!</h1> ``` * love.js ```ejs <link rel="stylesheet" href="/app.css"> <!--<%= %>被它包含地被視為javascript--> <!--接收app.js的資料--> <h1>You fell in love with: <%=thing.toUpperCase()%></h1> <!--<%= %>是將裡面的js內容直接傳回到html 但是如果只是要做邏輯指令就不要加等於改成<% %>--> <%if(thing.toLowerCase() === "rusty"){ %> <p>GOOD CHICE! RUSTY IS THE BEST!</p> <% } else { %> <p>Bad choice! You should have said Rusty!</p> <% } %> <p>P.S. this is the love.ejs</p> ``` * post.js ```ejs <link rel="stylesheet" href="/app.css"> <h1>The Posts Page</h1> <% for(var i = 0; i < posts.length; i++){%> <li><%= posts[i].title %> - <strong><%= posts[i].author %></strong></li> <% } %> <% posts.forEach(function(post){ %> <li><%= post.title %> - <strong><%= post.author %></strong></li> <% }) %> ``` * app.css ```css body { background: yellow; color: purple; } ``` ### 成品 ![](https://i.imgur.com/mjaB8et.gif) ## 作業二 ### 結構 * app.js ```javascript var express = require("express"); var app = express(); //body-parser主要是對post請求解析 var bodyParser = require('body-parser'); //bodyParser.urlencoded用來解析req.body的數據 //通常是用來解析from表單的數據 //如果設置為false那麼對URL-encoded的數據解析將採用querystring //如果設置為true那麼採用qs庫允許將父對象和數組編碼為url編碼格式允許使用url編碼的json體驗 app.use(bodyParser.urlencoded({ extended: true })); app.set("view engine", "ejs"); var friends = ["Tony", "Miranda", "Justin", "Pierre", "Lily"]; app.get("/", function(req, res){ res.render("home"); }); app.post("/addfriend", function(req, res){ var newFriend = req.body.newfriend; friends.push(newFriend); res.redirect("/friends"); }); app.get("/friends", function(req, res){ res.render("friends", {friends: friends}); }); app.listen(process.env.PORT, process.env.IP, function(){ console.log("Server is listening!!!"); }); ``` * friends.ejs ```ejs <h1>Friends List Goes Here!</h1> <% friends.forEach(function(friend){%> <li><%= friend %></li> <% }); %> <form method="POST" action="/addfriend" > <input type="text" name="newfriend" placeholder="name"> <button>I made a new friend!"</button> </form> ``` * home.ejs ```ejs <h1>HOME PAGE!!</h1> ``` ### 成品 ![](https://i.imgur.com/5SuU9GF.gif) * 如果要POST請求BODY裡面的內容必須先在commendline輸入npm install body-parser --save 安裝body-parser套件 ## YelpCarmp ### 結構 - app.js ```javascript var express = require("express"); var app = express(); app.set("view engine", "ejs"); app.get("/", function(req, res){ res.render("landing"); }); app.get("/campgrounds", function(req, res){ var campgrounds = [ {name: "Salmon Creek", image:"https://s3-ap-northeast-1.amazonaws.com/thegate/2019/06/13/17/29/28/Shima-onsen-lake-okushima-Top.jpg"}, {name: "Granite Hill", image:"https://e.share.photo.xuite.net/winnie199064/1ec093a/11600393/545581617_m.jpg"}, {name: "Mountain Goat's Rest", image:"https://pic.pimg.tw/jay7134/1484674030-1921788632.jpg"} ] res.render("campgrounds", {campgrounds:campgrounds}); }); app.listen(process.env.PORT, process.env.IP, function(){ console.log("The YelpCamp Sever Has Started!"); }); ``` - landion.ejs ```html <h1>Landing Page!</h1> <p>Welcome to YelpCamp</p> <a href="/campgrounds">View All Campgrounds</a> ``` - campgrounds.ejs ```ejs <h1>This is the camprounds page!</h1> <% campgrounds.forEach(function(campground){ %> <div> <h4><%= campground.name %></h4> <!--這邊的圖片可以直接使用建立的物件這樣就不用一個一個貼圖片網址--> <img src="<%= campground.image %>"> </div> <% }); %> ``` ### 成品 {%youtube WF24xHGLmG4 %} ## YelpCarmp2 ### 結構 * app.js ```javascript var express = require("express"); var app = express(); var bodyParser = require("body-parser"); var campgrounds = [ {name: "Salmon Creek", image:"https://s3-ap-northeast-1.amazonaws.com/thegate/2019/06/13/17/29/28/Shima-onsen-lake-okushima-Top.jpg"}, {name: "Granite Hill", image:"https://e.share.photo.xuite.net/winnie199064/1ec093a/11600393/545581617_m.jpg"}, {name: "Mountain Goat's Rest", image:"https://pic.pimg.tw/jay7134/1484674030-1921788632.jpg"} ] app.use(bodyParser.urlencoded({extended: true})); app.set("view engine", "ejs"); app.get("/", function(req, res){ res.render("landing"); }); app.get("/campgrounds", function(req, res){ res.render("campgrounds", {campgrounds:campgrounds}); }); //對campground發送一個POST請求 app.post("/campgrounds", function(req, res){ //接收new.ejs所傳送出來的資料 var name = req.body.name; var image = req.body.image; var newCampground = {name: name, image: image} //將newCampground物件的東西推進新增到campgrounds物件裡 campgrounds.push(newCampground); //重新轉向 res.redirect("/campgrounds"); }); //執行new.ejs的動作內容 app.get("/campgrounds/new", function(req, res){ res.render("new.ejs"); }); app.listen(process.env.PORT, process.env.IP, function(){ console.log("The YelpCamp Sever Has Started!"); }); ``` * landion.ejs ```ejs <!--影片中的include語法是舊版的語法--> <!--現在新版的include方法是下面這種--> <%- include ('partials/header'); %> <h1>Landing Page!</h1> <p>Welcome to YelpCamp</p> <a href="/campgrounds">View All Campgrounds</a> <%- include ('partials/footer') ;%> ``` * campgrounds.ejs ```ejs <!--影片中的include語法是舊版的語法--> <!--現在新版的include方法是下面這種--> <%- include ('partials/header'); %> <h1>This is the camprounds page!</h1> <a href="/campgrounds/new">Add New Campground</a> <% campgrounds.forEach(function(campground){ %> <div> <h4><%= campground.name %></h4> <!--這邊的圖片可以直接使用建立的物件這樣就不用一個一個貼圖片網址--> <img src="<%= campground.image %>"> </div> <% }); %> <%- include ('partials/footer') ;%> ``` * new.ejs ```ejs <!--影片中的include語法是舊版的語法--> <!--現在新版的include方法是下面這種--> <%- include ('partials/header'); %> <h1>Create a New Campground</h1> <!--對campgrounds執行POST請求--> <form action="/campgrounds" method= "POST"> <input type="text" name="name"placeholder= "name"> <input type="text" name= "image"placeholder= "imge url"> <button>Submit!</button> </form> <a href="/campgrounds">Go Back</a> <%- include ('partials/footer') ;%> ``` ### 成品 {%youtube WF24xHGLmG4 %} ## YelpCarmp美化 ### 結構 **app.js** ```javascript var express = require("express"); var app = express(); var bodyParser = require("body-parser"); var campgrounds = [ {name: "Salmon Creek", image:"https://s3-ap-northeast-1.amazonaws.com/thegate/2019/06/13/17/29/28/Shima-onsen-lake-okushima-Top.jpg"}, {name: "Granite Hill", image:"https://e.share.photo.xuite.net/winnie199064/1ec093a/11600393/545581617_m.jpg"}, {name: "Mountain Goat's Rest", image:"https://pic.pimg.tw/jay7134/1484674030-1921788632.jpg"}, {name: "Salmon Creek", image:"https://s3-ap-northeast-1.amazonaws.com/thegate/2019/06/13/17/29/28/Shima-onsen-lake-okushima-Top.jpg"}, {name: "Granite Hill", image:"https://e.share.photo.xuite.net/winnie199064/1ec093a/11600393/545581617_m.jpg"}, {name: "Mountain Goat's Rest", image:"https://pic.pimg.tw/jay7134/1484674030-1921788632.jpg"}, {name: "Salmon Creek", image:"https://s3-ap-northeast-1.amazonaws.com/thegate/2019/06/13/17/29/28/Shima-onsen-lake-okushima-Top.jpg"}, {name: "Granite Hill", image:"https://e.share.photo.xuite.net/winnie199064/1ec093a/11600393/545581617_m.jpg"}, {name: "Mountain Goat's Rest", image:"https://pic.pimg.tw/jay7134/1484674030-1921788632.jpg"} ] app.use(bodyParser.urlencoded({extended: true})); app.set("view engine", "ejs"); app.get("/", function(req, res){ res.render("landing"); }); app.get("/campgrounds", function(req, res){ res.render("campgrounds", {campgrounds:campgrounds}); }); //對campground發送一個POST請求 app.post("/campgrounds", function(req, res){ //接收new.ejs所傳送出來的資料 var name = req.body.name; var image = req.body.image; var newCampground = {name: name, image: image} //將newCampground物件的東西推進新增到campgrounds物件裡 campgrounds.push(newCampground); //重新轉向 res.redirect("/campgrounds"); }); //執行new.ejs的動作內容 app.get("/campgrounds/new", function(req, res){ res.render("new.ejs"); }); app.listen(process.env.PORT, process.env.IP, function(){ console.log("The YelpCamp Sever Has Started!"); }); ``` **landion.ejs** ```ejs <!--影片中的include語法是舊版的語法--> <!--現在新版的include方法是下面這種--> <%- include ('partials/header'); %> <h1>Landing Page!</h1> <p>Welcome to YelpCamp</p> <a href="/campgrounds">View All Campgrounds</a> <%- include ('partials/footer') ;%> ``` **campgrounds.ejs** ```ejs <!--影片中的include語法是舊版的語法--> <!--現在新版的include方法是下面這種--> <%- include ('partials/header'); %> <div class="containter"> <header class="jumbotron"> <div class="container"> <h1>Welcome To YelpCamp</h1> <p>View our hand-picked campground from all over the world</p> <p> <a class="btn btn-primary btn-large" href="/campgrounds/new">Add New Campground</a> </p> </div> </header> <div class="row text-center" style="display:flex; flex-wrap: wrap;"> <% campgrounds.forEach(function(campground){ %> <div class="col-md-3 col-md-6"> <div class="thumbnail"> <div class="caption"> <h4><%= campground.name %></h4> </div> <!--這邊的圖片可以直接使用建立的物件這樣就不用一個一個貼圖片網址--> <img src="<%= campground.image %>"> </div> </div> <% }); %> </div> </div> <%- include ('partials/footer') ;%> ``` **new.ejs** ```ejs <!--影片中的include語法是舊版的語法--> <!--現在新版的include方法是下面這種--> <%- include ('partials/header'); %> <div class="container"> <div class="row"> <h1 style="text-align: center;">Create a New Campground</h1> <!--對campgrounds執行POST請求--> <div style="width: 30%; margin: 25px auto;"> <form action="/campgrounds" method= "POST"> <div class="form-group"> <input class="form-control" type="text" name="name"placeholder= "name"> </div> <div class="form-group"> <input class="form-control" type="text" name= "image"placeholder= "imge url"> </div> <div class="form-group"> <button class="btn btn-lg btn-primary btn-block">Submit!</button> </div> </form> <a href="/campgrounds">Go Back</a> </div> </div> </div> <%- include ('partials/footer') ;%> ``` **header.ejs** ```ejs <!DOCTYPE html> <html> <head> <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css"> <title>YelpCamp</title> </head> <body> <nav class="navbar navbar-default"> <div class="container-fluid"> <div class="navbar-header"> <a class="navbar-brand" href="/">YelpCamp</a> </div> <div class="collapse navbar-collapse"> <ul class="nav navbar-nav navbar-right"> <li><a href="/">Login</a></li> <li><a href="/">Sign Up</a></li> <li><a href="/">Logout</a></li> </ul> </div> </div> </nav> ``` **footer.ejs** ```ejs <p>TradeMark YelpCamp 2020</p> </body> </html> ``` ### 成品 **首頁** ![](https://i.imgur.com/Kb55kqc.png) **內容** ![](https://i.imgur.com/3JQeCTh.jpg) **新增頁** ![](https://i.imgur.com/AwvhjW4.png)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully