2409js,学习js2
原文
全局对象
function sayHi() {
alert("Hello");
}
// 全局对象的函数.
window.sayHi();
alert(window.innerHeight);
更改背景
document.body.style.background = "red";
setTimeout(() => document.body.style.background = "", 1000);
当前地址
alert(location.href);
if (confirm("Go to Wikipedia?")) {
location.href = "https://wikipedia.org";
// 重定向
}
子:childNodes,firstChild,lastChild
elem.childNodes[0] === elem.firstChild
elem.childNodes[elem.childNodes.length - 1] === elem.lastChild
//子们.
for (let node of document.body.childNodes) {
alert(node); // 迭代.
}
同级与父级
alert( document.body.parentNode === document.documentElement ); // true
alert( document.head.nextSibling ); //
alert( document.body.previousSibling );
对于所有节点:parentNode,childNodes,firstChild,lastChild,previousSibling,nextSibling
.
仅适用于元素节点:parentElement,children,firstElementChild,lastElementChild,previousElementSibling,nextElementSibling
.
取元素
let elem = document.getElementById('elem');
elem.style.background = 'red';
选择器
let elements = document.querySelectorAll('ul > li:last-child');
//支持伪类
for (let elem of elements) {
alert(elem.innerHTML);
}
elem.querySelector
返回第1个匹配元素.
elem.matches(css)
,是否匹配.
for (let elem of document.body.children) {
if (elem.matches('a[href$="zip"]')) {
alert("哈哈.." + elem.href );
}
}
elem.closest(css)
查找与CSS
选择器匹配
的最近祖先
.包含elem
.
querySelector
更强大,
document.body.innerHTML = 'The new BODY!';
alert(elem.outerHTML);
// <div id="elem">Hello <b>World</b></div>
文本的兄弟:
let text = document.body.firstChild;
alert(text.data); // Hello
let comment = text.nextSibling;
alert(comment.data); // Comment
alert(news.textContent);//去掉所有标签的纯文本.
elem.hidden = true;//隐藏元素
setInterval(() => elem.hidden = !elem.hidden, 1000);
//闪烁元素.
直接访问属性
alert(elem.type); // "text"
alert(elem.id); // "elem"
alert(elem.value); // value
给节点加元素加方法
document.body.myData = {
name: 'Caesar',
title: 'Imperator'
};
alert(document.body.myData.title); //
document.body.sayTagName = function() {
alert(this.tagName);
};
document.body.sayTagName();
给所有元素加方法
Element.prototype.sayHi = function() {
alert(`Hello, I'm ${this.tagName}`);
};
document.documentElement.sayHi(); //
document.body.sayHi(); //
几个属性方法
elem.hasAttribute(name)
,检查是否存在属性.
elem.getAttribute(name)
,获取值.
elem.setAttribute(name,value)
,设置值.
elem.removeAttribute(name)
,删除属性
.
属性同步
let input = document.querySelector('input');
// attribute => property
input.setAttribute('id', 'id');
alert(input.id); // id (updated)
// property => attribute
input.id = 'newId';
alert(input.getAttribute('id')); // newId (updated)
不同步
let input = document.querySelector('input');
// attribute => property
input.setAttribute('value', 'text');
alert(input.value); // text
// NOT property => attribute
input.value = 'newValue';
alert(input.getAttribute('value')); // 未更新.
更改属性值
将更新属性
.
但更改属性
不会影响属性
.
数据集
<style>
.order[data-order-state="new"] {
color: green;
}
.order[data-order-state="pending"] {
color: blue;
}
.order[data-order-state="canceled"] {
color: red;
}
</style>
<div id="order" class="order" data-order-state="new">
A new order.
</div>
<script>
// read
alert(order.dataset.orderState); // new
// modify
order.dataset.orderState = "pending"; // (*)
</script>
elem.attributes
是所有属性
的集合.
创建元素
let div = document.createElement('div');
let textNode = document.createTextNode('Here I am');
//文本节点,
let div = document.createElement('div');
div.className = "alert";
//设置类.填充内容.
div.innerHTML = "<strong>Hi there!</strong> You've read an important message.";
node.append(...节点或串)
,在节点末尾附加节点或串
,
node.prepend(...节点或串)
,在节点的开头插入节点或串
,
node.before(...节点或串)
,在node
之前插入节点或串
,
node.after(...节点或串)
,在节点后插入节点或串
,
node.replaceWith(...节点或串)
,按给定的节点或串替换node
.
ol.before('before');
ol.after('after');
ol.prepend(liFirst);
ol.append(liLast);
div.insertAdjacentHTML('beforebegin', '<p>Hello</p>');
div.insertAdjacentHTML('afterend', '<p>Bye</p>');
//插入html
elem.insertAdjacentText(where,text)
//beforebegin,afterbegin,beforeend,afterend
//插入文本
elem.insertAdjacentElement(where,elem)
div.remove()
//删除节点.
所有插入
方法都会自动从旧位置
删除节点
.
克隆节点
let div2 = div.cloneNode(true);//深度
let div2 = div.cloneNode(假);//非深度
文档片段
function getListContent() {
let fragment = new DocumentFragment();
for(let i=1; i<=3; i++) {
let li = document.createElement('li');
li.append(i);
fragment.append(li);
}
return fragment;
}
ul.append(getListContent()); // (*)
高级点
function getListContent() {
let result = [];
for(let i=1; i<=3; i++) {
let li = document.createElement('li');
li.append(i);
result.push(li);
}
return result;
}
ul.append(...getListContent());
旧方法
list.appendChild(newLi);
list.insertBefore(newLi, list.children[1]);
list.insertBefore(newLi, list.firstChild);
list.removeChild(li);
parentElem.replaceChild(节点,oldChild)
风格
elem.style.left = left;
elem.style.top = top;
alert(document.body.className);
//类名,main page
document.body.classList.add('article');
alert(document.body.className);
// main page article
for (let name of document.body.classList) //迭代.
方法有:
classList.add/remove
classList.toggle
classList.contains
风格
button.style.MozBorderRadius = '5px';
button.style.WebkitBorderRadius = '5px';
隐藏
document.body.style.display = "none"; // hide
setTimeout(() => document.body.style.display = "", 1000); // 显示.
setTimeout(() => document.body.style.removeProperty('background'), 1000);
//删除属性
文本串属性
div.style.cssText=`color: red !important;
background-color: yellow;
width: 100px;
text-align: center;
`;
alert(div.style.cssText);
单位
document.body.style.margin = '20px';
alert(document.body.style.margin); // 20px
alert(document.body.style.marginTop); // 20px
alert(document.body.style.marginLeft); // 20px
let computedStyle = getComputedStyle(document.body);
//计算风格.只读.
alert( computedStyle.marginTop ); // 5px
alert( computedStyle.color );
延迟或异步加载
<script defer src="https://javascript.info/article/script-async-defer/long.js?speed=1"></script>
<script async src="https://javascript.info/article/script-async-defer/long.js"></script>
<script async src="https://javascript.info/article/script-async-defer/small.js"></script>
动态脚本
let script = document.createElement('script');
script.src = "/article/script-async-defer/long.js";
document.body.append(script); // (*)
改变监视器
使用MutationObserver
,可以检测到在DOM
中何时出现不需要的元素
,并删除它.
有更改后,执行回调
:
let observer = new MutationObserver(callback);
observer.observe(node, config);
例:
<div contentEditable id="elem">Click and <b>edit</b>, please</div>
<script>
let observer = new MutationObserver(mutationRecords => {
console.log(mutationRecords); // 记录更改.
});
// 除了属性外.
observer.observe(elem, {
childList: true, // 观察直接子,
subtree: true, // 及子树.
characterDataOldValue: true // 旧数据
});
</script>
//
mutationRecords = [{
type: "characterData",
oldValue: "edit",
target: <text node>,
// other properties empty
}];
数组缓冲
ArrayBuffer
,固定长度
连续内存区域
的引用
.
let buffer = new ArrayBuffer(16);
let view = new Uint32Array(buffer);
alert(view.length);//4
alert(view.byteLength); // 16,按字节.
// 赋值.
view[0] = 123456;
// 迭代
for(let num of view) {
alert(num); // 123456, 然后0, 0, 0
相同视图
let arr8 = new Uint8Array([0, 1, 2, 3]);
let arr16 = new Uint16Array(arr8.buffer);
任意格式视图
let buffer = new Uint8Array([255, 255, 255, 255]).buffer;
let dataView = new DataView(buffer);
alert( dataView.getUint8(0) ); // 255
alert( dataView.getUint16(0) ); // 65535
alert( dataView.getUint32(0) ); // 4294967295
dataView.setUint32(0, 0);
解码二进制
let uint8Array = new Uint8Array([72, 101, 108, 108, 111]);
alert( new TextDecoder().decode(uint8Array) ); // Hello
let uint8Array = new Uint8Array([228, 189, 160, 229, 165, 189]);
alert( new TextDecoder().decode(uint8Array) ); // 你好
文本编码器
let encoder = new TextEncoder();
let uint8Array = encoder.encode("Hello");
alert(uint8Array); // 72,101,108,108,111
块
let blob = new Blob(["<html>…</html>"], {type: 'text/html'});
//第1参为数组.
动态下载
<a download="hello.txt" href='#' id="link">Download</a>
<script>
let blob = new Blob(["Hello, world!"], {type: 'text/plain'});
link.href = URL.createObjectURL(blob);
</script>
动态链接
let link = document.createElement('a');
link.download = 'hello.txt';
let blob = new Blob(['Hello, world!'], {type: 'text/plain'});
link.href = URL.createObjectURL(blob);
link.click();
URL.revokeObjectURL(link.href);//删除掉
图像操作
let img = document.querySelector('img');
let canvas = document.createElement('canvas');
canvas.width = img.clientWidth;
canvas.height = img.clientHeight;
let context = canvas.getContext('2d');
context.drawImage(img, 0, 0);
//前面是绘画,后面是保存.
canvas.toBlob(function(blob) {
// 下载
let link = document.createElement('a');
link.download = 'example.png';
link.href = URL.createObjectURL(blob);
link.click();
URL.revokeObjectURL(link.href);
}, 'image/png');
流
const readableStream = blob.stream();
const stream = readableStream.getReader();
while (true) {
let { done, value } = await stream.read();
if (done) {
console.log('all blob processed.');
break;
}
console.log(value);
}
取文件
<input type="file" onchange="showFile(this)">
<script>
function showFile(input) {
let file = input.files[0];//可选择多个文件.
alert(`File name: ${file.name}`);
alert(`Last modified: ${file.lastModified}`); // e.g 1552830408824
}
</script>
读文件
<input type="file" onchange="readFile(this)">
<script>
function readFile(input) {
let file = input.files[0];
let reader = new FileReader();//
reader.readAsText(file);//方法!
//readAsArrayBuffer,readAsText,readAsDataURL,
reader.onload = function() {
console.log(reader.result);
};
reader.onerror = function() {
console.log(reader.error);
};
}
</script>