Notes
基本是直接拷贝代码了。。原书《Eloquent JavaScript》
Why I won't be using Fetch API in my apps – Shahar Talmi – Medium(这篇文章的评论区有精彩辩论:p)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script type="text/javascript"> let resp; fetch("example/data.txt").then(response => { console.log(response.status); // → 200 console.log(response.headers.get("Content-Type")); // header是一种类似map的对象,大小写无关紧要 // → text/plain resp = response; }); // 只有在网络错误或者无法找到请求服务器时,promise才会被reject fetch("example/data.txt") .then(resp => resp.text()) // 读取响应也是个耗时操作,因此仍然用promise来读它 .then(text => console.log(text)); // → hello world fetch("example/data.txt", {headers: {Range: "bytes=8-19"}}) .then(resp => resp.text()) .then(console.log); // → the content(本机测试还是整段话输出来了?) // 默认是GET方法 fetch("example/data.txt", {method: "DELETE" }).then(resp => { console.log(resp.status); // → 405 (本机测试是500) }).catch(reason => console.log(reason)); </script> </body> </html>
form是在还没有js的时代被设计出来的,在有js的时代,form并不是必要的。
可以用focus()和blur()方法控制focus:
<input type="text"> <script> document.querySelector("input").focus(); console.log(document.activeElement.tagName); // → INPUT document.querySelector("input").blur(); console.log(document.activeElement.tagName); // → BODY </script>
自定义tab切换focus顺序:
<input type="text" tabindex=1> <a href=".">(help)</a> <button onclick="console.log('ok')" tabindex=2>OK</button>
例如在执行异步操作时,不希望用户反复点击按钮:
<button>I'm all right</button> <button disabled>I'm out</button>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="example/submit.html"> Name: <input type="text" name="name"><br> Password: <input type="password" name="password"><br> <button type="submit">Log in</button> </form> <script> let form = document.querySelector("form"); console.log(form.elements[1].type); // → password console.log(form.elements.password.type); // → password console.log(form.elements.name.form == form); // → true </script> </body> </html>
然后自己用js提交(fetch,ajax等)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <form action="example/submit.html"> Value: <input type="text" name="value"> <button type="submit">Save</button> </form> <script> let form = document.querySelector("form"); form.addEventListener("submit", event => { console.log("Saving value", form.elements.value.value); event.preventDefault(); }); </script> </body> </html>
借助selectionStart和selectionEnd以及value属性:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <textarea></textarea> <script> let textarea = document.querySelector("textarea"); textarea.addEventListener("keydown", event => { // The key code for F2 happens to be 113 if(event.keyCode == 113) { replaceSelection(textarea, "Khasekhemwy"); event.preventDefault(); } }); function replaceSelection(field, word) { let from = field.selectionStart, to = field.selectionEnd; field.value = field.value.slice(0, from) + word + field.value.slice(to); // Put the cursor after the word field.selectionStart = from + word.length; field.selectionEnd = from + word.length; } </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="text"> length: <span id="length">0</span> <script> let text = document.querySelector("input"); let output = document.querySelector("#length"); text.addEventListener("input", () => { output.textContent = text.value.length; }); </script> </body> </html>
<label> <input type="checkbox" id="purple"> Make this page purple </label> <script> let checkbox = document.querySelector("#purple"); checkbox.addEventListener("change", () => { document.body.style.background = checkbox.checked ? "mediumpurple" : ""; }); </script>
X
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> Color: <label> <input type="radio" name="color" value="orange"> Orange </label> <label> <input type="radio" name="color" value="lightgreen"> Green </label> <label> <input type="radio" name="color" value="lightblue"> Blue </label> <script> let buttons = document.querySelectorAll("[name=color]"); for(let button of Array.from(buttons)) { button.addEventListener("change", () => { document.body.style.background = button.value; }); } </script> </body> </html>
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <select multiple> <option value="1">0001</option> <option value="2">0010</option> <option value="4">0100</option> <option value="8">1000</option> </select> = <span id="output">0</span> <script> let select = document.querySelector("select"); let output = document.querySelector("#output"); select.addEventListener("change", () => { let number = 0; for(let option of Array.from(select.options)) { if(option.selected) { number += Number(option.value); } } output.textContent = number; }); </script> </body> </html>
<input type="file"> <script> let input = document.querySelector("input"); input.addEventListener("change", () => { if (input.files.length > 0) { let file = input.files[0]; console.log("You chose", file.name); if (file.type) console.log("It has type", file.type); } }); </script>
异步读内容:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <input type="file" multiple> <script> let input = document.querySelector("input"); input.addEventListener("change", () => { for(let file of Array.from(input.files)) { let reader = new FileReader(); reader.addEventListener("load", () => { console.log("File", file.name, "starts with", reader.result.slice(0, 20)); }); reader.readAsText(file); } }); </script> </body> </html>
有时仅将数据保留在浏览器中就足够了。
localStorage。setItem(“username”,“marijn”);
控制台。日志(localStorage的。的getItem(“用户名”));
//→marijn
localStorage。removeItem(“username”);
localStorage特点:容量小,不可跨域。
类似的是sessionStorage,关掉浏览器就没有了。
简单笔记本↓
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> Notes: <select></select> <button>Add</button><br> <textarea style=" 100%"></textarea> <script> let list = document.querySelector("select"); let note = document.querySelector("textarea"); let state; function setState(newState) { list.textContent = ""; for(let name of Object.keys(newState.notes)) { let option = document.createElement("option"); option.textContent = name; if(newState.selected == name) option.selected = true; list.appendChild(option); } note.value = newState.notes[newState.selected]; localStorage.setItem("Notes", JSON.stringify(newState)); state = newState; } setState(JSON.parse(localStorage.getItem("Notes")) || { notes: { "shopping list": "Carrots Raisins" }, selected: "shopping list" }); list.addEventListener("change", () => { setState({ notes: state.notes, selected: list.value }); }); note.addEventListener("change", () => { setState({ notes: Object.assign({}, state.notes, { [state.selected]: note.value }), selected: state.selected }); }); document.querySelector("button") .addEventListener("click", () => { let name = prompt("Note name"); if(name) setState({ notes: Object.assign({}, state.notes, { [name]: "" }), selected: name }); }); </script> </body> </html>
Excercise
课本答案:
const url = "https://eloquentjavascript.net/author"; const types = ["text/plain", "text/html", "application/json", "application/rainbows+unicorns"]; async function showTypes() { for (let type of types) { let resp = await fetch(url, {headers: {accept: type}}); console.log(`${type}: ${await resp.text()} `); } } showTypes();
---------------------------
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title></title> </head> <body> <textarea id="code">return "hi";</textarea> <button id="button">Run</button> <pre id="output"></pre> <script> // Your code here. let run = document.querySelector("#button"); let outputNode = document.querySelector("#output"); run.addEventListener("click", event => { let code = document.querySelector("#code").value; let func = Function(code); let result; try { result = func(); } catch (error) { result = error; } outputNode.innerText = String(result); }); </script> </body> </html>
------------------- - -
暂时省略