学习笔记

0201-Promise-JQuery选择

Posted on 2022-02-01,11 min read
封面图

Promise

最简单的Promise例子:生成一个0-2之间的随机数,如果小于1,则等待一段时间后返回成功,否则返回失败:
resolvereject分别代表成功与失败执行的函数;

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

用一个Promise对象来执行上述函数,并根据设定的时间延迟显示结果;

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

Promise().then().then....catch() 多任务串行执行.
Promise.all([p1,p2,...]) 多任务并行执行
都要成功才进入then,返回结果数组.
Promise.race([p1,p2,...]) 多任务赛跑.
then()和catch(),谁先调用算谁的,其它任务中断.

Canvas

  • 在HTML中设定一块画布的大小与ID等属性;
  • 用JS在画图中绘画;
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
//矩形
ctx.fillStyle="#FF0000";
ctx.fillRect(0,0,150,75);
//路径
ctx.moveTo(0,0); //线条开始坐标
ctx.lineTo(200,100); //线条结束坐标
ctx.stroke();
//文本
ctx.font="30px Arial"; //字体
ctx.fillText("Hello World",10,50); //实心字
ctx.strokeText("Hello World",10,50); //空心字
//画圆
ctx.beginPath();
ctx.arc(95,50,40,0,2*Math.PI); //x,y,r,start,stop
ctx.stroke();
// ****创建渐变****
  //createLinearGradient(x,y,x1,y1) - 创建线条渐变
  //createRadialGradient(x,y,r,x1,y1,r1) - 创建一个径向/圆渐变
  var grd=ctx.createLinearGradient(0,0,200,0);
  grd.addColorStop(0,"red");
  grd.addColorStop(1,"white");
  // 填充渐变
  ctx.fillStyle=grd;
  ctx.fillRect(10,10,150,80);
//图像
var img=document.getElementById("scream");
ctx.drawImage(img,10,10);

JQuery选择器

按ID查找
#abc#开头,返回的对象是jQuery对象;如果idabc<div>存在:返回的JQuery对象为[<div id="abc">...</div>];若不存在:返回[]

// 查找<div id="abc">:
var div = $('#abc');
  • DOM与JQuery相互转化
var div = $('#abc'); // jQuery对象
var divDom = div.get(0); // 假设存在div,获取第1个DOM元素
var another = $(divDom); // 重新把DOM包装为jQuery对象

按tag查找

var ps = $('p'); // 返回所有<p>节点
ps.length; // 数一数页面有多少个<p>节点

按class查找
注意在class名称前加.

var a = $('.red'); // 所有节点包含`class="red"`都将返回
// 例如:
// <div class="red">...</div>
// <p class="green red">...</p>
  • 查找class同时包含redgreen的节点:
var a = $('.red.green'); // 注意没有空格!
// 符合条件的节点:
// <div class="red green">...</div>
// <div class="blue green red">...</div>

按属性查找
当属性存在空格 等特殊字符时需要用双引号""括起来;

var email = $('[name=email]'); // 找出<??? name="email">
var passwordInput = $('[type=password]'); // 找出<??? type="password">
var a = $('[items="A B"]'); // 找出<??? items="A B">

属性的前缀后缀查找

var icons = $('[name^=icon]'); // 找出所有name属性值以icon开头的DOM
// 例如: name="icon-1", name="icon-2"
var names = $('[name$=with]'); // 找出所有name属性值以with结尾的DOM
// 例如: name="startswith", name="endswith"
var icons = $('[class^="icon-"]'); // 找出所有class包含至少一个以`icon-`开头的DOM
// 例如: class="icon-clock", class="abc icon-home"

组合查找

var emailInput = $('input[name=email]'); // 不会找出<div name="email">, 只查找<input>标签
//tag和class组合查找
var tr = $('tr.red'); // 找出<tr class="red ...">...</tr>

多项选择器
选出的元素按在HTML中的顺序排序,且不会有重复元素;
<p class="red green">不会被下面的$('p.red,p.green')选择两次;

$('p,div'); // 把<p>和<div>都选出来
$('p.red,p.green'); // 把<p class="red">和<p class="green">都选出来

以下内容以此为例

<!-- HTML结构 -->
<div class="testing">
    <ul class="lang">
        <li class="lang-javascript">JavaScript</li>
        <li class="lang-python">Python</li>
        <li class="lang-lua">Lua</li>
    </ul>
</div>

层级选择器
$('ancestor descendant')来选择,层级之间用空格隔开;

