JavaScript的浏览器对象

JavaScript的浏览器对象

[TOC]

常见的内置对象

  • window对象

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

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

  • navigator

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

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

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

    1
    2
    3
    4
    5
    6
    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对象还有一个cookie属性,可以获取当前页面的Cookie。

####Document的基本操作

  • 查找节点

    要想进行dom操作,首先应该拿到dom对象。常用的方法如下:

    1
    2
    3
    4
    document.getElementById();
    document.getElementsByTagName();
    document.getElementsByClassName();
    document.getElementById(); //最常用,由于id可以唯一定位。

    如果想要通过父节点再查找子节点,可以通过:

    1
    2
    3
    4
    5
    6
    7
    8
    // 返回ID为'test'的节点:
    var test = document.getElementById('test');
    // 获取节点test下的所有直属子节点:
    var cs = test.children;
    // 获取节点test下第一个、最后一个子节点:
    var first = test.firstElementChild;
    var last = test.lastElementChild;
  • 更新节点

    1. 通过修改innerHTML属性,可以更改节点内部的结构(即支持加入html标签)

      1
      2
      3
      4
      5
      6
      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>的内部结构已修改。注意如果原来有标签的会直接替换。
    2. 通过修改innerText或者textContent,只能修改内容。无法添加标签

      1
      2
      3
      4
      5
      6
      // 获取<p id="p-id">...</p>
      var p = document.getElementById('p-id');
      // 设置文本:
      p.innerText = '<script>alert("Hi")</script>';
      // HTML被自动编码,无法设置一个<script>节点:
      // <p id="p-id">&lt;script&gt;alert("Hi")&lt;/script&gt;</p>
    3. 修改节点的样式。(因为CSS允许font-size这样的名称,但它并非JavaScript有效的属性名,所以需要在JavaScript中改写为驼峰式命名fontSize:)

      1
      2
      3
      4
      5
      6
      // 获取<p id="p-id">...</p>
      var p = document.getElementById('p-id');
      // 设置CSS:
      p.style.color = '#ff0000';
      p.style.fontSize = '20px';
      p.style.paddingTop = '2em';s
  • 插入节点

    1. 使用appendChild,把一个子节点添加到父节点的最后一个子节点。

      1
      2
      3
      4
      5
      6
      7
      <!-- HTML结构 -->
      <p id="js">JavaScript</p>
      <div id="list">
      <p id="java">Java</p>
      <p id="python">Python</p>
      <p id="scheme">Scheme</p>
      </div>
      1
      2
      3
      4
      var
      js = document.getElementById('js'),
      list = document.getElementById('list');
      list.appendChild(js);

      因为我们插入的js节点已经存在于当前的文档树,因此这个节点首先会从原先的位置删除,再插入到新的位置。假如我们需要创建一个新的dom对象:

      1
      2
      3
      4
      5
      var list = document.getElementById('list'),
      haskell = document.createElement('p');
      haskell.id = 'haskell';
      haskell.innerText = 'Haskell';
      list.appendChild(haskell);

      将某节点插入到指定节点之前:

      1
      2
      3
      4
      5
      6
      7
      var
      list = document.getElementById('list'),
      ref = document.getElementById('python'),
      haskell = document.createElement('p');
      haskell.id = 'haskell';
      haskell.innerText = 'Haskell';
      list.insertBefore(haskell, ref);
  • 删除子节点

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

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

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

表单操作

  • 获取表单的值

    对于普通输入框,可以直接表单值:

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    // <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
  • 设置表单的值:

    对于普通输入框:

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

    对于单选框和复选框,设置checkedtruefalse

    1
    2
    3
    // <label><input type="radio" name="weekday" id="monday" value="1"> Monday</label>
    var mon = document.getElementById('monday');
    mon.check=true;
  • 提交表单

    1. 通过获取表单dom,然后直接提交。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <!-- 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>

      这样破坏了正常的表单提交。推荐提交方法如():

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      <!-- 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。

      出于安全考虑,很多时候我们会对用户数据进行md5加密。

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      <!-- 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>

文件操作

  • 传统的html中,js只能获取上传文件的路径名:

    1
    2
    3
    4
    5
    6
    var f = document.getElementById('test-file-upload');
    var filename = f.value; // 'C:\study\test.png'
    if (!filename || !(filename.endsWith('.jpg') || filename.endsWith('.png') || filename.endsWith('.gif'))) {
    alert('Can only upload image file.');
    return false;
    }

    在h5中提供了读取上传文件的对象:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    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的一个重要的特性就是单线程执行模式。

    在JavaScript中,浏览器的JavaScript执行引擎在执行JavaScript代码时,总是以单线程模式执行,也就是说,任何时候,JavaScript代码都不可能同时有多于1个线程在执行。所以执行多任务实际上都是异步调用。所以上面我们在

    1
    reader.readAsDataURL(file);

    之前先设置了回调函数。

    1
    2
    3
    4
    5
    reader.onload = function(e) {
    var
    data = e.target.result; // 'data:image/jpeg;base64,/9j/4AAQSk...(base64编码)...'
    preview.style.backgroundImage = 'url(' + data + ')';
    };