原文链接

Document Ready 事件

在jQuery中,document.ready可以让代码在整个文档加载完毕之后执行:

$(document).ready(function() {
// Code
});

JavaScript同样拥有一个DOM内容加载事件的侦听器:

document.addEventListener("DOMContentLoaded", function() {
// Code
}, false);

选择器API

jQuery中的选择器语法丰富灵活:

var element = $("div");

现在js中的querySelector完全可以替代它,document.querySelector只获取第一个元素,document.querySelectorAll可以获取全部元素。

var element = document.querySelector("div");

或者选择所有div的某些内部容器:

var elements = document.querySelectorAll(".container div");

也可以针对特定元素进行查询来找到它的子元素:

var navigation = document.querySelector("nav");
var links = navigation.querySelectorAll("a");

很简单,容易理解且现在不需要太多的代码。更进一步,我们甚至可以自己建一个小型的JavaScript库来进行简单的DOM查询。以下是Andrew Lunny已经想出来的一些东西:

// This gives us simple dollar function and event binding
var $ = document.querySelectorAll.bind(document);
Element.prototype.on = Element.prototype.addEventListener; // This is how you use it
$(".element")[0].on("touchstart", handleTouch, false);

遍历DOM

用纯JavaScript来遍历DOM比起用jQuery来说有一些困难。但也不是太困难。下面是一些简单的例子:

// Getting the parent node
var parent = document.querySelector("div").parentNode;
// Getting the next node
var next = document.querySelector("div").nextSibling;
// Getting the previous node
var next = document.querySelector("div").previousSibling;
// Getting the first child element
var child = document.querySelector("div").children[0];
// Getting the last child
var last = document.querySelector("div").lastElementChild;

添加和删除样式名(class name)

使用jQuery,添加、删除和检查一个元素是否有确定的类是很简单的事。用纯JavaScript会有一些复杂,但也不是太复杂。给元素一个叫做“foo”的类且替换目前所有的类:

// Select an element
var element = document.querySelector(".some-class");
// Give class "foo" to the element
element.className = "foo";

在不替换目前类的前提下增加类:

element.className += " foo";

从html元素中移除”no-js”类且用”js”来替代:

<html class="no-js">
<head>
<script>
document.documentElement.className = "js";
</script>

这相当简单,对不对?下一步,只移除某些类稍微有点复杂。我一直在单独部分使用这个叫做util.js的小助手函数。它有两个参数:元素和你想移除的类:

// removeClass, takes two params: element and classname
function removeClass(el, cls) {
var reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
el.className = el.className.replace(reg, " ").replace(/(^\s*)|(\s*$)/g,"");
}

然后,在主应用程序部分,我一直像这样使用:

removeClass(element, "foo");

如果针对某些类你同样想检查一个元素,那么就像jQuery的hasClass一样。你可能需要把这些代码加入到你的utils工具中:

// hasClass, takes two params: element and classname
function hasClass(el, cls) {
return el.className && new RegExp("(\\s|^)" + cls + "(\\s|$)").test(el.className);
}

然后可以这样使用:

// Check if an element has class "foo"
if (hasClass(element, "foo")) { // Show an alert message if it does
alert("Element has the class!");
}

HTML5 的 classList API 简介

如果你只需要支持像IE10+,Chrome,FireFox,Opera和Safari这样较现代的浏览器,那么你可以开始使用HTML5的classList功能,它让增加和删除类变得更简单。

这是我在我们最新的开发者文档中最终做的事,随着功能的开发,这更像是UI的加强,且如果这不是现在的,其实际上并不是能打破经验的一些东西。

通过下面简单的”if”语句,你可以检测出浏览器是否支持这个功能:

if ("classList" in document.documentElement) {
// classList is supported, now do something with it
}

用classList来添加、删除、转换类:

// Adding a class
element.classList.add("bar");
// Removing a class
element.classList.remove("foo");
// Checking if has a class
element.classList.contains("foo");
// Toggle a class
element.classList.toggle("active");

使用classList的另一个好处是它比使用原始的类名属性表现得更好。如果你有像这样的元素:

<div id="test" class="one two three"></div>

你想操作哪一个:

var element = document.querySelector("#test");
addClass(element, "two");
removeClass(element, "four");

这些被类名属性读和写的方法将触发浏览器重绘。但这并不是我们是否应该用相应的classList方法的情况:

var element = document.querySelector("#test");
element.classList.add("two");
element.classList.remove("four");

用classList之后,最基本的类名属性仅在必要的时候进行更改。添加一个已经存在的类和移除一个不存在的类时,根本没有牵涉到类名属性,这意味着我们刚刚避免了两次重绘。

事件监听器

添加和移除一个元素的事件监听器在纯JavaScript和jQuery中都一样比较简单。当你必须要添加多个事件监听器时,事情就变得有点复杂了,但我会详细解释给你的。最简单的一个例子,当你单击一个元素时弹出一个警告信息,如下代码所述:

