zoukankan      html  css  js  c++  java
  • 【JavaScript】浏览器

    No1:

    【window】全局作用域,而且表示浏览器窗口

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

    outerWidth和outerHeight属性,可以获取浏览器窗口的整个宽高

    No2:

    【navigator】表示浏览器的信息

    appName属性:浏览器名称

    appVersion属性:浏览器版本

    language属性:浏览器设置的语言

    platform属性:操作系统类型

    userAgent属性:浏览器设定的User-Agent字符串

    No3:

    【screen】表示屏幕的信息

    width属性:屏幕宽度,单位像素

    height属性:屏幕高度,单位像素

    colorDepth属性:颜色位数,如8/16/24

    No4:

    【location】当前页面的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()--重新加载当前页面

    No5:

    【document】表示当前页面

    title属性:浏览器窗口的标题

    getElementById()和getElementByTagName()可以按ID获得一个DOM节点和按Tag名称获得一组DOM节点

    cookie属性可以获取当前页面的cookie,注意:设定了httpOnly的Cookie将不能被JavaScript读取

    No6:

    // 返回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');

    No7:

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

    No8:

    【更新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>的内部结构已修改

    第二种:innerText或textContent(可以自动对字符串进行HTML编码,保证无法设置任何HTML标签)

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

    注意:两者的区别在于读取属性时,innerText不返回隐藏元素的文本,而textContent返回所有文本。另外注意IE<9不支持textContent

    No9:

    DOM节点的style属性对应所有的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';

    No10:

    【插入DOM】

    【appendChild】把一个子节点添加到父节点的最后一个子节点

    <!-- 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>
    var
        js = document.getElementById('js'),
        list = document.getElementById('list');
    list.appendChild(js);

    运行结果

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

    或者

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

    运行结果

    <!-- HTML结构 -->
    <div id="list">
        <p id="java">Java</p>
        <p id="python">Python</p>
        <p id="scheme">Scheme</p>
        <p id="haskell">Haskell</p>
    </div>

    【insertBefore】使用parentElement.insertBefore(newElement, referenceElement);,子节点会插入到referenceElement之前。

    <!-- HTML结构 -->
    <div id="list">
        <p id="java">Java</p>
        <p id="python">Python</p>
        <p id="scheme">Scheme</p>
    </div>
    var
        list = document.getElementById('list'),
        ref = document.getElementById('python'),
        haskell = document.createElement('p');
    haskell.id = 'haskell';
    haskell.innerText = 'Haskell';
    list.insertBefore(haskell, ref);

    运行结果

    <!-- HTML结构 -->
    <div id="list">
        <p id="java">Java</p>
        <p id="haskell">Haskell</p>
        <p id="python">Python</p>
        <p id="scheme">Scheme</p>
    </div>

    循环一个父节点的所有子节点,可以通过迭代children属性实现

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

    No11:

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

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

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

    No12:

    【表单】

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

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

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

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

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

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

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

    提交表单

    第一种:

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

    第二种:

    <!-- 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修改密码为md5值

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

    No13:

    【操作文件】

    当一个表单包含<input type="file">时,表单的enctype必须指定为multipart/form-datamethod必须指定为post,浏览器才能正确编码并以multipart/form-data格式发送表单的数据。

    检查文件后缀

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

    h5读取图片

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

    No14:

    JavaScript的一个重要的特性就是单线程执行模式

    No15:

    【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('请求已发送,请等待响应...');

    异步执行可以用回调函数实现

    No16:

    【Promise】承诺式

    function test(resolve, reject) {
        var timeOut = Math.random() * 2;
        log('set timeout to: ' + timeOut + ' seconds.');
        setTimeout(function () {
            if (timeOut < 1) {
                log('call resolve()...');
                resolve('200 OK');
            }
            else {
                log('call reject()...');
                reject('timeout in ' + timeOut + ' seconds.');
            }
        }, timeOut * 1000);
    }

    这个test()函数有两个参数,这两个参数都是函数,如果执行成功,我们将调用resolve('200 OK'),如果执行失败,我们将调用reject('timeout in ' + timeOut + ' seconds.')。可以看出,test()函数只关心自身的逻辑,并不关心具体的resolvereject将如何处理结果。

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

    简化为

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

    Promise最大的好处是在异步执行的流程中,把执行代码和处理结果的代码清晰地分离了

    No17:

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

    <canvas id="test-stock" width="300" height="200">
        <p>Current Price: 25.51</p>
    </canvas>
    var
        canvas = document.getElementById('test-shape-canvas'),
        ctx = canvas.getContext('2d');
    ctx.clearRect(0, 0, 200, 200); // 擦除(0,0)位置大小为200x200的矩形,擦除的意思是把该区域变为透明
    ctx.fillStyle = '#00ff00'; // 设置颜色
    ctx.fillRect(10, 10, 130, 130); // 把(10,10)位置大小为130x130的矩形涂色
    // 利用Path绘制复杂路径:
    var path=new Path2D();
    path.arc(75, 75, 50, 0, Math.PI*2, true);
    path.moveTo(110,75);
    path.arc(75, 75, 35, 0, Math.PI, false);
    path.moveTo(65, 65);
    path.arc(60, 65, 5, 0, Math.PI*2, true);
    path.moveTo(95, 65);
    path.arc(90, 65, 5, 0, Math.PI*2, true);
    ctx.strokeStyle = '#0000ff';
    ctx.stroke(path);

    效果图

    var
        canvas = document.getElementById('test-text-canvas'),
        ctx = canvas.getContext('2d');
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    ctx.shadowOffsetX = 2;
    ctx.shadowOffsetY = 2;
    ctx.shadowBlur = 2;
    ctx.shadowColor = '#666666';
    ctx.font = '24px Arial';
    ctx.fillStyle = '#333333';
    ctx.fillText('带阴影的文字', 20, 40);

    效果图

    【JS实现K线图】

    'use strict';
    
    window.loadStockData = function (r) {
        var
            NUMS = 30,
            data = r.data;
        if (data.length > NUMS) {
            data = data.slice(data.length - NUMS);
        }
        data = data.map(function (x) {
            return {
                date: x[0],
                open: x[1],
                close: x[2],
                high: x[3],
                low: x[4],
                vol: x[5],
                change: x[6]
            };
        });
        window.drawStock(data);
    }
    
    window.drawStock = function (data) {
    var
      canvas = document.getElementById('stock-canvas'),
      width = canvas.width,
      height = canvas.height,
      ctx = canvas.getContext('2d');
    console.log(JSON.stringify(data));
    ctx.clearRect(0, 0, width, height);
    ctx.fillStyle = 'black';
    ctx.fillText('Test Canvas', 10, 10);
    
    // 价格基准点
    var base_price = data[0].open;
    // 整K的y轴基准位置
    var base_y = 100;
    // k线图缩小比例
    var scale = 4;
    // 日K的宽度/2
    var single_width_half = 3;
    // 日K的宽度
    var single_width_solo = single_width_half * 2;
    // 日K的间隔
    var single_margin = 2;
    // 日K加间隔的宽度
    var single_width = single_width_solo + single_margin;
    
    for (var i in data) {
      // 收盘大于开盘,涨!红色。
      // 收盘小于开盘,跌!绿色。
      // 收盘等于开盘,横盘!灰色。
      if (data[i].close > data[i].open) {
        ctx.fillStyle = 'red';
        ctx.strokeStyle = 'red';
      } else if (data[i].close < data[i].open) {
        ctx.fillStyle = 'green';
        ctx.strokeStyle = 'green';
      } else {
        ctx.fillStyle = 'grey';
        ctx.strokeStyle = 'grey';
      }
      // 开/收高点
      var open_close_high = data[i].open > data[i].close ? data[i].open : data[i].close;
      // 开/收低点
      var open_close_low = data[i].open < data[i].close ? data[i].open : data[i].close;
    
      // 画开收矩形,开/收作为矩形的上下点
      var rect_start = base_y - (open_close_high - base_price) / scale;
      var rect_height = (Math.abs(data[i].open - data[i].close)) / scale;
      ctx.fillRect(20 + single_width * i, rect_start, single_width_solo, rect_height);
    
      // 画高直线,当高点大于开收高点,才会有高直线
      if (data[i].high > open_close_high) {
        var high_line_start = base_y - (data[i].high - base_price) / scale;
        var high_line_end = base_y - (open_close_high - base_price) / scale;
        ctx.beginPath();
        ctx.moveTo(20 + single_width_half + single_width * i, high_line_start);
        ctx.lineTo(20 + single_width_half + single_width * i, high_line_end);
        ctx.stroke();
      }
    
      // 画低直线,当低点大于开收低点,才会有低直线
      if(data[i].low < open_close_low) {
        var low_line_start = base_y - (open_close_high - base_price) / scale;
        var low_line_end = base_y - (data[i].low - base_price) / scale;
        ctx.beginPath();
        ctx.moveTo(20 + single_width_half + single_width * i, low_line_start);
        ctx.lineTo(20 + single_width_half + single_width * i, low_line_end);
        ctx.stroke();
      }
    }
    };
    
    // 加载最近30个交易日的K线图数据:
    var js = document.createElement('script');
    js.src = 'http://img1.money.126.net/data/hs/kline/day/history/2015/0000001.json?callback=loadStockData&t=' + Date.now();
    document.getElementsByTagName('head')[0].appendChild(js);

    效果图

     

    这个感觉屌屌的

  • 相关阅读:
    YUV图片旋转
    mac http&git代理配置
    iOS 如何保持线程一直在运转
    iOS 后台录音Tweak实现参考--stackoverflow
    NSTimer的精确度
    svn递归添加目录下面所有文件
    利用instruments工具查看其它app的性能
    iOS符号表手工还原
    Hbase的安装测试工作
    Hadoop集群中pig工具的安装过程记录
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/9330850.html
Copyright © 2011-2022 走看看