Zepto API 学习

时间:2023-03-08 17:28:50
Zepto API 学习

1.  after, before, append, prepend 的区别

A.after(B) ==== B.insertAfter(A)     // B 放在 A 的后面
A.before(B) ==== B.insertBefore(A)  // B 放在 A 的前面
A.append(B) ==== B.appendTo(A)   // B 放在 A 最后一个子元素的后面
A.prepend(B) ==== B.prependTo(A)  // B 放在 A 第一个子元素的后面

2.  children find parent parents closest 区别; 不传参数则是找到所有的元素
  children 找的是所有的直接子元素 --- 可以在同一级的子元素
  find 找的是所有子元素 --- 可以在同一级的子元素
  parent 获取对象集合中每个元素的直接父元素 --- 一定是父级,不能是父级的同级
  parents 获取对象集合每个元素所有的祖先元素 --- 一定是父级,不能是父级的同级
  closest 从元素本身开始,逐级向上级元素匹配,并返回最先匹配selector的元素--- 一定是父级,不能是父级的同级

3:  zepto-1.1.6.js 和 jquery-1.12.4.js 下, 如果是"空数组"覆盖不了"非空数组"的值。

var obj = {a: {b: [1,2]} };
var obj2 = {a: {b: []} };
$.extend(true, obj, obj2);
//obj 没变: {a: {b: [1,2]} }, 覆盖不了 var obj = {a: {b: [1,2]} };
var obj2 = {a: {b: [3]} };
$.extend(true, obj, obj2);
//obj 变了: {a: {b: [3,2]} } var obj = {a: {b: {a: 1}} };
var obj2 = {a: {b: []} };
$.extend(true, obj, obj2);
// obj 变了: {a: b: []}, 由于一个是数组,一个是对象,所以全部覆盖了

3.  $()

$(htmlString, attributes)
$("<p />", { text:"Hello", id:"greeting", css:{color:'darkblue'} })

4.  $.contains

$.contains(parent, node)
检查父节点是否包含给定的dom节点,如果两者是相同的节点,则返回 false。

$.contains( document.documentElement, document.body ); // true
$.contains( document.documentElement, $('.aaaa')[0] ); // false, $('.aaaa')[0] 是undefined

5.  $.grep

获取一个新数组,新数组只包含回调函数中返回 ture 的数组项。

$.grep([1,2,3],function(item){
return item > 1
});//=>[2,3]

6:  $.inArray

返回数组中指定元素的索引值(愚人码头注:以0为基数),如果没有找到该元素则返回-1。

$.inArray('a', ['b', 'c', 'a']) //
$.inArray('a222', ['b', 'c', 'a']) // -1

7:  $.isPlainObject
测试对象是否是“纯粹”的对象

$.isPlainObject(new Date) // => false
$.isPlainObject(window) // => false
$.isPlainObject({}) // => true

8:  $.map
通过遍历集合中的元素,返回通过迭代函数的一个新数组,null 和 undefined 将被过滤掉。
注意: 既可以遍历数组,也可以遍历对象。注意函数的参数是 item, index
遍历完对象之后返回的还是数组,所以一般不遍历对象

$.map([1,2,3,4,5],function(item, index){
  if(item>1){return item*item;}
}); // =>[4, 9, 16, 25] $.map({"yao":1,"tai":2,"yang":3},function(item,index){
  if(item>1){return item*item;}
}); // =>[4, 9]

9:  attr
attr(name, function(index, oldValue){ ... })
attr({ name: value, name2: value2, ... }) 支持对象传递

$('body').attr('data-it', 10);
$('body').attr('data-it', function(index, oldValue){
  // oldValue 为 string 格式
  return oldValue * 2;
});// => body 变成 data-it 20

10:  closest
closest(selector, [context])
closest(collection)
closest(element)
参数context 比较特殊, 它必须是 selector 的父级元素(不用直接父级)才会起作用。当它是 selector 的子元素,则阻断查找(也就是最后结果是: [] 空Zepto数组);若它是selector的父元素,则没有问题。
查看jquery-1.12.4 源代码, 重点一行 cur !== context, 若等于就阻断了

for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ){}

其它例子:

$('a').closest('.cnt')
//若 $('.cnt') 有多个集合, jquery 结果会选择多个 cnt, zepto 默认只会选择第一个 cnt
$('a').closest( $('.cnt') )
$('a').closest( document.getElementById('cnt') )
$('a').closest( document.querySelectorAll('.cnt') ) // jquery 有效, zepto无效

11:  concat
这个方法 zepto里直接使用[].concat, 返回的是原生的数组 而不是 Zepto 的数组。
联想到, 如果你需要按顺序把原生Dom 放在一个数组里,则:

