JS-浏览器

浏览器

不同的浏览器对于JavaScript支持的差异主要是,有些API的接口不一样,比如AJAX,File接口。对于ES6标准,不同浏览器对各个特性支持也不一样。

浏览器对象


  • window

window对象不但充当全局作用域,而且表示浏览器窗口。

window.innerWidth
window.innerHeight // 获取浏览器窗口的内部宽度和高度。内部宽高是指除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高。
window.outerWidth
window.outerHeight // 获取浏览器窗口的整个宽高
  • navigator

navigator对象表示浏览器的信息。

navigator.appName:浏览器名称;
navigator.appVersion:浏览器版本;
navigator.language:浏览器设置的语言;
navigator.platform:操作系统类型;
navigator.userAgent:浏览器设定的User-Agent字符串。
  • screen

screen对象表示屏幕的信息。

screen.width:屏幕宽度,以像素为单位;
screen.height:屏幕高度,以像素为单位;
screen.colorDepth:返回颜色位数,如8、16、24。
  • location

location对象表示当前页面的URL信息。
可以用location.href获取URL,获取URL各个部分的值:

location.protocol; // 'http'
location.host; // 'www.example.com'
location.port; // '8080'
location.pathname; // '/path/index.html'
location.search; // '?a=1&b=2'
location.hash; // 'TOP'

加载页面:

location.assign() // 加载一个新页面
location.reload() // 重新加载当前页面
  • document

document对象表示当前页面。由于HTML在浏览器中以DOM形式表示为树形结构,document对象就是整个DOM树的根节点。

document.title // HTML文档的<title>xxx</title>
document.getElementById() // 按ID获得一个DOM节点
document.getElementsByTagName() // 按Tag名称获得一组DOM节点
document.cookie // 获取当前页面的Cookie

由于JavaScript能读取到页面的Cookie,而用户的登录信息通常也存在Cookie中,这就造成了巨大的安全隐患。为了解决安全问题,服务器在设置Cookie时可以使用httpOnly,设定了httpOnly的Cookie将不能被JvaScript读取。

  • history

history对象保存了浏览器的历史记录。

history.back() // 后退
history.forward() // 前进

这个对象属于历史遗留对象,对于现代Web页面来说,不应该使用history对象了。

操作DOM


  • 更新DOM

拿到一个DOM节点后,可以直接修改它的文本,有两种方式:
一种是修改innerHTML属性,这个方式非常强大,不但可以修改一个DOM节点的文本内筒,还可以直接通过HTML片段修改DOM节点内部的子树:

// 获取<p id="p-id">...</p>
var p = document.getElementById('p-id');
// 设置文本为abc:
p.innerHTML = 'ABC'; // <p id="p-id">ABC</p>
// 设置HTML:
p.innerHTML = 'ABC <span style="color:red">RED</span> XYZ';
// <p>...</p>的内部结构已修改

innerHTML时要注意,是否需要写入HTML。如果写入的字符串是通过网络拿到了,要注意对字符编码来避免XSS攻击。

另一种是修改innerTexttextContent属性,无法设置任何HTML标签。
两者的区别在于,innetText不返回隐藏元素的文本,textContent则返回所有文本。

修改CSS:DOM节点的style属性对应所有的CSS,可以直接获取和设置。CSS允许font-size这样的名称,但它并非JS有效名,需要在JS中改写为驼峰式命名:fontSize.

  • 插入DOM

如果这个DOM节点是空的,直接用innerHtml = '<span>child</span>'就可以修改DOM节点的内容,相当于“插入了”新的DOM节点。
如果DOM节点不是空的,有两个方法:
appendChild:把一个子节点添加到父节点的最后一个子节点。
insertBeforeparentElement.insertBefore(newElement, referenceElement);子节点会插入到referenceElement之前。

  • 删除DOM

要删除一个节点,首先要获得该节点以及它的父节点,然后,调用父节点的**removeChild()**把自己删除掉。

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

操作表单


  • 文本框,对应的,用于输入文本;
  • 口令框,对应的,用于输入口令;
  • 单选框,对应的,用于选择一项;
  • 复选框,对应的,用于选择多项;
  • 下拉框,对应的,用于选择一项;
  • 隐藏文本,对应的,用户不可见,但表单提交时会把隐藏文本发送到服务器。
  • 获取值

获得一个<input>节点的引用,直接调用value获得对应的用户输入值。
这种方法适用于textpasswordhidden以及select。但对于单选框和复选框,value属性返回的永远是HTML预设的值,而我们实际要获取的是用户是否“勾上了”选项,此时用checked判断。

  • 设置值

对于textpasswordhidden以及select,直接设置value就可以。
对于单选框和复选框,设置checkedtruefalse即可。

  • HTML5控件

HTML5新增了大量标准控件,常用的包括:datedatetimedatetime-localcolor

<input type="date" value="2015-07-01">
  • 提交表单

浏览器默认点击<button type='submit'>时提交表单,或者用户在最后一个输入框按回车键。
响应<form>本身的onsubmit事件,在提交时作修改:

<!-- 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>

注意要return true来告诉浏览器继续提交,如果return false,浏览器将不会继续提交form,这种情况通常对应用户输入有误,提示用户错误信息后终止提交form。
在检查和修改<input>时,要充分利用<input type="hidden">来传递数据。
例如,很多登录表单希望用户输入用户名和口令,但是,安全考虑,提交表单时不传输明文口令,而是口令的MD5。普通JavaScript开发人员会直接修改<input>

<!-- HTML -->
<form id="login-form" method="post" onsubmit="return checkForm()">
    <input type="text" id="username" name="username">
    <input type="password" id="input-password">
    <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>

没有name属性的<input>的数据不会被提交。

操作文件


