浏览器

操作DOM

始终记住DOM是一个树形结构。操作一个DOM节点实际上就是这么几个操作:

  • 更新:更新该DOM节点的内容,相当于更新了该DOM节点表示的HTML的内容;
  • 遍历:遍历该DOM节点下的子节点,以便进行进一步操作;
  • 添加:在该DOM节点下新增一个子节点,相当于动态增加了一个HTML节点;
  • 删除:将该节点从HTML中删除,相当于删掉了该DOM节点的内容以及它包含的所有子节点。
// 返回ID为'test'的节点:
var test = document.getElementById('test');

// 先定位ID为'test-table'的节点,再返回其内部所有tr节点:
var trs = document.getElementById('test-table').getElementsByTagName('tr');

// 先定位ID为'test-div'的节点,再返回其内部所有class包含red的节点:
var reds = document.getElementById('test-div').getElementsByClassName('red');

// 获取节点test下的所有直属子节点:
var cs = test.children;

// 获取节点test下第一个、最后一个子节点:
var first = test.firstElementChild;
var last = test.lastElementChild;

// 通过querySelector获取ID为q1的节点:
var q1 = document.querySelector('#q1');

// 通过querySelectorAll获取q1节点内的符合条件的所有节点:
var ps = q1.querySelectorAll('div.highlighted > p');

demo

<!-- html -->
<div id="test-div">
<div class="c-red">
<p id="test-p">JavaScript</p>
<p>Java</p>
</div>
<div class="c-red c-green">
<p>Python</p>
<p>Ruby</p>
<p>Swift</p>
</div>
<div class="c-green">
<p>Scheme</p>
<p>Haskell</p>
</div>
</div>
// 选择<p>JavaScript</p>:
var js = document.getElementById('test-p');

// 选择<p>Python</p>,<p>Ruby</p>,<p>Swift</p>:
var arr = document.getElementsByClassName('c-green')[0].children;

// 选择<p>Haskell</p>:
var haskell = document.getElementsByClassName('c-green')[1].lastElementChild;

更新

  • innerHTML
  • innerText // 会自动编码 不返回hidden
  • innerContent // 自动编码

修改css

// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置CSS:
p.style.color = '#ff0000';
p.style.fontSize = '20px';
p.style.paddingTop = '2em';
<!-- HTML结构 -->
<div id="test-div">
<p id="test-js">javascript</p>
<p>Java</p>
</div>
// 获取<p>javascript</p>节点:
var js = document.getElementById('test-js');

// 修改文本为JavaScript:
// TODO:
js.innerHTML = 'JavaScript';
// 修改CSS为: color: #ff0000, font-weight: bold
// TODO:
js.style.color = '#ff0000';
js.style.fontWeight = 'bold';

插入

  • appendChild
  • insertBefore // 插到ref之前

appendChild

var
    list = document.getElementById('list'),
    haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.appendChild(haskell);
    

insertBefore

var
    list = document.getElementById('list'),
    ref = document.getElementById('python'),
    haskell = document.createElement('p');
haskell.id = 'haskell';
haskell.innerText = 'Haskell';
list.insertBefore(haskell, ref);

删除

removeChild

// 拿到待删除节点:
var self = document.getElementById('to-be-removed');
// 拿到父节点:
var parent = self.parentElement;
// 删除:
var removed = parent.removeChild(self);
removed === self; // true

删除web不相关技术

<!-- HTML结构 -->
<ul id="test-list">
<li>JavaScript</li>
<li>Swift</li>
<li>HTML</li>
<li>ANSI C</li>
<li>CSS</li>
<li>DirectX</li>
</ul>
var 
parent = document.getElementById('test-list'),
web=['JavaScript', 'HTML', 'CSS'];
for (var i of parent.children){
if(web.indexOf(i.innerText)===-1){
parent.removeChild(i);
}
}

操作表单

获取

// <input type="text" id="email">
var input = document.getElementById('email');
input.value; // '用户输入的值'
// <label><input type="radio" name="weekday" id="monday" value="1"> Monday</label>
// <label><input type="radio" name="weekday" id="tuesday" value="2"> Tuesday</label>
var mon = document.getElementById('monday');
var tue = document.getElementById('tuesday');
mon.value; // '1'
tue.value; // '2'
mon.checked; // true或者false
tue.checked; // true或者false

设置

