這個是第二版, 這次主要會變成帶實作(好像後面的課程就會取消這一塊了)
- [1] 問卷
- [1] Windows 下的編輯工具 5
- [1] HTML 影片 21mins + 練習
- [1] CSS 影片 40mins + 練習
- [1] BREAK
- [1] HTML & CSS 影片 15 mins + 練習
- [1] 3cschool/browser support HTML CSS
- [1] Github Page 使用 影片
- [1] 練習1: 將自我介紹的網頁建立到 Github Pages
- [1] 練習2: 加上img
- [1] BREAK
- [1] HTML/CSS ref
-
[1] 簡述前端 Roadmap
-
[2] colab 使用
- [2] HTTP 介紹 ref
- [2] JSON 介紹 ref
- [2] 建立 API service
- [2] BREAK
- [2] FastAPI 的介面使用
- [2] curl的安裝與使用 ref
- [2] POST/GET/PUT/DELETE sample
- [2] BREAK
- [2] 習作題目
- [2] BREAK
-
[2] 簡述後端 Roadmap
-
[2] Question: colab file access, google drive access 是否已經學過?
-
[3] Intro 影片 5mins + 練習
- [3] Variable/Operator 影片 28 mins + 練習 相等比較 運算子
- [3] ~~Chrome dev tool 的使用~~
- [3] Flow control 影片 15 mins + 練習
- [3] BREAK
- [3] Looping 影片 15 mins + 練習
- [3] Function 影片1 影片2 (20+14) + 練習 Scope
- [3] HTML DOM 影片 20 mins + 練習題目:
- [3] HTML Form 影片 30mins
- [3] JS 練習 身分證字號檢測, 答案
- [3] HTML Event handling 影片1 17mins 影片2 11 mins ref
- [3] BREAK
-
[3] XMLHTTPRequest 的使用 + JS的同步與非同步簡介 + python requests 的使用. XHR使用.
跟隨實做
CORS參考資料 -
[4] [練習] 利用fastapi 取出 腳踏車道, 來源 讓前端網頁可以讀取, 然後列出相關資訊(加上 Travellinginfo, Remarks, Bike_length)
- [4] BREAK
- [4] leaflet js lib 的使用
- [4] [練習] 建立web page 提供車道查詢, 並顯示在地圖上
- [4] [練習] 取出Route_XY作為路線繪製
- [4] BREAK
- [4] BootStrap 的使用
- [4] BREAK
- [4] telegram bot的建立以及使用
- [4] [練習] 利用 bootstrap 建立交易顧問 web page, 提供註冊查詢服務
- [4] [練習] 建立API service 註冊, 連線 telegram bot 提供查詢服務
參考資料
Smaple Code
- 建立 API service
- POST/GET/PUT/DELETE sample
- XMLHTTPRequest 的使用
- JS的同步與非同步
- BootStrap 的使用
- JS sample
建立 API service
利用 colab 建立 fastapi平台
code:
!pip install fastapi nest-asyncio pyngrok uvicorn python-multipart
from fastapi import FastAPI, UploadFile, File, Request
from fastapi.middleware.cors import CORSMiddleware
from datetime import datetime
from typing import Optional
from pydantic import BaseModel
local_customer = []
class Item(BaseModel):
name: str
description: Optional[str] = None
price: float
tax: Optional[float] = None
class Customer(BaseModel):
name: str
phone_number: Optional[str] = None
email: Optional[str] = None
bitcoin_asset: Optional[float] = 0
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_credentials=True,
allow_methods=['*'],
allow_headers=['*'],
)
@app.get("/customers/{customer_name}")
async def get_customer(customer_name):
if not customer_name:
return local_customer
for c in local_customer:
if c.name == customer_name:
return c
return {'status': 'no data'}
@app.post("/customers/")
async def add_customer(customer: Customer):
is_exist = False
for c in local_customer:
if c.name == customer.name:
is_exist = True
if not is_exist:
local_customer.append(customer)
return {'status': 'success'}
@app.put("/customers/")
async def update_customer(customer: Customer):
for c in local_customer:
if c.name == customer.name:
c.phone_number = customer.phone_number
c.email = customer.email
c.bitcoin_asset = customer.bitcoin_asset
return c
return {'status': '不存在'}
@app.delete("/customers/")
async def delete_customer(customer: Customer):
for c in local_customer:
if c.name == customer.name:
local_customer.remove(c)
return {'status': '已刪除'}
return {'status': '不存在'}
@app.get('/test/{id}/{birthday}/{address})
async def root(id, birthday, address):
print(f'id: {id}, birthday: {birthday}, address: {address}')
return {'hello': 'world', 'now_time': datetime.now().strftime("%m/%d/%Y, %H:%M:%S")}
@app.post("/insert_data/{client_name}")
async def insert_data(request: Request, client_name):
count = 0
for header in request.headers:
print('H [{}] {}'.format(header, request.headers[header]))
count = count + 1
print(await request.json())
return {'header_length': count}
@app.post("/items/")
async def create_item(item: Item):
print('item: {}'.format(item))
return item
@app.put("/items/")
async def update_item(item: Item):
print('UPDATE {}'.format(item))
return {'status': 'updated'}
@app.post("/upload_sample")
async def upload_csshtml(htmlfile: UploadFile=File(...)):
try:
print(htmlfile.filename)
with open('./{}'.format(htmlfile.filename), 'wb+') as f:
f.write(htmlfile.file.read())
return {'status': 'success'}
except BaseException as ex:
import traceback
r = {'error': '{}'.format(ex), 'error_detail': '{}'.format(traceback.format_exc())}
return json.dumps(r)
import nest_asyncio
from pyngrok import ngrok
import uvicorn
ngrok_tunnel = ngrok.connect(8000)
print('Public URL:', ngrok_tunnel.public_url)
nest_asyncio.apply()
uvicorn.run(app, port=8000)
程式碼的解說
介紹Restful API 的特別的地方 ref
POST/GET/PUT/DELETE sample
利用 fastapi 建立 HTTP相關的服務
DEMO 題目: 註冊數位貨幣網站用戶 (用戶註冊, 用戶資料查詢, 用戶資料更改, 用戶取消)
進階練習1: 條列出 外送餐點網站所需要的 API (單客戶 單外送 多餐廳)
進階練習2: 建立相對應的API
BootStrap 的使用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.5.0/font/bootstrap-icons.css">
<link rel="stylesheet" href="bs5.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
<!-- Make sure you put this AFTER Leaflet's CSS -->
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
<title>數位貨幣推薦系統</title>
</head>
<body>
<!-- Navbar -->
<navbar class="navbar navbar-expand-lg bg-dark navbar-dark py-3 fixed-top">
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navmenu">
<span class="navbar-toggler-icon"></span>
</button>
<div class="container">
<a href="#" class="navbar-brand">數位貨幣推薦系統</a>
<div class="collapse navbar-collapse" id="navmenu">
<ul class="navbar-nav">
<li class="nav-item">
<a href="#about" class="nav-link">有關推薦系統</a>
</li>
<li class="nav-item">
<a href="#service" class="nav-link">服務項目</a>
</li>
<li class="nav-item">
<a href="#success-case" class="nav-link">成功案例</a>
</li>
</ul>
</div>
</div>
</navbar>
<!-- Showcase -->
<section class="bg-dark text-light p-5 p-lg-3 pt-lg-5 text-center text-sm-start">
<dev class="container">
<div class="d-sm-flex align-items-center justify-content-between">
<div>
<h1>客製<span class="text-warning">推薦系統</span>增加你的財富</h1>
<p class="lead my-4">
推薦系統是一種信息過濾系統,用於預測用戶對物品的「評分」或「偏好」。 推薦系統近年來非常流行,應用於各行各業。
</p>
<button class="btn btn-primary btn-lg" data-bs-toggle="modal" data-bs-target="#enroll">開始你的財富之旅</button>
</div>
<img class="img-fluid w-50 d-none d-sm-block" src="/img/sample.jpeg" alt="">
</div>
</dev>
</section>
<!-- About -->
<section class="bg-primary text-light p-5">
<div class="container">
<div class="d-md-flex justify-content-between align-items-center">
<h3 class="mb-3 mb-md-0">輸入Email以獲取最新訊息</h3>
<div class="input-group news-input">
<input type="text" class="form-control" placeholder="輸入Email">
<button class="btn btn-dark btn-lg" type="button">輸入</button>
</div>
</div>
</div>
</section>
<!-- Box -->
<section class="p-5">
<div class="container">
<div class="row text-center g-4">
<div class="col-md">
<div class="card bg-dark text-light">
<div class="card-body text-center">
<div class="h1 mb-3"><i class="bi bi-laptop"></i></div>
<h3 class="card-title mb-3">系統</h3>
<p class="card-text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Asperiores mollitia adipisci minus suscipit ut delectus harum porro odit dolore labore, fuga enim ex necessitatibus facilis? Facilis reprehenderit omnis itaque assumenda.
</p>
<a href="" class="btn btn-primary">知道更多</a>
</div>
</div>
</div>
<div class="col-md">
<div class="card bg-secondary text-light">
<div class="card-body text-center">
<div class="h1 mb-3"><i class="bi bi-person-square"></i></div>
<h3 class="card-title mb-3">智慧分享</h3>
<p class="card-text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Asperiores mollitia adipisci minus suscipit ut delectus harum porro odit dolore labore, fuga enim ex necessitatibus facilis? Facilis reprehenderit omnis itaque assumenda.
</p>
<a href="" class="btn btn-dark">知道更多</a>
</div>
</div>
</div>
<div class="col-md">
<div class="card bg-dark text-light">
<div class="card-body text-center">
<div class="h1 mb-3"><i class="bi bi-people"></i></div>
<h3 class="card-title mb-3">展望未來</h3>
<p class="card-text">
Lorem ipsum, dolor sit amet consectetur adipisicing elit. Asperiores mollitia adipisci minus suscipit ut delectus harum porro odit dolore labore, fuga enim ex necessitatibus facilis? Facilis reprehenderit omnis itaque assumenda.
</p>
<a href="" class="btn btn-primary">知道更多</a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- 簡述 -->
<section class="p-5" id="about">
<div class="container">
<div class="row align-items-center justify-content-between">
<div class="col-md">
<img src="/img/process1.png" class="img-fluid" alt="">
</div>
<div class="col-md p-5">
<h2>推薦系統的作用</h2>
<p class="lead">
推薦系統是一種有效代替搜索算法的方式,因為他們幫助用戶找到一些他們自己沒有辦法找到的物品。有趣的是,推薦系統在實現之時通常使用搜尋引擎對非傳統數據索引。
</p>
<p>
Montaner 從智能代理角度給出了有關推薦系統的第一篇綜述文章[13]。Adomavicius給出了一種新的有關推薦系統的全景[14]。Herlock提供了有關評價推薦系統的技術綜述[15]。Beel等討論了離線評價中的問題[16]。Beel等同事也提供了現有有關推薦系統的研究文獻與現存挑戰[17][18][19]。
</p>
<a href="" class="btn btn-light mt-3">
<i class="bi bi-chevron-right"></i>知道更多
</a>
</div>
</div>
</div>
</section>
<!-- 簡述2 -->
<section class="p-5 bg-dark text-light" id="about-detail">
<div class="container">
<div class="row align-items-center justify-content-between">
<div class="col-md p-5">
<h2>推薦系統的威力</h2>
<p class="lead">
推薦系統是一種有效代替搜索算法的方式,因為他們幫助用戶找到一些他們自己沒有辦法找到的物品。有趣的是,推薦系統在實現之時通常使用搜尋引擎對非傳統數據索引。
</p>
<p>
Montaner 從智能代理角度給出了有關推薦系統的第一篇綜述文章[13]。Adomavicius給出了一種新的有關推薦系統的全景[14]。Herlock提供了有關評價推薦系統的技術綜述[15]。Beel等討論了離線評價中的問題[16]。Beel等同事也提供了現有有關推薦系統的研究文獻與現存挑戰[17][18][19]。
</p>
<a href="" class="btn btn-light mt-3">
<i class="bi bi-chevron-right"></i>知道更多
</a>
</div>
<div class="col-md">
<img src="/img/rs.png" class="img-fluid" alt="">
</div>
</div>
</div>
</section>
<!-- 問與答 -->
<section class="p-5" id="questions">
<div class="container">
<h2 class="text-center mb-4">問與答</h2>
<div class="accordion accordion-flush" id="questions">
<!-- item-1 -->
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#question-one">
推薦系統的來源
</button>
</h2>
<div id="question-one" class="accordion-collapse collapse" aria-labelledby="flush-headingOne" data-bs-parent="#questions">
<div class="accordion-body">Placeholder content for this accordion, which is intended to demonstrate the <code>.accordion-flush</code> class. This is the first item's accordion body.</div>
</div>
</div>
<!-- item-2 -->
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#question-two">
推薦系統的運作
</button>
</h2>
<div id="question-two" class="accordion-collapse collapse" aria-labelledby="flush-headingOne" data-bs-parent="#questions">
<div class="accordion-body">Placeholder content for this accordion, which is intended to demonstrate the <code>.accordion-flush</code> class. This is the first item's accordion body.</div>
</div>
</div>
<!-- item-3 -->
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#question-three">
推薦系統的成本
</button>
</h2>
<div id="question-three" class="accordion-collapse collapse" aria-labelledby="flush-headingOne" data-bs-parent="#questions">
<div class="accordion-body">Placeholder content for this accordion, which is intended to demonstrate the <code>.accordion-flush</code> class. This is the first item's accordion body.</div>
</div>
</div>
<!-- item-4 -->
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#question-four">
推薦系統的交互作用
</button>
</h2>
<div id="question-four" class="accordion-collapse collapse" aria-labelledby="flush-headingOne" data-bs-parent="#questions">
<div class="accordion-body">Placeholder content for this accordion, which is intended to demonstrate the <code>.accordion-flush</code> class. This is the first item's accordion body.</div>
</div>
</div>
<!-- item-4 -->
<div class="accordion-item">
<h2 class="accordion-header">
<button class="accordion-button collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#question-five">
成功案例
</button>
</h2>
<div id="question-five" class="accordion-collapse collapse" aria-labelledby="flush-headingOne" data-bs-parent="#questions">
<div class="accordion-body">Placeholder content for this accordion, which is intended to demonstrate the <code>.accordion-flush</code> class. This is the first item's accordion body.</div>
</div>
</div>
</div>
</div>
</section>
<!-- 成功案例 -->
<section id="successcases" class="p-5 bg-primary">
<div class="container">
<h2 class="text-center text-white">成功案例</h2>
<p class="lead text-center text-white mb-5">
沒有良好的行銷策略,就像無頭蒼蠅一樣開始做宣傳,可能讓消費者對公司跟產品的形象搞得一頭霧水,對公司長期來說也不是良好效應。
</p>
<div class="row g-4">
<div class="col-md-6 col-lg-3">
<div class="card bg-light">
<div class="card-body text-center">
<img src="https://randomuser.me/api/portraits/men/22.jpg" class="rounded-circle mb-3" alt="">
<h3 class="card-title mb-3">賺真大公司</h3>
<p class="card-text">由於勞工意識抬頭,這種吃力不討好的工作其實不員工不好找,加上基本薪資持續調漲,超商經營的成本越來越高,日前跟傳出日本7-ELEVEN 母公司打算關閉近...</p>
<a href=""><i class="bi bi-facebook text-dark mx-1"></i></a>
<a href=""><i class="bi bi-twitter text-dark mx-1"></i></a>
<a href=""><i class="bi bi-linkedin text-dark mx-1"></i></a>
<a href=""><i class="bi bi-instagram text-dark mx-1"></i></a>
</div>
</div>
</div>
<div class="col-md-6 col-lg-3">
<div class="card bg-light">
<div class="card-body text-center">
<img src="https://randomuser.me/api/portraits/women/66.jpg" class="rounded-circle mb-3" alt="">
<h3 class="card-title mb-3">真真</h3>
<p class="card-text">由於勞工意識抬頭,這種吃力不討好的工作其實不員工不好找,加上基本薪資持續調漲,超商經營的成本越來越高,日前跟傳出日本7-ELEVEN 母公司打算關閉近...</p>
<a href=""><i class="bi bi-facebook text-dark mx-1"></i></a>
<a href=""><i class="bi bi-twitter text-dark mx-1"></i></a>
<a href=""><i class="bi bi-linkedin text-dark mx-1"></i></a>
<a href=""><i class="bi bi-instagram text-dark mx-1"></i></a>
</div>
</div>
</div>
<div class="col-md-6 col-lg-3">
<div class="card bg-light">
<div class="card-body text-center">
<img src="https://randomuser.me/api/portraits/men/22.jpg" class="rounded-circle mb-3" alt="">
<h3 class="card-title mb-3">強森</h3>
<p class="card-text">由於勞工意識抬頭,這種吃力不討好的工作其實不員工不好找,加上基本薪資持續調漲,超商經營的成本越來越高,日前跟傳出日本7-ELEVEN 母公司打算關閉近...</p>
<a href=""><i class="bi bi-facebook text-dark mx-1"></i></a>
<a href=""><i class="bi bi-twitter text-dark mx-1"></i></a>
<a href=""><i class="bi bi-linkedin text-dark mx-1"></i></a>
<a href=""><i class="bi bi-instagram text-dark mx-1"></i></a>
</div>
</div>
</div>
<div class="col-md-6 col-lg-3">
<div class="card bg-light">
<div class="card-body text-center">
<img src="https://randomuser.me/api/portraits/women/33.jpg" class="rounded-circle mb-3" alt="">
<h3 class="card-title mb-3">網紅圳再開</h3>
<p class="card-text">由於勞工意識抬頭,這種吃力不討好的工作其實不員工不好找,加上基本薪資持續調漲,超商經營的成本越來越高,日前跟傳出日本7-ELEVEN 母公司打算關閉近...</p>
<a href=""><i class="bi bi-facebook text-dark mx-1"></i></a>
<a href=""><i class="bi bi-twitter text-dark mx-1"></i></a>
<a href=""><i class="bi bi-linkedin text-dark mx-1"></i></a>
<a href=""><i class="bi bi-instagram text-dark mx-1"></i></a>
</div>
</div>
</div>
</div>
</div>
</section>
<!-- contact and map -->
<section class="p-5">
<div class="container">
<div class="row">
<div class="col-md-6 col-sm-12 contacts-container">
<h2 class="text-center mb-4">聯繫我們</h2>
<ul class="list-group list-group-flush lead">
<li class="list-group-item">
<span class="fw-bold">地址:</span>中正路一號
</li>
<li class="list-group-item">
<span class="fw-bold">Email:</span>admin@xxxx.conc.co
</li>
<li class="list-group-item">
<span class="fw-bold">電話:</span>0999999999
</li>
<li class="list-group-item">
<span class="fw-bold">傳真:</span>0222222222
</li>
</ul>
</div>
<div class="col-md-6 col-sm-12 map-container rounded flex-fill" id="mapid"></div>
</div>
</div>
</section>
<!-- Footer -->
<footer class="p-5 bg-dark text-white text-center position-relative">
<div class="container">
<p class="lead">Copyright © 2021 數位貨幣推薦系統</p>
<a href="#" class="position-absolute bottom-0 end-0 p-5">
<i class="bi bi-arrow-up-circle h1"></i>
</a>
</div>
</footer>
<!-- form -->
<!-- Modal -->
<div class="modal fade" id="enroll" tabindex="-1" aria-labelledby="enrollLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="enrollLabel">Modal title</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p class="lead">我們會根據資料儘速回覆你</p>
<form action="">
<div class="mb-3">
<label for="username" class="col-form-label">姓名</label>
<input type="text" class="form-control" id="usernmae">
</div>
<div class="mb-3">
<label for="email" class="col-form-label">Email</label>
<input type="text" class="form-control" id="email">
</div>
<div class="mb-3">
<label for="phone" class="col-form-label">電話</label>
<input type="text" class="form-control" id="phone">
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">關閉</button>
<button type="button" class="btn btn-primary">確定</button>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script>
<script>
var mymap = L.map('mapid').setView([51.505, -0.09], 13);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={your token}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: 'your token'
}).addTo(mymap);
</script>
</body>
</html>
JS sample
// 註解
/*
很多行的註解的第一行
很多行的註解的第二行
*/
// 基本變數的設定以及使用
// var x = 15;
// console.log('[1]變數x的值:' + x);
// x = '這個世界變化快';
// console.log('[2]變數x的值:' + x);
// // 布林變數
// var condition1 = true;
// console.log('變數condition1的值:' + condition1);
// // 變數間的運算
// x = 16;
// var v = 15 + x;
// console.log('[3]變數v的值:' + v);
// v ++;
// console.log('[4]變數v的值:' + v);
// v = v + 1;
// console.log('[5]變數v的值:' + v);
// // 布林運算
// console.log('4 > 3:' + (4 > 3));
// console.log('2 > 3:' + (2 > 3));
// console.log('2 == 3:' + (2 == 3));
// console.log('3 == 3:' + (3 == 3));
// var d = 3;
// v = d * d;
// console.log('[6]變數v的值:' + v);
// // 輸入->運算->輸出
// var input1 = prompt('請輸入數值:', '12');
// var input2 = prompt('請輸入數值:', '12');
// v = input1 * input2;
// console.log('[7]兩者相乘的值:' + v);
// 相等
var num = 0;
var obj = new String("0");
var str = "0";
console.log('[8]變數num的值:' + num + ', 型別為:' + typeof(num));
console.log('[8]變數obj的值:' + obj + ', 型別為:' + typeof(obj));
console.log('[8]變數str的值:' + str + ', 型別為:' + typeof(str));
console.log('num === obj => ' + (num === obj));
console.log('num === str => ' + (num === str));
console.log('obj === str => ' + (obj === str));
console.log('null === undefined => ' + (null === undefined));
console.log('obj === null => ' + (obj === null));
console.log('obj === undefined => ' + (obj === undefined));
console.log('num == obj => ' + (num == obj));
console.log('num == str => ' + (num == str));
console.log('obj == str => ' + (obj == str));
console.log('null == undefined => ' + (null == undefined));
console.log('obj == null => ' + (obj == null));
console.log('obj == undefined => ' + (obj == undefined));
var withdraw = prompt('請輸入提款金額', '');
if (withdraw > 30000){
console.log('不好意思, 金管會為了防止詐騙不允許提那麼多錢!');
}else{
console.log('請點收現鈔');
}
var input = prompt('請輸入數字')
if (input % 3 == 0){
console.log('被3整除');
}else if(input % 3 == 1){
console.log('餘數為1');
}else{
console.log('餘數為2');
}
var input1 = prompt("input v1", "");
var input2 = prompt("input v1", "");
var op = prompt("operator is +-*/:", "");
input1 = Number(input1);
input2 = Number(input2);
if(op=='+'){
alert(input1 + input2);
}else if(op == '-'){
alert(input1 - input2);
}else if(op == '*'){
alert(input1 * input2);
}else if(op == '/'){
alert(input1 / input2);
}else{
alert('不認識');
}
Loop
// 陣列使用
var a = [12, 45, 88, 47, 33];
var i = 0;
// while 迴圈使用
while(i < a.length){
if (a[i] % 3 == 0){
console.log(a[i] + '被3整除');
}
i++;
}
// for 迴圈使用
var sum = 0;
for (var i = 1; i <= 100; i++){
sum = sum + i;
}
console.log('sum = ' + sum);
Function
var x = 3;
function test(x){
console.log('[1]x = ' + x);
var x = 12;
var y = 99;
console.log('[2]x = ' + x);
console.log('[2]y = ' + y);
}
test(x);
console.log('[3] y = ' + y);
HTML Dom
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
var simple_count = 0;
var weather_array = ["下雨", "颱風", "超熱", "可以打球的好天氣", "風大適合逛夜市"];
var weather_color = ["red", "green", "Tomato", "Orange", "SlateBlue"];
var weather_count = 0;
function update_count(){
simple_count ++;
window.document.getElementById('counter').innerHTML = ('count:' + simple_count);
}
function update_weather(){
var spanObj = document.getElementById('weather');
weather_count ++;
if (weather_count >= weather_array.length){
weather_count = 0;
}
console.log('weather_count = ' + weather_count);
spanObj.innerHTML = weather_array[weather_count];
spanObj.style.color = weather_color[Math.floor(Math.random() * weather_color.length)];
}
</script>
</head>
<body>
<div id="counter">count</div>
<button onclick="update_count()">加數字</button>
<hr>
<button onclick="update_weather()">改天氣</button>
<div><span id="weather">下雨</span></div>
</body>
</html>
JS 遞增數字填滿 ARRAY
function range(start, end) {
return Array(end - start + 1).fill().map((_, idx) => start + idx)
}
var result = range(9, 18); // [9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
console.log(result);
JS Form
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>HTML Form</title>
<style type="text/css">
form{
line-height: 2em;
}
form>input, form>select{
padding: 5px, 10px;border: tomato 1px solid;border-radius: 5px;
}
form>.ok{
color:darkgreen;
}
form>input:valid+.ok{
display: inline;
}
form>input:invalid+.ok{
display: none;
}
</style>
</head>
<body>
<h3>Sign up</h3>
<form onsubmit="alert('表班送出');">
帳號: <input type="text" placeholder="4-12英數字" pattern="[0-9a-zA-Z]{4,12}" required><span class='ok'>ok</span> <br/>
密碼: <input type="password" pattern="[0-9a-zA-Z]{8,16}" required><span class='ok'>ok</span><br/>
Email: <input type="email" required><span class='ok'>ok</span><br/>
電話: <input type="text" pattern="[0-9]{8,10}" required><span class='ok'>ok</span><br/>
性別: 男 <input type="radio" name="gender" value="male" required>
女 <input type="radio" name="gender" value="female" required>
其他 <input type="radio" name="gender" value="other" required><span class='ok'>ok</span><br/>
生日: <select name="birthday" id="birthday_year" required><span class='ok'>ok</span></select>
<br/>
<input type="submit" name="" id="" value="送出資料">
</form>
<script>
var a = Array(2020 - 1900 + 1).fill().map((_, idx) => 1900 + idx)
for (var i = 0; i<a.length; i++){
var opt = document.createElement('option');
opt.value = a[i];
opt.innerHTML = a[i];
document.getElementById('birthday_year').add(opt, null);
}
</script>
</body>
</html>
JS Event
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script>
function over_div(el){
el.style.color = 'yellow';
}
function out_div(el){
el.style.color = 'green';
}
function init(){
var btn = document.getElementById('btn');
var handler = function(){document.getElementById('x-div').innerHTML="不是空的";}
btn.addEventListener('click', handler);
var btn2 = document.getElementById('btn2');
var handler2 = function(e){
document.getElementById('x-div2').innerHTML="不是空的";
console.log(e.clientX + ',' + e.clientY);
}
btn2.addEventListener('click', handler2);
}
document.addEventListener('keydown', function(e){console.log(e.keyCode)});
function keyup(e){
console.log('keyup[' + e.keyCode + ']');
}
document.addEventListener('keyup', keyup);
</script>
</head>
<body onload="init();">
<span onmouseover="this.style.color='red';" onmouseout="this.style.color='black';">拖鞋是鞋子的一種。鞋後跟全空,只有前面有鞋頭,多為平底。材質經常是相當輕軟的皮料、塑膠、布料、橡膠等。</span>
<div onmouseover="over_div(this);" onmouseout="out_div(this);">拖鞋的種類依穿著的場合有所區分,例如:海灘拖鞋和浴室的拖鞋,就不會是布料製,而是塑膠材質,這是為了要防水,好清洗的緣故,鞋頭的型式也依功能設計。</div>
<button id="btn">按鈕</button>
<div id="x-div">空的</div>
<hr>
<button id="btn2">按鈕</button>
<div id="x-div2">空的</div>
</body>
</html>
XHR(1)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自行車道</title>
</head>
<body>
選擇 <select id="route-selector" onchange="update_info();"></select>
<div id="route-info"></div>
<script>
var a = new XMLHttpRequest();
a.open('get', 'https://blog.robertiv.org/images/Bike_f.json', false);
a.send();
var b = JSON.parse(a.responseText);
var datalist = b["XML_Head"]["Infos"]["Info"];
var route_names = datalist.map(x => x.Name);
let selector = document.getElementById("router-selector");
let desc = document.getElementById("route-info");
for(i=0; i< route_names.length; i++){
var opt = document.createElement('option');
opt.text = route_names[i];
opt.value = route_names[i];
selector.add(opt, null);
}
function update_info(){
for(i=0;i<datalist.length;i++){
if(datalist[i]["Name"] == selector.selectedOptions[0].value){
desc.innerHTML = "<h2>" + datalist[i]["region"] + "</h2><p>" + datalist[i]["Toldescribe"] + "</p>";
break;
}
}
}
</script>
</body>
</html>
co-lab for XHR
!pip install fastapi nest-asyncio pyngrok uvicorn python-multipart requests
from fastapi import FastAPI, UploadFile, File, Request
from fastapi.middleware.cors import CORSMiddleware
from datetime import datetime
from typing import Optional
from pydantic import BaseModel
import requests
import json
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=['*'],
allow_credentials=True,
allow_methods=['*'],
allow_headers=['*'],
)
@app.get("/route-info")
async def route_info():
try:
r = requests.get('https://gis.taiwan.net.tw/XMLReleaseALL_public/Bike_f.json')
print(r.text[:100])
route_data = json.loads(r.text)
return route_data
except BaseException as ex:
print(ex)
import nest_asyncio
from pyngrok import ngrok
import uvicorn
ngrok_tunnel = ngrok.connect(8000)
print('Public URL:', ngrok_tunnel.public_url)
nest_asyncio.apply()
uvicorn.run(app, port=8000)
XHR(2)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自行車道</title>
</head>
<body>
選擇 <select id="route-selector" onchange="update_info();"></select>
<div id="route-info"></div>
<script>
datalist = null;
let selector = document.getElementById("route-selector");
let desc = document.getElementById("route-info");
function reqListener(){
var b = JSON.parse(this.responseText);
datalist = b.XML_Head.Infos.Info;
var route_names = datalist.map(x => x.Name);
for(i=0; i< route_names.length; i++){
var opt = document.createElement('option');
opt.text = route_names[i];
opt.value = route_names[i];
selector.add(opt, null);
}
}
var a = new XMLHttpRequest();
a.open('get', 'http://81ad01ce44d9.ngrok.io/route-info');
a.addEventListener("load", reqListener);
a.send();
// var a = new XMLHttpRequest();
// a.open('get', 'http://81ad01ce44d9.ngrok.io/route-info', false);
// a.send();
// var b = JSON.parse(a.responseText);
// var datalist = b["XML_Head"]["Infos"]["Info"];
// var route_names = datalist.map(x => x.Name);
// let selector = document.getElementById("route-selector");
// let desc = document.getElementById("route-info");
// for(i=0; i< route_names.length; i++){
// var opt = document.createElement('option');
// opt.text = route_names[i];
// opt.value = route_names[i];
// selector.add(opt, null);
// }
function update_info(){
for(i=0;i<datalist.length;i++){
if(datalist[i]["Name"] == selector.selectedOptions[0].value){
var k = datalist[i];
desc.innerHTML = "<h2>" + k.Region + "</h2><p>" + k.Toldescribe + "</p><p>路線簡述:" +
k.Travellinginfo + "</p><p>路線長度" + k.Bike_length + "公尺</p><p>注意事項: " +
k.Remarks + '</p>';
break;
}
}
}
</script>
</body>
</html>
Leaflet
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>自行車道</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css"
integrity="sha512-xodZBNTC5n17Xt2atTPuE1HxjVMSvLVW9ocqUKLsCC5CXdbqCmblAshOMAS6/keqq/sMZMZ19scR4PsZChSR7A=="
crossorigin=""/>
<!-- Make sure you put this AFTER Leaflet's CSS -->
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"
integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA=="
crossorigin=""></script>
<style type="text/css">
#mapid {height: 500px;}
</style>
</head>
<body>
選擇 <select id="route-selector" onchange="update_info();"></select>
<div id="route-info"></div>
<div id="mapid"></div>
<script>
datalist = null;
let selector = document.getElementById("route-selector");
let desc = document.getElementById("route-info");
function reqListener(){
var b = JSON.parse(this.responseText);
datalist = b.XML_Head.Infos.Info;
var route_names = datalist.map(x => x.Name);
for(i=0; i< route_names.length; i++){
var opt = document.createElement('option');
opt.text = route_names[i];
opt.value = route_names[i];
selector.add(opt, null);
}
}
var a = new XMLHttpRequest();
a.open('get', 'https://blog.robertiv.org/images/Bike_f.json');
a.addEventListener("load", reqListener);
a.send();
// var a = new XMLHttpRequest();
// a.open('get', 'http://81ad01ce44d9.ngrok.io/route-info', false);
// a.send();
// var b = JSON.parse(a.responseText);
// var datalist = b["XML_Head"]["Infos"]["Info"];
// var route_names = datalist.map(x => x.Name);
// let selector = document.getElementById("route-selector");
// let desc = document.getElementById("route-info");
// for(i=0; i< route_names.length; i++){
// var opt = document.createElement('option');
// opt.text = route_names[i];
// opt.value = route_names[i];
// selector.add(opt, null);
// }
function update_info(){
for(i=0;i<datalist.length;i++){
if(datalist[i]["Name"] == selector.selectedOptions[0].value){
var k = datalist[i];
desc.innerHTML = "<h2>" + k.Region + "</h2><p>" + k.Toldescribe + "</p><p>路線簡述:" +
k.Travellinginfo + "</p><p>路線長度" + k.Bike_length + "公尺</p><p>注意事項: " +
k.Remarks + '</p>';
var latlngs = k.Trail_Periphery.map(x => [x.Py, x.Px]);
console.log(latlngs);
var polyline = L.polyline(latlngs, {color: 'red'}).addTo(mymap);
mymap.fitBounds(polyline.getBounds())
break;
}
}
}
var mymap = L.map('mapid').setView([23.1001253946, 121.379766259], 13);
L.tileLayer('https://api.mapbox.com/styles/v1/{id}/tiles/{z}/{x}/{y}?access_token={token}', {
attribution: 'Map data © <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, Imagery © <a href="https://www.mapbox.com/">Mapbox</a>',
maxZoom: 18,
id: 'mapbox/streets-v11',
tileSize: 512,
zoomOffset: -1,
accessToken: 'your.mapbox.access.token'
}).addTo(mymap);
</script>
</body>
</html>
Comments
comments powered by Disqus