在HTML表单中,可以上传文件的唯一控件就是<input type='file'>
注意:当一个表单包含<input type='file'>时,表单的enctype必须指定为multipart/form-datamethod必须指定为post,浏览器才能正常编码并以multipart/form-data格式发送表单的数据。
出于安全考虑,浏览器只允许用户点击<input type="file">来选择本地文件,用JavaScript对<input type="file">value赋值是没有任何效果的。当用户选择了上传某个文件后,JavaScript也无法获得该文件的真实路径.
通常,上传的文件都由后台服务器处理,JavaScript可以在提交表单时对文件扩展名做检查,以便防止用户上传无效格式的文件:

var f = document.getElementById('test-file-upload');
var filename = f.value; // 'C:\fakepath\test.png'
if (!filename || !(filename.endsWith('.jpg') || filename.endsWith('.png') || filename.endsWith('.gif'))) {
    alert('Can only upload image file.');
    return false;
}
  • File API

JvaScript对用户上传的文件操作非常有限。
HTML5的File API提供了FileFileReader两个主要对象,可以获得文件信息并读取文件。

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.lastModifiedDate;
    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的形式读取文件:
    reader.readAsDataURL(file);
});
  • 回调

JavaScript的一个重要特性就是单线程执行模式
单线程模式执行的JvaScript,如何处理多任务?
在JavaScript中,执行多任务实际上都是异步调用,比如上面的代码:

reader.readAsDataURL(file);

就会发起一个异步操作来读取文件内容。因为是异步操作,所以我们在JavaScript代码中就不知道什么时候操作结束,因此需要先设置一个回调函数:

reader.onload = function(e) {
    // 当文件读取完成后,自动调用此函数:
};

当文件读取完成后,JavaScript引擎将自动调用我们设置的回调函数。执行回调函数时,文件已经读取完毕,所以我们可以在回调函数内部安全地获得文件内容。

AJAX


在现代浏览器上写AJAX主要依靠XMLHttpRequest对象:

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;
if (window.XMLHttpRequest) {
    request = new XMLHttpRequest(); // 新建XMLHttpRequest对象
} else {
    request = new ActiveXObject('Microsoft.XMLHTTP'); // 对于低版本的IE,需要换用ActiveXObject对象。
}

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对象后,要先设置onreadystatechange的回调函数。在回调函数中,通常我们只需通过readyState === 4判断请求是否完成,如果已完成,再根据status === 200判断是否是一个成功的响应。
XMLHttpRequest对象的open()方法有3个参数,第一个参数指定是GET还是POST,第二个参数指定URL地址,第三个参数指定是否使用异步,默认是true,所以不用写。
最后调用send()方法才真正发送请求。GET请求不需要参数,POST请求需要把body部分以字符串或者FormData对象传进去。

  • 安全限制

浏览器的同源策略:默认情况下,JavaScript在发送AJAX请求时,URL的域名必须和当前页面完全一致。 (协议、端口号等都要相同)。
但是,也可以使用JavaScript请求外域的URL的方法的:
一是通过Flash插件发送HTTP请求,这种方式可以绕过浏览器的安全限制,但必须安装Flash,并且跟Flash交互。不过Flash用起来麻烦,而且现在用得也越来越少了。
二是通过在同源域名下架设一个代理服务器来转发,JavaScript负责把请求发送到代理服务器,代理服务器再把结果返回,这样就遵守了浏览器的同源策略。这种方式麻烦之处在于需要服务器端额外做开发。
第三种方式称为JSONP,它有个限制,只能用GET请求,并且要求返回JavaScript。

  • CORS

如果浏览器支持HTML5,那么就可以一劳永逸地使用新的跨域策略:CORS

Promise


在JavaScript的世界中,所有的代码都是单线程执行的。
正因如此,导致JavaScript的所有网络操作、浏览器事件都必须是异步执行。
比如,统一AJAX逻辑:2

var ajax = ajaxGet('http://...');
ajax.ifSuccess(success)
    .ifFail(fail);

不关心如何处理结果,只根据结果是成功还是失败,在将来的某个时候调用success函数或fail函数。
这种承诺将来会执行的对象在JavaScript中成为Promise对象。
例:

new Promise(test).then(function (result) {
    console.log('成功:' + result);
}).catch(function (reason) {
    console.log('失败:' + reason);
});

建立一个Promise对象,它负责执行test函数。当test函数执行成功时,then;失败时,catch
Promise还可以做更多。比如有若干个异步任务,需要先做任务1,如果成功后再做任务2,任何任务失败则不再继续并执行错误处理函数。可以这样写:

job1.then(job2).then(job3).catch(handleError);

其中,job1job2job3都是Promise对象。

Canvas


CanvasHTML5新增的组件,它就像一块幕布,可以用JavaScript在上面绘制各种图表、动画等。

在使用Canvas之前,用canvas.getContext来测试浏览器是否支持Canvas:

<canvas id="test-canvas" width="300" height="200"></canvas>

var canvas = document.getElementById('test-canvas');
if (canvas.getContext) {
    console.log('你的浏览器支持Canvas!');
} else {
    console.log('你的浏览器不支持Canvas!');
}

定义一个指定尺寸的矩形框:

<canvas id="test-canvas" width="300" height="200"></canvas>

通常在<canvas>内部添加一些说明性HTML代码,如果浏览器支持Canvas,它将忽略<canvas>内部的HTML;如果不支持Canvas,它将显示<canvas>内部的HTML:

<canvas id="test-stock" width="300" height="200">
    <p>Current Price: 25.51</p>
</canvas>

getContext('2d')方法让我们拿到一个CanvasRenderingContext2D对象,所有的绘图操作都需要通过这个对象完成。

var ctx = canvas.getContext('2d');

如果要绘制3D:

gl = canvas.getContext("webgl");
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值