element.addEventListener("click", function() {
alert("You clicked");
}, false);

为了让页面的所有元素都实现这个功能,我们必须依次重复每个元素且给他们添加事件监听器:

// Select all links
var links = document.querySelectorAll("a"); // For each link element
[].forEach.call(links, function(el) { // Add event listener
el.addEventListener("click", function(event) {
event.preventDefault();
alert("You clicked");
}, false); });

JavaScript有关事件监听器一个最伟大的功能就是“addEventListener” 能携带一个作为第二个参数的对象,这将会让它自动的寻找一个叫做“handleEvent”的方法然后调用它。

var object = {
init: function() {
button.addEventListener("click", this, false);
button.addEventListener("touchstart", this, false);
},
handleEvent: function(e) {
switch(e.type) {
case "click":
this.action();
break;
case "touchstart":
this.action();
break;
}
},
action: function() {
alert("Clicked or touched!");
}
}; // Init
object.init();

操作DOM

用纯JavaScript来操作DOM刚开始听起来就像一个可怕的想法,但比使用jQuery其实它并没有复杂多少。下面,我们会有一个例子,选择DOM的元素,克隆它,用JavaScript来操作克隆的样式,然后用被操纵的东西来替代原始的元素。

// Select an element
var element = document.querySelector(".class"); // Clone it
var clone = element.cloneNode(true); // Do some manipulation off the DOM
clone.style.background = "#000"; // Replaces the original element with the new cloned one
element.parentNode.replaceChild(clone, element);

在DOM中,如果除了附加在中新创建div,你不想替代任何东西,那么你可以这样做:

document.body.appendChild(clone);

如果你觉得你想了解更多不同的DOM方法,我建议你可以拜读一下 Peter-Paul Koch的DOM Core tables。

进一步深入

在这儿我想再多分享两个我最近发现的先进技术。这些都是我们在创建Adtile的时候需要的功能,因此你也会觉得它们很有用。

在JS中决定响应图片的最大宽度

这是我最爱的之一,且如果你需要用JavaScript操作流体图片时这非常有用。由于浏览器默认返回当前被调整过大小的图片,我们必须要想一些其它的办法。幸运的是,现代浏览器目前已有解决的方案了:

var maxWidth = img.naturalWidth;

这将会给我们提供最大宽度100%像素的图片,且IE9,Chrome,Firefox,Safari和Opera都支持这个方法。我们也可以保留这个特性然后通过加载图片到内存中添加老浏览器的支持:

// Get image's max-width:100%; in pixels
function getMaxWidth(img) {
var maxWidth; // Check if naturalWidth is supported
if (img.naturalWidth !== undefined) {
maxWidth = img.naturalWidth; // Not supported, use in-memory solution as fallback
} else {
var image = new Image();
image.src = img.src;
maxWidth = image.width;
} // Return the max-width
return maxWidth;
}

你应该注意到在检查宽度前,图片必须完全被加载。这是我们一直使用的用于确定它们有尺寸的方法:

function hasDimensions(img) {
return !!((img.complete && typeof img.naturalWidth !== "undefined") || img.width);
}

判断一个元素是否在视图窗口中

通过使用getBoundingClientRect方法,你可以获取页面中任何元素的位置。以下是一个简单的函数来表明它有多简单和多强大。这个函数有一个参数,那就是你想要检查的元素。当元素为可见时,函数将返回true:

// Determine if an element is in the visible viewport
function isInViewport(element) {
var rect = element.getBoundingClientRect();
var html = document.documentElement;
return (
rect.top >= 0 &&
rect.left >= 0 &&
rect.bottom <= (window.innerHeight || html.clientHeight) &&
rect.right <= (window.innerWidth || html.clientWidth)
);
}

上面的函数可以在给窗体添加一个”滚动”事件监听器,然后调用isInViewport()方法时使用。

结论

在你的下个项目中是否使用jQuery很大程度上取决于你所建的项目。如果你的项目需要大量的前端代码,那么你应该使用jQuery。然而,当你构建一个JavaScript插件或库时,你应该只考虑纯JavaScript。使用纯JavaScript意味着更少的请求和更少的数据加载。这同样意味着你不必强迫开发人员在他们的项目中加jQuery。

