阅读更多

7顶
4踩

Web前端

转载新闻 网站如何做到 jQuery-free?

2013-05-13 10:49 by 副主编 WnouM 评论(17) 有18269人浏览
本文转载自阮一峰的博客,作者在文中讨论了如何使用JavaScript标准语法,取代越来越臃肿的jQuery,做到jQuery-free。原文内容如下:



jQuery是现在最流行的JavaScript工具库

统计,目前全世界57.3%的网站使用它。也就是说,10个网站里面,有6个使用jQuery。如果只考察使用工具库的网站,这个比例就会上升到惊人的91.7%。

虽然jQuery如此受欢迎,但是它臃肿的体积也让人头痛不已。jQuery 2.0的原始大小为235KB,优化后为81KB;如果是支持IE6、7、8的jQuery 1.8.3,原始大小为261KB,优化后为91KB。

这样的体积,即使是宽带环境,完全加载也需要1秒或更长,更不要说移动设备了。这意味着,如果你使用了jQuery,用户至少延迟1秒,才能看到网页效果。考虑到本质上,jQuery只是一个操作DOM的工具,我们不仅要问:如果只是为了几个网页特效,是否有必要动用这么大的库?

2006年,jQuery诞生的时候,主要用于消除不同浏览器的差异(主要是IE6),为开发者提供一个简洁的统一接口。相比当时,如今的情况已经发生了很大的变化。IE的市场份额不断下降,以ECMAScript为基础的JavaScript标准语法,正得到越来越广泛的支持。开发者直接使用JavScript标准语法,就能同时在各大浏览器运行,不再需要通过jQuery获取兼容性。

下面就探讨如何用JavaScript标准语法,取代jQuery的一些主要功能,做到jQuery-free。

一、选取DOM元素

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

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


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

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


二、DOM操作

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

尾部追加DOM元素。

  // jQuery写法
  $(parent).append($(child));

  // DOM写法
  parent.appendChild(child)


头部插入DOM元素。

  // jQuery写法
  $(parent).prepend($(child));
  // DOM写法
  parent.insertBefore(child, parent.childNodes[0])


删除DOM元素。

  // jQuery写法
  $(child).remove()
  // DOM写法
  child.parentNode.removeChild(child)


三、事件的监听

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

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


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

  NodeList.prototype.on = function (event, fn) {
    []['forEach'].call(this, function (el) {
      el.on(event, fn);
    });
    return this;
  };


四、事件的触发

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

  Element.prototype.trigger = function (type, data) {
    var event = document.createEvent('HTMLEvents');
    event.initEvent(type, true, true);
    event.data = data || {};
    event.eventName = type;
    event.target = this;
    this.dispatchEvent(event);
    return this;
  };


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

  NodeList.prototype.trigger = function (event) {
    []['forEach'].call(this, function (el) {
      el['trigger'](event);
    });
    return this;
  };


五、document.ready

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

六、attr方法

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

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


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

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


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

七、addClass方法

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

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


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

  document.body.className = 'hasJS';
  // or
  document.body.className += ' hasJS';


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

  document.body.classList.add('hasJS');
  document.body.classList.remove('hasJS');
  document.body.classList.toggle('hasJS');
  document.body.classList.contains('hasJS');


八、CSS

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

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


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

  element.style.color = "red";;
  // or
  element.style.cssText += 'color:red';


九、数据储存

jQuery对象可以储存数据。

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


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

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


十、Ajax

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

  $.ajax({
    type: "POST",
    url: "some.php",
    data: { name: "John", location: "Boston" }
  }).done(function( msg ) {
    alert( "Data Saved: " + msg );
  });


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

  function request(type, url, opts, callback) {
    var xhr = new XMLHttpRequest();
    if (typeof opts === 'function') {
      callback = opts;
      opts = null;
    }
    xhr.open(type, url);
    var fd = new FormData();
    if (type === 'POST' && opts) {
      for (var key in opts) {
        fd.append(key, JSON.stringify(opts[key]));
      }
    }
    xhr.onload = function () {
      callback(JSON.parse(xhr.response));
    };
    xhr.send(opts ? fd : null);
  }


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

  var get = request.bind(this, 'GET');
  var post = request.bind(this, 'POST');


十一、动画

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

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


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

  foo.classList.add('animate');


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

  el.addEventListener("webkitTransitionEnd", transitionEnded);
  el.addEventListener("transitionend", transitionEnded);


十二、替代方案

由于jQuery体积过大,替代方案层出不穷。

其中,最有名的是zepto.js。它的设计目标是以最小的体积,做到最大兼容jQuery的API。zepto.js 1.0版的原始大小是55KB,优化后是29KB,gzip压缩后为10KB。

如果不求最大兼容,只希望模拟jQuery的基本功能,那么,min.js优化后只有200字节,而dolla优化后是1.7KB。

此外,jQuery本身采用模块设计,可以只选择使用自己需要的模块。具体做法参见它的github网站,或者使用专用的Web界面