var arr = [];
arr.push( $('.dom')[0] );
arr.push( $('.dom2')[0] );
arr.push( $('.dom3')[0] );
$(arr);

12:  css
css([property1, property2, ...])

$('.cnt1').css(['background-color', 'font-size', 'color'])
// {background-color: "rgb(255, 0, 0)", font-size: "", color: "rgb(0, 0, 0)"}

注意: 若css 写在 style 里<style type='text/css'> .cnt1 { font-size: 30px;} </style>, 那么 $('.cnt1').css(['backgroundColor', 'fontSize']) 取不到值, zepto 处理不好的地方,需要改成 $('.cnt').css(['background-color', 'font-size'])

13:  filter

filter 和 map 的区别是, map 里每次遍历元素时 return 的值就是实际的值。 filter 里每次元素只有 return 为 true, 那个值才会被放到集合里。
filter 和 not 刚好相反的功能

$('.cnt').filter('.cnt1')
$('.cnt').filter( $('.cnt1') ); // 这么写会报错, 而not 可以 // 只有第1个参数 index, 没有 el
$('.cnt').filter( function(index, el){
console.log(index, el); // el 为undefined
}); // 相当于 $('.cnt2')
$('.cnt').filter( function(index, el){
if( $(this).hasClass('cnt2') ){
return true;
}
});

14:  find
find 和 children 功能区别是, children只寻找直接子元素, find 是查找所有后代元素

$('.box').find( '.cnt1' )
$('.box').find( $('.cnt1') ) // 找到所有的 .cnt1
$('.box').find( $('.cnt1')[0] ) // 找到 .cnt1 的集合里的第1个

15:  get
get() ==> array
get(index) ==> DOM node

var elements = $('h2');
elements.get(); // 变成一个数组, 相当于[].slice.call(elements);
elements.get(0); // 相当于 elements[0];

16:  has
has(selector)
has(node)
判断当前对象集合的子元素是否有符合选择器的元素,或者是否包含指定的DOM节点。如果有,则返回新的对象集合。

$('.box').has('a') // 如果 box 元素里 a标签, 返回 box 集合
$('.box').has( document.getElementById('cnt1') );
//通常我项目里会这样写:
$('.box').fitler(function(){
  if( $(this).find('a').length > 0 ){
    return true;
  }
});

17:  height
height(function(index, oldHeight){ ... })

// 返回原来高度的两倍
$('a').eq(0).height(function(i, h){
  return h * 2;
});

18:  html
html(function(index, oldHtml){ ... })

19:  index
index([element]);

<div class='cnt cnt1' id='cnt1'>
  <a href='https://www.baidu.com/' class='a a1'>aaa</a>
  <div></div>
  <a href='https://www.baidu.com/' class='a a2'>aaa</a>
  <a href='https://www.baidu.com/' class='a a3'>aaa</a>
</div>
<script>
  $('.a2').index(); // 2 这个值其实不是我们想要的
  $('.a').index( $('.a2') ); // 1, 对了。源代码里其实就是用了类似 [2,3,4].indexOf(4);
</script>

20:  map
同 $.map, 不过它是遍历 zepto 对象集合.

$('a').map(function(){ return 1}) // 若有两个a, 则返回[1,1]

21:  offset
offset() ==> object
offset(coordinates) ==> self
offset(function(index, oldOffset){ ... })

$('.cnt2').offset(); // 返回一个对象 {left: 200, top: 36, width: 595, height: 18}
$('.cnt2').offset({left: 200}); // 赋值 left: 200
$('a').offset(function(index, oldOffset){ }) // oldOffset 相当于 {left: 200, top: 36, width: 595, height: 18}

22:  pluck

pluck(property) ==> array
pluck 相当于直接取属性的值, 比如 $('a').eq(0)['href'] 等同于 $('a').eq(0).pluck('href')
只不过里面的源代码里面用 $.map 包装了下, 结果返回的是属性值的集合
return $.map(this, function(el){ return el[property] })

23:  positon
它和 offset 的区别是, 假设 B元素{position: absolute; left: 300px; top: 300px;} 的offsetParent() A {position: relative; left: 100px, top: 100px}
那么 B 的 offset() 为 {top: 400, left: 400}; position 为 {top: 100, left: 100}
源代码里:

return {
  top: offset.top - parentOffset.top,
  left: offset.left - parentOffset.left
}

24:  replaceWith
用给定的内容替换所有匹配的元素。(包含元素本身)

25:  unwrap
移除集合中每个元素的直接父节点,并把他们的子元素保留在原来的位置。 基本上,这种方法删除上一的祖先元素,同时保持DOM中的当前元素。

wrap
wrap(structure)
wrap(function(index){ ... })
wrapAll
wrapInner

3者的区别是:

<div class='a'>
  <p>a</p>
  <p>b</p>