[转]抛弃jQuery,使用原生JavaScript的更多相关文章

  1. 抛弃jQuery 深入原生的JavaScript

    虽然我已经做网站建设工作10多年了,但我从最近3年才开始更多地学习如何更好的将纯JavaScript用于工作中,而不总是将jQuery考虑在第一位.现在我每天学习很多东西.这个过程让我觉得Adtile ...

  2. jquery及原生javascript对jsonp解决跨域问题实例详解

    jquery方式 前端: $.ajax({ url: 'http://m.xxx.tv/goLottery', data: { data: data }, type: 'GET', dataType: ...

  3. JQuery和原生JavaScript实现网页定位导航特效

    慕课网的一个小课程,练习了一遍,不足之处,欢迎指正(照片在本地,大家可以着重看代码哈): <!DOCTYPE html> <html lang="en"> ...

  4. 抛弃jQuery,拥抱原生JavaScript

    前端发展很快,现代浏览器原生 API 已经足够好用.我们并不需要为了操作 DOM.Event 等再学习一下 jQuery 的 API.同时由于 React.Angular.Vue 等框架的流行,直接操 ...

  5. 你可能不需要 jQuery!使用原生 JavaScript 进行开发

    很多的 JavaScript 开发人员,包括我在内,都很喜欢 jQuery.因为它的简单,因为它有很多丰富的插件可供使用,和其它优秀的工具一样,jQuery 让我们开发人员能够更轻松的开发网站和 We ...

  6. 表单美化-原生javascript和jQuery单选按钮(兼容IE6)

    最近很多人问怎么美化表单的元素,大家都知道表单元素在各个浏览器中的表现不一,反正也是特别的丑,那么问题就来了,我们能自己设计表单元素的外观么?答案是可以的,现在我们就来试试吧.我们用两种方式来实现这一 ...

  7. 原生 JavaScript 代码和Jquery实现对比

    下面就带大家一起看看在 IE 浏览器环境中如果使用原生 JavaScript 代码实现 jQuery 中的功能.如果你打算自己开发一个小的基础框架,可以好好参考一下这些代码的实现. 本文转载:http ...

  8. 四种常见的提示弹出框(success,warning,error,loading)原生JavaScript和jQuery分别实现

    原文:四种常见的提示弹出框(success,warning,error,loading)原生JavaScript和jQuery分别实现 虽然说现在官方的自带插件已经有很多了,但是有时候往往不能满足我们 ...

  9. 原生javascript与jquery 的比较

    JavaScript的优点和缺点: 优点: 性能:由于JavaScript运行在客户端,节省了web服务器的请求时间和带宽 轻量级的脚本语言,比较容易学习 运行在用户机器上,运行结果和处理相对比较快. ...

  10. 常见的dom操作----原生JavaScript与jQuery

    1.创建元素 文本节点 JavaScript: document.createElement(),只接收一个参数,创建后需要手动将其添加到文档树中,例如: var newDiv = document. ...

随机推荐

  1. NodeJS学习:搭建私有NPM

    工具 verdaccio nrm pm2 特点 verdaccio 的特点: 不同步拉取npm库,占据大量硬盘,没有硬盘被撑爆的问题: 安装配置极其简单,不需要数据库: 支持配置上游registry配 ...

  2. python3 使用SimpleHTTPServer搭建web服务器

    刚刚萌发了一个念头,要用python来做个web服务器,秀出自己的网页.于是,开始了我的搭建web服务器之旅. 首先,如果不想使用Apache.IIS,那就需要一个HTTP服务,而python自带了一 ...

  3. Pycharm里面使用PIL库之后,为什么调用Image的方法不能弹出代码提示,怎样能让代码提示弹出?

    之前也碰到了这个问题,安装了pillow后没有代码提示,最后查了半天,发现问题原来非常简单,解决方法也很无厘头. 之所以没有代码提示,仅仅是因为Pycharm没法判断Image.open()返回的对象 ...

  4. J 判断二叉树每个结点的权值是否关于根节点完全对称

    如果二叉树每个结点的权值关于根节点完全对称 就输出Yes Sample Input 27 //结点1 2 3 //结点1的左孩子是结点2 右孩子是结点32 4 53 6 74 0 05 0 06 0 ...

  5. [CQOI2017]小Q的棋盘

    题解: 好像有题解说可以贪心.. 显然这是一棵树,考虑树形dp 维护f[i][j]从点i往下走j再回来经过的最多点,g[i][j]从点i往下走j不用回来经过的最多点 转移方程还是挺显然的,枚举的时候像 ...

  6. Python全局解释器锁

    超过十年以上,没有比解释器全局锁(GIL)让Python新手和专家更有挫折感或者更有好奇心.    Python的底层 要理解GIL的含义,我们需要从Python的基础讲起.像C++这样的语言是编译型 ...

  7. Docker 注意事项

    一.Dockerfile名字不能是大写. 二.Docker-compares 引用自:https://www.cnblogs.com/wj5633/p/6707012.html 引用自:https:/ ...

  8. 基于kubernetes集群部署DashBoard

    目录贴:Kubernetes学习系列 在之前一篇文章:Centos7部署Kubernetes集群,中已经搭建了基本的K8s集群,本文将在此基础之上继续搭建K8s DashBoard. 1.yaml文件 ...

  9. 通过pyqt5实现俄罗斯方块游戏例子

    # *_* coding:utf-8 *_* # 开发团队:中国软件开发团队# 开发人员:Administrator# 开发时间:2019/3/17 2:13# 文件名称:RussiaBoard# 开 ...

  10. where field in

    SELECT * FROM xx  WHERE field IN ('11','22','33');