一、选取DOM元素

jQuery的核心是通过各种选择器,选中DOM元素,可以用querySelectorAll方法模拟这个功能。

1

var$ = document.querySelectorAll.bind(document);

这里需要注意的是,querySelectorAll方法返回的是NodeList对象,它很像数组(有数字索引和length属性),但不是数组,不能使用pop、push等数组特有方法。如果有需要,可以考虑将Nodelist对象转为数组。

1

myList = Array.prototype.slice.call(myNodeList);

二、DOM操作

DOM本身就具有很丰富的操作方法,可以取代jQuery提供的操作方法。

尾部追加DOM元素。

1

2

3

4

// jQuery写法

  $(parent).append($(child));

  // DOM写法

  parent.appendChild(child)

头部插入DOM元素。

1

2

3

4

// jQuery写法

  $(parent).prepend($(child));

  // DOM写法

  parent.insertBefore(child, parent.childNodes[0])

删除DOM元素。

1

2

3

4

// jQuery写法

  $(child).remove()

  // DOM写法

  child.parentNode.removeChild(child)

三、事件的监听

jQuery的on方法,完全可以用addEventListener模拟。

1

Element.prototype.on = Element.prototype.addEventListener;

为了使用方便,可以在NodeList对象上也部署这个方法。

1

2

3

4

5

6

NodeList.prototype.on =function(event, fn) {

    []['forEach'].call(this,function(el) {

      el.on(event, fn);

    });

    returnthis;

  };

四、事件的触发

jQuery的trigger方法则需要单独部署,相对复杂一些。

1

2

3

4

5

6

7

8

9

Element.prototype.trigger =function(type, data) {

    varevent = document.createEvent('HTMLEvents');

    event.initEvent(type,true,true);

    event.data = data || {};

    event.eventName = type;

    event.target =this;

    this.dispatchEvent(event);

    returnthis;

  };

在NodeList对象上也部署这个方法。

1

2

3

4

5

6

NodeList.prototype.trigger =function(event) {

    []['forEach'].call(this,function(el) {

      el['trigger'](event);

    });

    returnthis;

  };

五、document.ready

目前的最佳实践,是将JavaScript脚本文件都放在页面底部加载。这样的话,其实document.ready方法(jQuery简写为$(function))已经不必要了,因为等到运行的时候,DOM对象已经生成了。

六、attr方法

jQuery使用attr方法,读写网页元素的属性。

1

$("#picture").attr("src","http://url/to/p_w_picpath");

DOM元素允许直接读取属性值,写法要简洁许多。

1

$("#picture").src ="http://url/to/p_w_picpath";

需要注意,input元素的this.value返回的是输入框中的值,链接元素的this.href返回的是绝对URL。如果需要用到这两个网页 元素的属性准确值,可以用this.getAttribute(‘value’)和this.getAttibute(‘href’)。

七、addClass方法

jQuery的addClass方法,用于为DOM元素添加一个class。

1

$('body').addClass('hasJS');

DOM元素本身有一个可读写的className属性,可以用来操作class。

1

2

3

document.body.className ='hasJS';

  // or

document.body.className +=' hasJS';

HTML 5还提供一个classList对象,功能更强大(IE 9不支持)。

1

2

3

4

document.body.classList.add('hasJS');

  document.body.classList.remove('hasJS');

  document.body.classList.toggle('hasJS');

  document.body.classList.contains('hasJS');

八、CSS

jQuery的css方法,用来设置网页元素的样式。

1

$(node).css("color","red");

DOM元素有一个style属性,可以直接操作。

1

2

3

element.style.color ="red";;

// or

element.style.cssText +='color:red';

九、数据储存

jQuery对象可以储存数据。

1

$("body").data("foo", 52);

HTML 5有一个dataset对象,也有类似的功能(IE 10不支持),不过只能保存字符串。

1

2

element.dataset.user = JSON.stringify(user);

element.dataset.score = score;

十、Ajax

jQuery的Ajax方法,用于异步操作。

1

2

3

4

5

6

7

$.ajax({

  type:"POST",

  url:"some.php",

  data: { name:"John", location:"Boston"}

}).done(function( msg ) {

 alert("Data Saved: "+ msg );

});

我们可以定义一个request函数,模拟Ajax方法。

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

functionrequest(type, url, opts, callback) {

    varxhr =newXMLHttpRequest();

    if(typeofopts ==='function') {

      callback = opts;

      opts =null;

    }

    xhr.open(type, url);

    varfd =newFormData();

    if(type ==='POST'&& opts) {

      for(varkeyinopts) {

        fd.append(key, JSON.stringify(opts[key]));

      }

    }

    xhr.onload =function() {

      callback(JSON.parse(xhr.response));

    };

    xhr.send(opts ? fd :null);

  }

然后,基于request函数,模拟jQuery的get和post方法。

1

2

varget = request.bind(this,'GET');

varpost = request.bind(this,'POST');

十一、动画

jQuery的animate方法,用于生成动画效果。

1

$foo.animate('slow', { x:'+=10px'});

jQuery的动画效果,很大部分基于DOM。但是目前,CSS 3的动画远比DOM强大,所以可以把动画效果写进CSS,然后通过操作DOM元素的class,来展示动画。

1

foo.classList.add('animate');

如果需要对动画使用回调函数,CSS 3也定义了相应的事件。

1

2

el.addEventListener("webkitTransitionEnd", transitionEnded);

el.addEventListener("transitionend", transitionEnded);