</div> $('p').wrap('<div class="b"></div>');
/* 结果是:
<div class='a'>
<div class="b">
   <p>a</p>
</div>
<div class="b">
   <p>b</p>
</div>
</div>
*/ $('p').wrapAll('<div class="b"></div>');
/* 结果是:
<div class='a'>
<div class="b">
<p>a</p>
<p>b</p>
</div>
</div>
*/ $('p').wrapInner('<div class="b"></div>');
/* 结果是:
<div class='a'>
<p><div class="b">a</div></p>
<p><div class="b">b</div></p>
</div>
*/

26:  $.proxy
$.proxy(fn, context)
$.proxy(fn, context, [additionalArguments...])
$.proxy(context, name) // 这里 property 改成 name
$.proxy(context, name, [additionalArguments...]) // 这里 property 改成 name

最常用的 $.proxy(fn, context);
$.proxy(fn, context, [additionalArguments...])

$.proxy(context, name)
The name of the function whose context will be changed (should be a property of the context object).

var obj = {
name: "John",
test: function(para, e) {
// e 必须有用户点击触发
console.log(this.name + ' sssss');
}
}; /*
test 为obj 里的 function 的名字
若直接执行 fn(), e 是取不到值的(为 undefined), 必须有用户点击事件触发。
最后一个参数始终为 event 对象
*/
var fn = jQuery.proxy(obj, "test", 'para');

27:  on
on(type, [selector], [data], function(e){ ... })
on({ type: handler, type2: handler2, ... }, [selector], [data])

$('body').on({click: function(e){
e.preventDefault();
console.log(e.data); // 输出 sss
}}, '#div', 'sss'); $('body').on('click', '#div', 'sss', function(e){
e.preventDefault();
console.log(e.data); // 输出 sss
});

28:  $.Event

var mylib = $.Event('mylib:change', {a: 1 });
$('body').on('mylib:change', function(a, b){
console.log(a);
console.log(b); // undefined, 第2个参数b 是传递不过来
});
$('html').on('mylib:change', function(){
console.log('html');
}); // 或者用 $('body').trigger('mylib:change'), 最后会冒泡到 html 上
$('body').trigger(mylib); // 若改 mylib 为
var mylib = $.Event('mylib:change', {bubbles: false});
$('body').trigger(mylib); // 将不会冒泡

29:  Ajax 请求
context (default: window): context to execute callbacks in
traditional (default: false): activate traditional (shallow) serialization of data parameters with $.param ---- 参考 $.param

Ajax callbacks 回调函数
beforeSend(xhr, settings): before the request is sent.
complete(xhr, status): after the request is complete, regardless of error or success

$.ajax({
  url:'',
  dataType: 'json',
  beforeSend: function(){},
  success: funciton(){},
  error: function(){},
  // 这个挺好用的, 不用再 success和error 里面都执行同一函数
  complete: function(){},
});

Ajax events => Ajax 事件;
1. ajaxStart
2. ajaxBeforeSend
3. ajaxSend
4. ajaxSuccess
5. ajaxError
6. ajaxComplete
7. ajaxStop

// 默认情况下,Ajax事件在document对象上触发。然而,如果请求的 context 是一个DOM节点,该事件会在此节点上触发然后再DOM中冒泡。唯一的例外是 ajaxStart & ajaxStop这两个全局事件。

$(document).on('ajaxBeforeSend', function(e, xhr, options){
// This gets fired for every Ajax request performed on the page.
// The xhr object and $.ajax() options are available for editing.
// Return false to cancel this request.
});

Content-Type

POST 默认的 Content-Type
Content-Type:application/x-www-form-urlencoded; charset=UTF-8

GET 默认的 Content-Type
jQuery和Zepto 里面源代码没有设置任何值,

若指定 contentType 为 'application/json', 则是为了传递的data是可以有深度的对象

// post a JSON payload:
$.ajax({
  type: 'POST',
  url: '/projects',
  // post payload:
  data: JSON.stringify({
    a: 1,
    b: {
      c: 2
    }
  }),
  contentType: 'application/json'
});

若用 get方式, 最后传递的可能会是: a=1&b%5Bc%5D=2, 前端可读性不好,后台也不好处理
若用 post 方式, 控制台From Data里面是 a:1, b[c]:2, 后台也是不好处理

$.ajaxSettings的设置里面有 beforeSend 和 complete, 可以设置全站的发送请求前作一些动作,比如有正在加载 loading的效果

$.ajaxSettings = {
  // Default type of request
  type: 'GET',
  // Callback that is executed before request
  beforeSend: empty,
  // Callback that is executed if the request succeeds
  success: empty,
  // Callback that is executed the the server drops error
  error: empty,
  // Callback that is executed on request complete (both: error and success)
  complete: empty,
  ....
}