• JavaScript 浏览器对象


    window

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

    window对象有innerWidthinnerHeight属性,可以获取浏览器窗口的内部宽度和高度。内部宽高是指除去菜单栏、工具栏、边框等占位元素后,用于显示网页的净宽高。还有一个outerWidthouterHeight属性,可以获取浏览器窗口的整个宽高。

    补充:

    网页可见区域宽:document.body.clientWidth 
    网页可见区域高:document.body.clientHeight 
    网页可见区域宽:document.body.offsetWidth (包括边线和滚动条的宽) 
    网页可见区域高:document.body.offsetHeight (包括边线的宽) 
    网页正文全文宽:document.body.scrollWidth 
    网页正文全文高:document.body.scrollHeight 
    网页被卷去的高:document.body.scrollTop 或者 jQuery(document).scrollTop() 
    网页被卷去的左:document.body.scrollLeft 
    网页正文部分上:window.screenTop 
    网页正文部分左:window.screenLeft 
    屏幕分辨率的高:window.screen.height 
    屏幕分辨率的宽:window.screen.width 
    屏幕可用工作区高度:window.screen.availHeight 
    屏幕可用工作区宽度:window.screen.availWidth 
    屏幕彩色位数: window.screen.colorDepth 
    屏幕像素/英寸比例: window.screen.deviceXDPI 
    浏览器窗口的高度: $(window).height() 
    浏览器窗口的宽度: $(window).width() 
    View Code
    特殊1: 
    document.body.scrollTop总为0的解决方法 
    var scrollPos; 
    if (typeof window.pageYOffset != 'undefined') { 
    scrollPos = window.pageYOffset; 
    } 
    else if (typeof document.compatMode != 'undefined' && 
    document.compatMode != 'BackCompat') { 
    scrollPos = document.documentElement.scrollTop; 
    } 
    else if (typeof document.body != 'undefined') { 
    scrollPos = document.body.scrollTop; 
    } 
    alert(scrollPos ); 
    
    特殊2: 
    网页正文全文宽:"+ document.body.scrollWidth; 
    网页正文全文高:"+ document.body.scrollHeight; 
    以上函数有时获取不了,就用以下方法。 
    var xScroll, yScroll; 
    if (window.innerHeight && window.scrollMaxY) 
    { 
    xScroll = document.body.scrollWidth; 
    yScroll = window.innerHeight + window.scrollMaxY; 
    } else if (document.body.scrollHeight > document.body.offsetHeight){ // all but Explorer Mac 
    xScroll = document.body.scrollWidth; 
    yScroll = document.body.scrollHeight; 
    } else { //Explorer Mac...would also work in Explorer 6 Strict, Mozilla and Safari 
    xScroll = document.body.offsetWidth; 
    yScroll = document.body.offsetHeight; 
    }
    View Code

    navigator对象表示浏览器的信息,最常用的属性包括:

    • navigator.appName:浏览器名称;

    • navigator.appVersion:浏览器版本;

    • navigator.language:浏览器设置的语言;

    • navigator.platform:操作系统类型;

    • navigator.userAgent:浏览器设定的User-Agent字符串。

    初学者为了针对不同浏览器编写不同的代码,喜欢用if判断浏览器版本,例如:

    var width;
    if (getIEVersion(navigator.userAgent) < 9) {
        width = document.body.clientWidth;
    } else {
        width = window.innerWidth;
    }

    但这样既可能判断不准确,也很难维护代码。正确的方法是充分利用JavaScript对不存在属性返回undefined的特性,直接用短路运算符||计算:

    var width = window.innerWidth || document.body.clientWidth;

    screen

    screen对象表示屏幕的信息,常用的属性有:

    • screen.width:屏幕宽度,以像素为单位;

    • screen.height:屏幕高度,以像素为单位;

    • screen.colorDepth:返回颜色位数,如8、16、24。

    location

    location对象表示当前页面的URL信息。例如,一个完整的URL:

    http://www.example.com:8080/path/index.html?a=1&b=2#TOP

    可以用location.href获取。要获得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树的根节点。

    documenttitle属性是从HTML文档中的<title>xxx</title>读取的,但是可以动态改变:

    document对象还有一个cookie属性,可以获取当前页面的Cookie。

    Cookie是由服务器发送的key-value标示符。因为HTTP协议是无状态的,但是服务器要区分到底是哪个用户发过来的请求,就可以用Cookie来区分。当一个用户成功登录后,服务器发送一个Cookie给浏览器,例如user=ABC123XYZ(加密的字符串)...,此后,浏览器访问该网站时,会在请求头附上这个Cookie,服务器根据Cookie即可区分出用户。

    Cookie还可以存储网站的一些设置,例如,页面显示的语言等等。

    JavaScript可以通过document.cookie读取到当前页面的Cookie:

    document.cookie; // 'v=123; remember=true; prefer=zh'

    由于JavaScript能读取到页面的Cookie,而用户的登录信息通常也存在Cookie中,这就造成了巨大的安全隐患,这是因为在HTML页面中引入第三方的JavaScript代码是允许的:

    <!-- 当前页面在wwwexample.com -->
    <html>
        <head>
            <script src="http://www.foo.com/jquery.js"></script>
        </head>
    </html>

    如果引入的第三方的JavaScript中存在恶意代码,则www.foo.com网站将直接获取到www.example.com网站的用户登录信息。

    为了解决这个问题,服务器在设置Cookie时可以使用httpOnly,设定了httpOnly的Cookie将不能被JavaScript读取。这个行为由浏览器实现,主流浏览器均支持httpOnly选项,为了确保安全,服务器端在设置Cookie时,应该始终坚持使用httpOnly

    document.write() 仅仅向文档输出新内容
    如果在文档已完成加载后执行 document.write,整个 HTML 页面将被覆盖:
    参考:http://www.w3school.com.cn/tiy/t.asp?f=js_write_over

    DOM | Document

    // 返回ID为'test'的节点:
    var test = document.getElementById('test');
    // 获取节点test下的所有直属子节点:
    var cs = test.children;
    var first = test.firstElementChild;

    第二种方法是使用querySelector()querySelectorAll(),需要了解selector语法,然后使用条件来获取节点,更加方便:

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

    严格地讲,我们这里的DOM节点是指Element,但是DOM节点实际上是Node,在HTML中,Node包括ElementCommentCDATA_SECTION等很多种,以及根节点Document类型,但是,绝大多数时候我们只关心Element,也就是实际控制页面结构的Node,其他类型的Node忽略即可。根节点Document已经自动绑定为全局变量document。 

    修改Dom

    修改CSS也是经常需要的操作。DOM节点的style属性对应所有的CSS,可以直接获取或设置。因为CSS允许font-size这样的名称,但它并非JavaScript有效的属性名,所以需要在JavaScript中改写为驼峰式命名fontSize

    // 获取<p id="p-id">...</p>var p = document.getElementById('p-id');
    // 设置CSS:
    p.style.color = '#ff0000';
    p.style.fontSize = '20px';
    p.style.paddingTop = '2em';

    插入DOM

    有两个办法可以插入新的节点。一个是使用appendChild,把一个子节点添加到父节点的最后一个子节点。例如:

    <!-- HTML结构 -->
    <p id="js">JavaScript</p>
    <div id="list">
        <p id="scheme">Scheme</p>
    </div>

    <p id="js">JavaScript</p>添加到<div id="list">的最后一项:

    var js = document.getElementById('js'), list = document.getElementById('list');
    list.appendChild(js);

    现在,HTML结构变成了这样:

    <!-- HTML结构 --><div id="list">
        <p id="scheme">Scheme</p>
        <p id="js">JavaScript</p>
    </div>

    因为我们插入的js节点已经存在于当前的文档树,因此这个节点首先会从原先的位置删除,再插入到新的位置。

    更多的时候我们会从零创建一个新的节点,然后插入到指定位置: 

     haskell = document.createElement('p');

    动态创建一个节点然后添加到DOM树中,可以实现很多功能。举个例子,下面的代码动态创建了一个<style>节点,然后把它添加到<head>节点的末尾,这样就动态地给文档添加了新的CSS定义:

    var d = document.createElement('style');
    d.setAttribute('type', 'text/css');
    d.innerHTML = 'p { color: red }';
    document.getElementsByTagName('head')[0].appendChild(d); 

    insertBefore

    如果我们要把子节点插入到指定的位置怎么办?可以使用parentElement.insertBefore(newElement, referenceElement);,子节点会插入到referenceElement之前。 

    很多时候,需要循环一个父节点的所有子节点,可以通过迭代children属性实现:

    var
        i, c,
        list = document.getElementById('list');
    for (i = 0; i < list.children.length; i++) {
        c = list.children[i]; // 拿到第i个子节点
    }

    删除DOM

    要删除一个节点,首先要获得该节点本身以及它的父节点,然后,调用父节点的removeChild把自己删掉:

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

    注意到删除后的节点虽然不在文档树中了,但其实它还在内存中,可以随时再次被添加到别的位置。

    当你遍历一个父节点的子节点并进行删除操作时,要注意,children属性是一个只读属性,并且它在子节点变化时会实时更新。因此,删除多个节点时,要注意children属性时刻都在变化。

    操作表单 

    用JavaScript操作表单和操作DOM是类似的,因为表单本身也是DOM树。

    不过表单的输入框、下拉框等可以接收用户输入,所以用JavaScript来操作表单,可以获得用户输入的内容,或者对一个输入框设置新的内容。

    HTML表单的输入控件主要有以下几种:

    • 文本框,对应的<input type="text">,用于输入文本;

    • 口令框,对应的<input type="password">,用于输入口令;

    • 单选框,对应的<input type="radio">,用于选择一项;

    • 复选框,对应的<input type="checkbox">,用于选择多项;

    • 下拉框,对应的<select>,用于选择一项;

    • 隐藏文本,对应的<input type="hidden">,用户不可见,但表单提交时会把隐藏文本发送到服务器。

    获取值

    如果我们获得了一个<input>节点的引用,就可以直接调用value获得对应的用户输入值:

    // <input type="text" id="email">
    var input = document.getElementById('email');
    input.value; // '用户输入的值'

    这种方式可以应用于textpasswordhidden以及select。但是,对于单选框和复选框,value属性返回的永远是HTML预设的值,而我们需要获得的实际是用户是否“勾上了”选项,所以应该用checked判断:

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

    设置值

    设置值和获取值类似,对于textpasswordhidden以及select,直接设置value就可以:

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

    对于单选框和复选框,设置checkedtruefalse即可。

    HTML5控件

    HTML5新增了大量标准控件,常用的包括datedatetimedatetime-localcolor等,它们都使用<input>标签:

    <input type="date" value="2015-07-01">

    <input type="datetime-local" value="2015-07-01T02:03:04">

    <input type="color" value="#ff0000">

    不支持HTML5的浏览器无法识别新的控件,会把它们当做type="text"来显示。支持HTML5的浏览器将获得格式化的字符串。例如,type="date"类型的inputvalue将保证是一个有效的YYYY-MM-DD格式的日期,或者空字符串。 

    提交表单

    最后,JavaScript可以以两种方式来处理表单的提交(AJAX方式在后面章节介绍)。

    方式一是通过<form>元素的submit()方法提交一个表单,例如,响应一个<button>click事件,在JavaScript代码中提交表单:

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

    这种方式的缺点是扰乱了浏览器对form的正常提交。浏览器默认点击<button type="submit">时提交表单,或者用户在最后一个输入框按回车键。因此,第二种方式是响应<form>本身的onsubmit事件,在提交form时作修改:

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

    <form id="login-form" method="post" onsubmit="return checkForm()">
        <input type="text" id="username" name="username">
        <input type="password" id="password" name="password">
        <button type="submit">Submit</button></form>
    <script>
    function checkForm() {
        var pwd = document.getElementById('password');    // 把用户输入的明文变为MD5:
        pwd.value = toMD5(pwd.value);    // 继续下一步:
        return true;
    }</script>

    这个做法看上去没啥问题,但用户输入了口令提交时,口令框的显示会突然从几个*变成32个*(因为MD5有32个字符)。

    要想不改变用户的输入,可以利用<input type="hidden">实现:

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

    注意到idmd5-password<input>标记了name="password",而用户输入的idinput-password<input>没有name属性。没有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	est.png'
    if (!filename || !(filename.endsWith('.jpg') || filename.endsWith('.png') || filename.endsWith('.gif'))) {
        alert('Can only upload image file.');
        return false;
    }

    File API

    由于JavaScript对用户上传的文件操作非常有限,尤其是无法读取文件内容,使得很多需要操作文件的网页不得不用Flash这样的第三方插件来实现。

    随着HTML5的普及,新增的File API允许JavaScript读取文件内容,获得更多的文件信息。

    HTML5的File API提供了FileFileReader两个主要对象,可以获得文件信息并读取文件。

    下面的例子演示了如何读取用户选取的图片文件,并在一个<div>中预览图像:

    图片预览:

     

    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);
    });

    上面的代码演示了如何通过HTML5的File API读取文件内容。以DataURL的形式读取到的文件是一个字符串,类似于data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...,常用于设置图像。如果需要服务器端处理,把字符串base64后的字符发送给服务器并用Base64解码就可以得到原始文件的二进制内容。 

    回调

    上面的代码还演示了JavaScript的一个重要的特性就是单线程执行模式。在JavaScript中,浏览器的JavaScript执行引擎在执行JavaScript代码时,总是以单线程模式执行,也就是说,任何时候,JavaScript代码都不可能同时有多于1个线程在执行。

    你可能会问,单线程模式执行的JavaScript,如何处理多任务?

    在JavaScript中,执行多任务实际上都是异步调用,比如上面的代码:

    reader.readAsDataURL(file);

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

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

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



  • 相关阅读:
    Vue 备
    mac 下如何建立vue-cli项目
    24,25-request对象
    nodejs 备忘
    nodejs中mysql断线重连
    创建node.js,blog
    Mac 升级node与npm
    js 弹出层,以及在javascript里定义层样式
    js 光标选中 操作
    js 捕获型事件
  • 原文地址:https://www.cnblogs.com/284628487a/p/5551155.html
Copyright © 2020-2023  润新知