十三、参考链接

  • 大小: 20.4 KB
7
4
评论 共 17 条 请登录后发表评论
17 楼 u010322546 2013-07-16 10:25
学习了!!!
16 楼 yixiandave 2013-05-20 15:54
个人不认为加载一个jquery库比加载一张图片更费力,不过写出来都值得鼓励
15 楼 zhukewen_java 2013-05-16 17:50
目前而言,虽然网速不怎样,但还是不用考虑几一两百k的差别的
14 楼 dk-deathknight 2013-05-15 10:45
或许应用场景不多,但还是感谢作者的分享。远比那些怕丢面子而不发表文章要强多了!
13 楼 pdreamer 2013-05-15 09:52
pdreamer 写道
扯蛋,闲得蛋疼了。
jQuery.min.js 1.9 经过gz压缩后32K而已,而且现在的web服务器都是多线程下载的。

在天朝你这么做一个ie6就可以整死你。

web浏览器都是多线程下载的
12 楼 pdreamer 2013-05-15 09:51
扯蛋,闲得蛋疼了。
jQuery.min.js 1.9 经过gz压缩后32K而已,而且现在的web服务器都是多线程下载的。

在天朝你这么做一个ie6就可以整死你。
11 楼 非法用户 2013-05-14 20:34
也就第一次慢一点,以后看到的都是304 Not Modified了吧,哪里还有那么长的延迟?一知半解就出来写文章,很丢人的
10 楼 osacar 2013-05-14 18:05
91K...我们还是忍了吧!
也不差这么一点了。
9 楼 jjfat 2013-05-14 16:33
用Javascript替代jQuery不太现实,如果觉得jQuery比较大,可以使用jQuery的编译工具来编译自己需要的部分(参考:http://www.gbin1.com/technology/jquery/20120921-build-your-own-jquery/),例如, ajax, dom操作, 现在网站最大的瓶颈是图片, 随便一张就是几百k,所以绝对不是js的问题。
8 楼 freezingsky 2013-05-13 19:04
第一感觉,我觉得有点扯!
7 楼 liqingyuan 2013-05-13 17:26
这个文章太荒谬了吧,作者不知道浏览器有缓存么?JS库的JS文件怎么可能不走缓存?甚至你自己的网站都没必要有JQUERY,直接用JQUERY官方提供的CDN版本不就行了。
6 楼 houyujiangjun 2013-05-13 15:41
akhuting 写道
jquery不在于操作Dom,而在于插件

正解.....  这个讨论没有必要了,  如果几乎用不到什么依赖的插件,而且本身对js的性能没什么要求, jquery当然可以不用
5 楼 nakupanda 2013-05-13 15:35
damoqiongqiu 写道
nakupanda 写道
damoqiongqiu 写道
原生API有一个shi一般的特点,那就是巨长无比的函数名,类似getElementById这种函数名完全是有病。


短函数名却提供SHI一样的表义效果

类似$这种东西表义效果确实太差,但是getElementById这种东西就实在太二了,搞成getEl("...")你觉得如何?


我学习JAVA那个时代函数名都是这样长的... 所以我觉得长函数名没什么问题 当然不要长得太夸张
4 楼 damoqiongqiu 2013-05-13 14:04
nakupanda 写道
damoqiongqiu 写道
原生API有一个shi一般的特点,那就是巨长无比的函数名,类似getElementById这种函数名完全是有病。


短函数名却提供SHI一样的表义效果

类似$这种东西表义效果确实太差,但是getElementById这种东西就实在太二了,搞成getEl("...")你觉得如何?
3 楼 nakupanda 2013-05-13 11:42
damoqiongqiu 写道
原生API有一个shi一般的特点,那就是巨长无比的函数名,类似getElementById这种函数名完全是有病。


短函数名却提供SHI一样的表义效果
2 楼 damoqiongqiu 2013-05-13 11:39
原生API有一个shi一般的特点,那就是巨长无比的函数名,类似getElementById这种函数名完全是有病。
1 楼 akhuting 2013-05-13 10:51
jquery不在于操作Dom,而在于插件

发表评论

您还没有登录,请您登录后再发表评论

相关推荐

  • 2024年甲骨文新版官网下载JavaSDK各个版本的方法

    最近甲骨文官网又改版了,导致下载一些较早的jdk找不到在哪下载,新版取消了logo旁边的菜单按钮,改到导航栏中了 点击Products,选择Java,如下: 进入后,可以直接点击右边的下载按钮,如下: 也可以往...

  • 【最新】Oracle官网Java SE各个版本JDK下载位置

    @TOC Oracle官网Java SE各个版本JDK下载位置 下载链接 link.https://www.oracle.com/java/technologies/downloads/archive/ 前情提要:先注册一个Oracle的账号,用邮箱注册就可以,不麻烦,只有登录Oracle账户才能...

  • Java各个历史版本下载链接

    Java各个历史版本下载链接 今天准备去下载jdk1.7,但是进入官网后只找到了最新版本的下载地址,最后终于找到一个链接可以显示所有历史版本,特记录以便以后查询 ...C:\Prog

  • JAVA各个版本特点总结

    这两天看了部分《Java7高级进阶》,对Java的发展进程及版本区别也有了更深刻的了解,下面是总结摘抄Java各个版本的特点跟大家分享一下。 1、JDK1.0(1996年1月23日)代号:OakJDK1.0本身非常小,差不多212个类、8个...

  • Java 7~14各个版本新特性详解

    Java 7 特性列表 switch中添加对String类型的支持 数字字面量的改进 / 数值可加下划 异常处理(捕获多个异常) try-with-resources 增强泛型推断 JSR203 NIO2.0(AIO)新IO的支持 JSR292与InvokeDynamic指令 ...

  • 如何找到Neo4j需要的Java版本

    在安装Neo4j时,需要确保安装对应的Java版本,我们可以在Neo4j的官网的安装手册里找到需要的安装版本,链接和图如下 System requirements - Operations Manual

  • 超详细JDK1.8所有版本下载地址

    超详细JDK1.8所有版本下载地址

  • 愤怒!竟然还有学校还在教 Java 的 Swing

    昨天,有个读者私信我说,“老师正在教 Swing,这个知识点还需要学习吗?” 说句实在话,刚看到这个问题的时候,我是想骂娘的!不是骂读者啊,你懂得,骂学校,骂老师。但我硬是掐着自己的大腿忍住了,很客气地回复...

  • 10万字208道Java经典面试题总结(附答案)

    1、JDK 和 JRE 有什么区别? JDK(Java Development Kit),Java开发工具包 JRE(Java Runtime Environment),Java运行环境 JDK中包含JRE,JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib,bin就是JVM,...

  • Java JDK 1.8 下载及其版本说明 8u202(最后一个免费版)

    默认看到的都是各个版本的最新一个版本,如果想要下载自己指定的版本,需要找到归档,归档版本在哪里呢,往下滑划到最下面哦,如下图? 点击 DownLoad! 按钮,即可打开链接,结果见下图 点击JavaSE8(8u202 and ...

  • Java面试题总结(附答案)

    Java经典面试题系列。

  • JAVA8之后的版本履历

    目录 一、JDK介绍 1.1 Java 的发布周期 1.2 OpenJDK VS Oracle JDK 1.3 Android 和 JDK 1.4 JVM 和 TCK ...1.6 Oracle 和 Google 关于 ...二、JAVA版本发布 2.1 JAVA8 2.1.1Lambda 和 函数式接口 2.1.2. 方法引...

  • Java框架总结

    本系列用来记录常用java框架的基本概念、区别及联系,也记录了在使用过程中,遇到的一些问题的解决方法,方便自己查看,也方便大家查阅。 欲速则不达,欲达则欲速! 一、SSH 1、基本概念 SSH框架是JAVA EE中三种...

  • jdk(Windows/Mac含M1/M2 Arm原生JDK)安装,附各个版本JDK下载链接

    Windows、Mac下JDK安装及配置 含各个版本JDK下载链接 含Arm原生JDK下载链接

  • 基于Java+SpringBoot+vue+elementui社区疫情防控系统详细设计实现

    博主介绍:✌公司项目主程、全网粉丝20W+,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,CSDN博客之星TOP100、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业设计✌ 文末获取...

  • java 容器都有哪些?

    容器可以说是Java Core中比较重要的一部分了。 数组,String,java.util下的集合容器 ============================================================================== 数组长度限制为 Integer.Integer.MAX_...

  • Java基础知识面试题

    一、JDK 和 JRE 有什么区别? JDK(Java Development Kit),Java开发工具包 JRE(Java Runtime Environment),Java运行环境 JDK中包含JRE,JDK中有一个名为jre的目录,里面包含两个文件夹bin和lib,bin就是JVM...

  • java同时引用不同版本同一个jar包

    java是当类名包名相同且类加载器相同时认为是同一个类,想要同时使用不同版本jar包只能通过自定义类加载器,破坏双亲委派模型来实现。 一 、Java类加载的过程 Java代码从编码完成到运行,包含两个步骤: 编译:把写...

  • 【Java基础知识 7】Java面向对象简介

    现在有一个独立的具有较小类库的Java微型版(JavaMicroEdition),这个版本适用于嵌人式设备。 2、面向对象 众所周知,Java是一个面向对象的语言,万物皆对象。 面向对象是一种新兴的程序设计方法,或者是一种新的程序...

  • 如何在官网下载各个版本的JDK

    1、打开Oracle官网,默认进入官网首页,官网地址为:http://www.oracle.com/2、这是我们可以看到Trials and Downloads...说明我们已经进入下载页面了3、进入下载页面后,可以看到它主要分为两大板块,分别是Trials(...

Global site tag (gtag.js) - Google Analytics