$('ul.lang li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]
$('div.testing li.lang-javascript'); // [<li class="lang-javascript">JavaScript</li>]

选择所有的<li>节点:

$('ul.lang li');
$('form[name=upload] input'); //选择范围限定在name属性为upload的表单里
$('form.test p input'); // 多层选择,在form表单选择被<p>包含的<input>

子选择器
$('parent>child')类似层级选择器,但必须是直系父子关系;

$('ul.lang>li.lang-javascript'); // 可以选出[<li class="lang-javascript">JavaScript</li>]
$('div.testing>li.lang-javascript'); // [], 无法选出,因为<div>和<li>不构成父子关系

过滤器

$('ul.lang li'); // 选出JavaScript、Python和Lua 3个节点
$('ul.lang li:first-child'); // 仅选出JavaScript
$('ul.lang li:last-child'); // 仅选出Lua
$('ul.lang li:nth-child(2)'); // 选出第N个元素,N从1开始
$('ul.lang li:nth-child(even)'); // 选出序号为偶数的元素
$('ul.lang li:nth-child(odd)'); // 选出序号为奇数的元素

查找和过滤

查找

  • 获得一个节点ul
  • ul.find()节点内查找
<!-- HTML结构 -->
<ul class="lang">
    <li class="js dy">JavaScript</li>
    <li class="dy">Python</li>
    <li id="swift">Swift</li>
    <li class="dy">Scheme</li>
    <li name="haskell">Haskell</li>
</ul>

find()查找:

var ul = $('ul.lang'); // 获得<ul>
var dy = ul.find('.dy'); // 获得JavaScript, Python, Scheme
var swf = ul.find('#swift'); // 获得Swift
var hsk = ul.find('[name=haskell]'); // 获得Haskell

向上查找,使用parent()

var swf = $('#swift'); // 获得Swift
var parent = swf.parent(); // 获得Swift的上层节点<ul>
var a = swf.parent('.red'); // 获得Swift的上层节点<ul>,同时传入过滤条件。如果ul不符合条件,返回空jQuery对象

同一层级的节点,可以使用next()prev()方法:

var swift = $('#swift');
swift.next(); // Scheme
swift.next('[name=haskell]'); // 空的jQuery对象,因为Swift的下一个元素Scheme不符合条件[name=haskell]
swift.prev(); // Python
swift.prev('.dy'); // Python,因为Python同时符合过滤器条件.dy

过滤
和函数的mapfilter类似:
filter()过滤掉不符合条件的节点;

var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var a = langs.filter('.dy'); // 拿到JavaScript, Python, Scheme

或者也可以传入函数,注意this的指向的对象为DOM

var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
langs.filter(function () {
    return this.innerHTML.indexOf('S') === 0; // 返回S开头的节点
}); // 拿到Swift, Scheme

map()把JQuery对象中的节点转化为数组或其他形式

var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var arr = langs.map(function () {
    return this.innerHTML;
}).get(); // 用get()拿到包含string的Array:['JavaScript', 'Python', 'Swift', 'Scheme', 'Haskell']

若JQuery包含多个节点,可以用first()last()slice()返回新的JQuery对象,删除不必要节点;

var langs = $('ul.lang li'); // 拿到JavaScript, Python, Swift, Scheme和Haskell
var js = langs.first(); // JavaScript,相当于$('ul.lang li:first-child')
var haskell = langs.last(); // Haskell, 相当于$('ul.lang li:last-child')
var sub = langs.slice(2, 4); // Swift, Scheme, 参数和数组的slice()方法一致

练习

对于下面表单,输入值后,用jQuery获取表单的JSON字符串,keyvalue分别对应每个输入的name和相应的value,例如:{"name":"Michael","email":...}

<form id="test-form" action="#0" onsubmit="return false;">
    <p><label>Name: <input name="name"></label></p>
    <p><label>Email: <input name="email"></label></p>
    <p><label>Password: <input name="password" type="password"></label></p>
    <p>Gender: <label><input name="gender" type="radio" value="m" checked> Male</label> <label><input name="gender" type="radio" value="f"> Female</label></p>
    <p><label>City: <select name="city">
    	<option value="BJ" selected>Beijing</option>
    	<option value="SH">Shanghai</option>
    	<option value="CD">Chengdu</option>
    	<option value="XM">Xiamen</option>
    </select></label></p>
    <p><button type="submit">Submit</button></p>
</form>
<!--****JS脚本****-->
<script>
json = {};  //将json初始化为对象
// 利用和表单元素相关的特殊选择器
// 理解filter和map的机制
let tmp1 = $('#test-form :input').not('button').filter(function(){
    //console.log(this.type);
    return this.type !== 'radio' || this.checked;
}).map(function(){
    json[this.name] = this.value;
    return true;
});
json = JSON.stringify(json);
</script>

下一篇: 0131-DOM-文件-AJAX→

loading...