// <input type="text" id="email">
var input = document.getElementById('email');
input.value = 'test@example.com'; // 文本框的内容已更新

提交

  1. 绑定提交函数
    <!-- HTML -->
    <form id="test-form">
    <input type="text" name="test">
    <button type="button" onclick="doSubmitForm()">Submit</button>
    </form>

    <script>
    function doSubmitForm() {
    var form = document.getElementById('test-form');
    // 可以在此修改form的input...
    // 提交form:
    form.submit();
    }
    </script>
  2. 响应form onsubmin
    <!-- HTML -->
    <form id="test-form" onsubmit="return checkForm()">
    <input type="text" name="test">
    <button type="submit">Submit</button>
    </form>

    <script>
    function checkForm() {
    var form = document.getElementById('test-form');
    // 可以在此修改form的input...
    // 继续下一步:
    return true;
    }
    </script>
    hidden使用
    <!-- HTML -->
    <form id="login-form" method="post" onsubmit="return checkForm()">
    <input type="text" id="username" name="username">
    <input type="password" id="input-password"> // 无name
    <input type="hidden" id="md5-password" name="password">
    <button type="submit">Submit</button>
    </form>

    <script>
    function checkForm() {
    var input_pwd = document.getElementById('input-password');
    var md5_pwd = document.getElementById('md5-password');
    // 把用户输入的明文变为MD5:
    md5_pwd.value = toMD5(input_pwd.value);
    // 继续下一步:
    return true;
    }
    </script>

操作文件

var
fileInput = document.getElementById('test-image-file'),
info = document.getElementById('test-file-info'),
preview = document.getElementById('test-image-preview');
// 监听change事件:
fileInput.addEventListener('change', function () {
// 清除背景图片:
preview.style.backgroundImage = '';
// 检查文件是否选择:
if (!fileInput.value) {
info.innerHTML = '没有选择文件';
return;
}
// 获取File引用:
var file = fileInput.files[0];
// 获取File信息:
info.innerHTML = '文件: ' + file.name + '<br>' +
'大小: ' + file.size + '<br>' +
'修改: ' + file.lastModified;
if (file.type !== 'image/jpeg' && file.type !== 'image/png' && file.type !== 'image/gif') {
alert('不是有效的图片文件!');
return;
}
// 读取文件:
var reader = new FileReader();
reader.onload = function(e) { // 回调
var
data = e.target.result; // 'data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...'
preview.style.backgroundImage = 'url(' + data + ')';
};
// 以DataURL的形式读取文件 base64格式:
reader.readAsDataURL(file); // 异步读取
});

AJAX

function success(text) {
var textarea = document.getElementById('test-response-text');
textarea.value = text;
}

function fail(code) {
var textarea = document.getElementById('test-response-text');
textarea.value = 'Error code: ' + code;
}

var request = new XMLHttpRequest(); // 新建XMLHttpRequest对象

request.onreadystatechange = function () { // 状态发生变化时,函数被回调
if (request.readyState === 4) { // 成功完成
// 判断响应结果:
if (request.status === 200) {
// 成功,通过responseText拿到响应的文本:
return success(request.responseText);
} else {
// 失败,根据响应码判断失败原因:
return fail(request.status);
}
} else {
// HTTP请求还在继续...
}
}

// 发送请求:
request.open('GET', '/api/categories');
request.send(); // 真正发送

alert('请求已发送,请等待响应...');

XMLHttpRequest对象的open()方法有3个参数,第一个参数指定是GET还是POST,第二个参数指定URL地址,第三个参数指定是否使用异步,默认是true,所以不用写。

CORS

CORS全称Cross-Origin Resource Sharing,是HTML5规范定义的如何跨域访问资源。

假设本域是my.com,外域是sina.com,只要响应头Access-Control-Allow-Origin为http://my.com,或者是*,本次请求就可以成功。

可见,跨域能否成功,取决于对方服务器是否愿意给你设置一个正确的Access-Control-Allow-Origin,决定权始终在对方手中。

上面这种跨域请求,称之为“简单请求”。简单请求包括GET、HEAD和POST(POST的Content-Type类型 仅限application/x-www-form-urlencoded、multipart/form-data和text/plain),并且不能出现任何自定义头(例如,X-Custom: 12345),通常能满足90%的需求。

Promise

Canvas

jQuery

选择器

操作dom

事件

动画

AJAX

扩展

错误处理

underscore

node.js