https://hackmd.io/@IMOK/Lab8
講師: 賴昱有
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!---
width=device-width 表示網頁的寬度應該等於設備的寬度。
確保網頁在不同設備上有適當的寬度。
initial-scale=1.0 表示初始的縮放比例為1.0。
這確保了網頁在載入時不進行縮放
--->
<title>15 Puzzle</title>
<link rel="stylesheet" href="15puzzle.css">
</head>
<body>
<div id="puzzle"></div>
<div id="controls">
<button id="solve">Solve</button>
<button id="scramble">Scramble</button>
</div>
<script src="script.js"></script>
</body>
</html>
<div>
<!-- 這裡可以包含其他HTML元素,如文本、圖片、表格等 -->
<p>This is a paragraph inside a div.</p>
<img src="example.jpg" alt="An example image">
</div>
經常作為CSS selector的容器,以便對特定區域設計樣式
定義每個文字的顏色、物件的外框、element 之間的距離,甚至撰寫動畫等等。
CSS語法重點:
1. selector 語法:用來指定 HTML 中,哪些 element 要套用這個樣式
2. 樣式描述:用來說明指定的 elements 要用什麼樣子去顯示
• Simple selectors (select elements based on name, id, class)
• Combinator selectors (select elements based on a specific relationship between them)
• Pseudo-class selectors (select elements based on a certain state)
• Pseudo-elements selectors (select and style a part of an element)
• Attribute selectors (select elements based on an attribute or attribute value)
• Element selector
• ID selector
• Class selector
• Grouping selector
• Universal selector
選擇的 element 名稱來設定該類 element 的顯示樣式
p {
color: yellow;
}
div {
height: 50px;
width: 60px;
}
幫 element 設定 id attribute ,再利用這個 id 來設定不同的顯示樣式
HTML:
<div id="block"></div>
CSS:
#block {
height: 50px;
width: 50px;
color: red;
}
在 css 中先定義好一個種類的樣式,
然後在HTML 中透過 class attribute 來選擇要使用哪一個種類的樣式顯示。
CSS:
.redBlock {
height: 50px;
width: 50px;
color: red;
}
HTML:
<div class="redBlock"></div>
group selector 的寫法可以省略重複的樣式定義。
p {
color: red;
}
input {
color: red;
}
div {
color: red;
}
p, input , div {
color: red;
}
對所有的 element 進行樣式定義。
* {
color: red;
}
• Content : element 內容所顯示的區域
• Padding : 位於外框 (Border) 與內容 (Content) 之間的空間
• Border : element 的邊框
• Margin : element 與 element 之間的空間
CSS 還可以做什麼呢?
https://www.w3schools.com/cssref/index.php
https://css-tricks.com/
/* pseudo-element */
::selection {background: transparent;}
p{margin: 0; font: 12px/150% Arial; text-align: center; color: #999;}
p a{color: #888;}
#controls{text-align: center;}
#controls button{
cursor: pointer; /*設置鼠標懸停在按鈕上時的鼠標樣式為手型*/
outline: none; /*去掉按鈕點擊時的默認輪廓線*/
padding: 10px 20px;
margin: 25px 2px;
border: 0;
border-radius: 4px;
background: #001F1F;
font: bold 14px Arial;
text-align: center;
text-transform: uppercase;
text-shadow: -1px -1px 0 rgba(0,0,0, 0.5);
color: #fff;
}
#controls button:hover{background: #003333;}
#puzzle{
position: relative;
width: 325px;
height: 325px;
margin: 0 auto;
margin-top: 80px;
border: 8px solid #001F1F;
border-radius: 4px;
}
#puzzle span{
position: absolute;
display: block;
width: 80px;
height: 80px;
border-radius: 4px;
}
#puzzle span.number{
cursor: pointer;
font: bold 36px/80px Arial;
text-align: center;
text-shadow: -1px -1px 0 rgba(0,0,0, 0.5);
color: #fff;
}
#puzzle span.empty{background: transparent;}
#puzzle span.number.light{background: #226666;}
#puzzle span.number.dark{background: #003333;}
#puzzle.animate span{
-webkit-transition: 0.15s left, 0.15s top;
transition: 0.15s left, 0.15s top; /*left、top 會在0.15s內被改變*/
/*-webkit-transition 用於支援WebKit(例如Chrome和Safari等)的瀏覽器*/
/*transition 則是標準的CSS3屬性*/
}
Javascript做了哪些事情?
1. 接收使用者的輸入內容
2. 根據輸入內容來做判斷
3. 將結果顯示在網頁上
function search_animal() {
let input = document.getElementById('searchbar').value
input=input.toLowerCase();
let x = document.getElementsByClassName('animals');
for (i = 0; i < x.length; i++) {
if (!x[i].innerHTML.toLowerCase().includes(input)) {
x[i].style.display="none";
}
else {
x[i].style.display="list-item";
}
}
}
function checkEnter(event) {
// 檢查是否按下的是 Enter 鍵
if (event.key === "Enter") {
search_animal();
}
}
<!DOCTYPE html>
<html>
<head>
<title>Hello Javascript</title>
<meta charset="utf-8">
<script>
console.log("Hello World");
/*使用瀏覽器打開.html,按下F12,選擇console*/
</script>
</head>
<body>
</body>
</html>
告訴電腦說,我要產生一個變數,並且給他一個名子,
讓我們之後可以根據這個名子找到他。
var x = 5;
var x = 1; //整 數(integer)
var y = 10.13; //浮 點 數(float)
var z = "Hello"; //字 串(String)
var p = true; //布 林 值 (Boolean)
var o = { firstName: 123 } //物 件 (object)
// = 這個符號,不是數學上的等於喔,他代表 Assignment
var x = 1;
x = x + 2;
console.log(x); // 3
x = x - 1;
console.log(x); // 2
x = x * 12;
console.log(x); // 24
x = x / 3;
console.log(x); // 8
x = x % 5; //取餘數
console.log(x); //3
這邊我們嘗試將字串進行串接 (+)
var str = "Hello";
var blank = " ";
var world = "World";
var helloWorld = str + blank + world;
console.log(helloWorld); //Hello World
撰寫flow chart可以幫助我們釐清流程,而撰寫程式與撰寫flow chart是相同的
在程式的流程中,主要影響正個流程的走向有兩種不同的語法,分別稱為 Condition 跟Loop。
最常用的判斷語法為 if 判斷句
if (grade > 60)
{
console.log("good");
}
else if (grade == 60)
{
console.log("safe")
}
else
{
console.log("nice to meet you.see you next year!");
}
• == (等於)
• != (不等於)
• > (大於)
• < (小於)
• >= (大於等於)
• <= (小於等於)
var day;
switch (new Date().getDay())
{
case 0:
day = "Sunday";
break;
case 1:
day = "Monday";
break;
case 2:
day = "Tuesday";
break;
case 3:
day = "Wednesday";
break;
case 4:
day = "Thursday";
break;
case 5:
day = "Friday";
break;
case 6:
day = "Saturday";
default:
day = "Unknown"; // 在這裡添加了 default,以處理未知的日期情況
}
console.log("Today is " + day);
var x = 1;
while(x <= 5)
{
console.log(x);
x = x + 1;
}
for(let i =1; i<=5 ;i++){
console.log(i)
}
接下來看看javascript要怎麼知道要怎麼知道使用者輸入了甚麼呢
在 HTML 中,當使用者使用鍵盤或是滑鼠對 element 進行操作的時候,
element 會發出一個訊號,這個訊號中會記錄了使用者正在對 element 進行甚麼樣的操作。
例如,當我們用滑鼠點擊 element ,他會發出一個訊號說使用者使用滑鼠左鍵進行點擊。
因此在獲取使用者的輸入之前,我們要先取得我們要關注的 Html element 。
在 Javascript 中,我們可以透過 Html Element 的 ID attribute 來取得 html 中的 element
HTML:
<div id="block" class="a"></div>
Javascript:
var x = document.getElementById("block");
console.log(x.id); //block
console.log(x.className); //a
<!--創建一個按鈕被點擊時輸出Click!!!-->
<!DOCTYPE html>
<html>
<head>
<title>addEventListener</title>
<meta charset="utf-8">
</head>
<body>
<input id="btn" type="button" value="Click!!!">
<script>
function clickHandler()
{
console.log("Click!!");
}
var button = document.getElementById("btn");
button.addEventListener("click", clickHandler , false);
</script>
</body>
</html>
Html 是直譯式語言,因此我們 getElementById 一
定要寫在要取得的 element 之後,這也是為什麼這邊的 script element 寫在 body 最後的原因。
透過 getElementById 取得 Html element 之後,我們可以透過他更改 element 的各種attriubte 以及 element content
<!DOCTYPE html>
<html>
<head>
<title>change element content</title>
<meta charset="utf-8">
</head>
<body>
<input id="btn" type="button" value="Click!!!">
<div id="board">
</div>
<script>
function clickHandler()
{
var board = document.getElementById("board");
board.innerHTML = "Click!!";
board.style = "color: red;";
}
var button = document.getElementById("btn");
button.addEventListener("click", clickHandler , false);
</script>
</body>
</html>
.id : 存取指定element的id。
.nodeName : 取得指定element的節點名稱,但是無法變更element。
.innerHTML : 取出指定element下所有的內容。
.textContent : 取出指定element下的content。
(function(){
var state = 1;
var puzzle = document.getElementById('puzzle');
// Creates solved puzzle
solve();
// Listens for click on puzzle cells
puzzle.addEventListener('click', function(e){
if(state == 1){
// Enables sliding animation
puzzle.className = 'animate';
shiftCell(e.target);
}
});
// Listens for click on control buttons
document.getElementById('solve').addEventListener('click', solve);
document.getElementById('scramble').addEventListener('click', scramble);
/*Creates solved puzzle*/
function solve(){
if(state == 0){
return;
}
puzzle.innerHTML = '';
var n = 1;
for(var i = 0; i <= 3; i++){
for(var j = 0; j <= 3; j++){
var cell = document.createElement('span');
cell.id = 'cell-'+i+'-'+j;
cell.style.left = (j*80+1*j+1)+'px';
cell.style.top = (i*80+1*i+1)+'px';
if(n <= 15){
cell.classList.add('number');
cell.classList.add((i%2==0 && j%2>0 || i%2>0 && j%2==0) ? 'dark' : 'light');
cell.innerHTML = (n++).toString();
} else {
cell.className = 'empty';
}
puzzle.appendChild(cell);
}
}
}
/*Shifts number cell to the empty cell*/
function shiftCell(cell){
// Checks if selected cell has number
if(cell.clasName != 'empty'){
// Tries to get empty adjacent cell
var emptyCell = getEmptyAdjacentCell(cell);
if(emptyCell){
// Temporary data
var tmp = {style: cell.style.cssText, id: cell.id};
// Exchanges id and style values
cell.style.cssText = emptyCell.style.cssText;
cell.id = emptyCell.id;
emptyCell.style.cssText = tmp.style;
emptyCell.id = tmp.id;
if(state == 1){
// Checks the order of numbers
setTimeout(checkOrder, 150);
}
}
}
}
/*Gets specific cell by row and column*/
function getCell(row, col){
return document.getElementById('cell-'+row+'-'+col);
}
/*Gets empty cell*/
function getEmptyCell(){
return puzzle.querySelector('.empty');
}
/*Gets empty adjacent cell if it exists*/
function getEmptyAdjacentCell(cell){
// Gets all adjacent cells
var adjacent = getAdjacentCells(cell);
// Searches for empty cell
for(var i = 0; i < adjacent.length; i++){
if(adjacent[i].className == 'empty'){
return adjacent[i];
}
}
// Empty adjacent cell was not found
return false;
}
/*Gets all adjacent cells*/
function getAdjacentCells(cell){
var id = cell.id.split('-');
// Gets cell position indexes
var row = parseInt(id[1]);
var col = parseInt(id[2]);
var adjacent = [];
// Gets all possible adjacent cells
if(row < 3){adjacent.push(getCell(row+1, col));}
if(row > 0){adjacent.push(getCell(row-1, col));}
if(col < 3){adjacent.push(getCell(row, col+1));}
if(col > 0){adjacent.push(getCell(row, col-1));}
return adjacent;
}
/*Chechs if the order of numbers is correct*/
function checkOrder(){
// Checks if the empty cell is in correct position
if(getCell(3, 3).className != 'empty'){
return;
}
var n = 1;
// Goes through all cells and checks numbers
for(var i = 0; i <= 3; i++){
for(var j = 0; j <= 3; j++){
if(n <= 15 && getCell(i, j).innerHTML != n.toString()){
// Order is not correct
return;
}
n++;
}
}
// Puzzle is solved, offers to scramble it
if(confirm('Congrats, You did it! \nScramble the puzzle?')){
scramble();
}
}
/*Scrambles puzzle*/
function scramble(){
if(state == 0){
return;
}
puzzle.removeAttribute('class');
state = 0;
var previousCell;
var i = 1;
var interval = setInterval(function(){
if(i <= 100){
var adjacent = getAdjacentCells(getEmptyCell());
if(previousCell){
for(var j = adjacent.length-1; j >= 0; j--){
if(adjacent[j].innerHTML == previousCell.innerHTML){
adjacent.splice(j, 1);
}
}
}
// Gets random adjacent cell and memorizes it for the next iteration
previousCell = adjacent[rand(0, adjacent.length-1)];
shiftCell(previousCell);
i++;
} else {
clearInterval(interval);
state = 1;
}
}, 5);
}
/*Generates random number*/
function rand(from, to){
return Math.floor(Math.random() * (to - from + 1)) + from;
}
}());
匿名函數or立即函數,這個語法的目的是在定義函數之後立即執行它。
(function() {
// 這裡是函數體,可以包含你想要執行的程式碼
}());
1.作用域隔離: 這個函數的所有變數和函數定義都將位於函數作用域內,不會污染全局作用域。
2.避免衝突: 在這個函數內,你可以使用相同的變數名稱而不擔心與全局作用域中的變數產生衝突。
使用至少4種simple selector美化自我介紹網頁
在我最喜歡的神奇寶貝頁面使用至少2個CSS box model
畫出flow chart並在自我介紹頁面,設計一個按鈕,content為九九乘法表真好玩,
並在script加入連結.js檔使用javascript於console顯示九九乘法表的計算結果
奇數從1乘到9,偶數從9乘到1,完成後換行,兩個計算結果之間需要使用空白作為間隔
(使用巢狀迴圈完成該要求)
於自我介紹頁面建立一個內部連接至新的分頁,另外選一隻神奇寶貝並加入退化、進化按鈕
點選進(退)化按鈕後由進化前型態變更為進(退)化後的資訊
需包含神奇寶貝名稱,圖片及數值表格(如Lab7所顯示資訊)
製作一個9 puzzle game(字體、字塊顏色不可和16puzzle範例相同)
並在自我介紹網頁建立作品集 內部連結連結至9puzzle game網頁