jQuery 取代jQuery

使用说明

jQuery自2006年发布以来一直是操作DOM的王者,因为其对原生JS做了很多封装以至于让jQuery用起来非常简单,很容易上手,配合Bootstrap流行而一路凯歌高奏。这种情况直到ES6发布和三大前端框架的出现才开始破局,使业界不得不思考基于DOM的操作是否过时了。当你看到jQuery选择器完全可以用原生JS的document.querySelectordocument.querySelectorAll替代的时候再认真对比原生JS和jQuery的写法区别,其实用原生JS写起来也挺好的,只是多写了一点代码罢了。

常用选择器

// jQuery
$('.elem');//按class选择
$('#elem');//按id选择
$('[href]');//按href属性选择
$('.elem  p');//选择所有下属p元素
$('.elem > p');//选择所有p子元素
$('.elem + p');//选择下一个兄弟元素
$('.elem:first');//选择第一个

// 原生JS
document.querySelectorAll('.elem');//按class选择数组
document.querySelector('#elem');//按id选择
document.querySelectorAll('[href]');//按href属性选择数组
document.querySelectorAll('.elem  p');//选择所有下属p元素数组
document.querySelectorAll('.elem > p');//选择所有p子元素数组
document.querySelector('.elem + p');//选择下一个兄弟元素
document.querySelector('.elem:first');//选择第一个

//注意document.querySelectorAll输出的是NodeList数组,如果需要应用到每一个元素请使用循环遍历,举例如下:
var elems = document.querySelectorAll('.elem');
for (let i = 0; i < elems.length; ++i) {
    elems[i].style.color = "green";
}
                        

相同选择器

选择器 示例 示例说明
.class .intro 选择所有class="intro"的元素
#id #firstname 选择所有id="firstname"的元素
* * 选择所有元素
element p 选择所有<p>元素
element,element div,p 选择所有<div>元素和<p>元素
element element div p 选择<div>元素内的所有<p>元素
element>element div>p 选择所有父级是<div>元素的 <p>元素
element+element div+p 选择所有紧接着<div>元素之后的<p>元素
[attribute=value] a[target=_blank] 选择所有使用target="_blank"的<a>元素
[attribute^=value] a[src^="http"] 选择每一个src属性的值以"http"开头的<a>元素
[attribute$=value] a[src$=".jpg"] 选择每一个src属性的值以".jpg"结尾的<a>元素
:first-child ul li:first-child 选择<ul>元素下的首个<li>元素
:nth-child(n) ul li:nth-child(3) 选择<ul>元素下的第三个<li>元素
:last-child ul li:last-child 选择<ul>元素下的最后一个<li>元素

DOM树查询

jQuery Native 方法说明
$ele.parent() ele.parentNode 元素的直接父元素
$ele.children() ele.childNodes 元素的所有直接子元素
$ele.find("a") ele.querySelectorAll("a") 元素的后代元素
$ele.prev() ele.previousElementSibling 元素的上一个同胞元素
$ele.next() ele.nextElementSibling 元素的下一个同胞元素

选择兄弟

// jQuery
$('#elem').siblings();

// 原生JS
var elem = document.querySelector('#elem');
var elems = elem.parentNode.children;
for (var i = 0, i < elems.length; ++i) {
    if (elems[i] !== elem) {        
        elems[i].style.color = "gray"; 
    }
}




                        

最近的一个祖先

// jQuery
$('#elem').closest('p');

// 原生JS
function closest(el, selector) {
  const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;

  while (el) {
    if (matchesSelector.call(el, selector)) {
      return el;
    } else {
      el = el.parentElement;
    }
  }
  return null;
}
var elem = document.querySelector('p');
closest(elem, ".elem").style.color="red";
                        

选择直系祖先

// jQuery
$('#elem').parentsUntil(selector, filter);

// 原生JS
function parentsUntil(el, selector, filter) {
  const result = [];
  const matchesSelector = el.matches || el.webkitMatchesSelector || el.mozMatchesSelector || el.msMatchesSelector;
  el = el.parentElement;
  while (el && !matchesSelector.call(el, selector)) {
    if (!filter) {
      result.push(el);
    } else {
      if (matchesSelector.call(el, filter)) {
        result.push(el);
      }
    }
    el = el.parentElement;
  }
  return result;
}
var elem = document.querySelector('p');
parentsUntil(elem, ".elem", filter).style.color="red";
                        

选择匹配祖先

// jQuery
$('#elem').parents(selector);

// 原生JS
function getParents(el, parentSelector) {
            if (parentSelector === undefined) {
                parentSelector = document;
            }

            var parents = [];
            var p = el.parentNode;

            while (p !== parentSelector) {

                var o = p;
                parents.push(o);
                p = o.parentNode;
            }
            parents.push(parentSelector);
            return parents;
        }
var elem = document.querySelector('p');
getParents(elem, ".elem").style.color="red";
                        

修改内容和属性

jQuery Native 方法说明
var text = $ele.text() let text = ele.innerText 获取所选元素的文本内容
$ele.text("text") ele.innerText = "text" 设置所选元素的文本内容
var html = $ele.html() let html = ele.innerHTML 获取所选元素的HTML内容
$ele.html("<div>html</div>") ele.innerHTML = "<div>html</div>" 设置所选元素的HTML内容
var input = $ele.val() let input = ele.value 获取表单字段的值
$ele.val("input") ele.value = "input" 设置表单字段的值
var href = $ele.attr("href") let href = ele.getAttribute("href") 获取元素的属性值
$ele.attr("href", "/") ele.setAttribute("href", "/") 设置元素的属性值

修改DOM树

jQuery Native 方法说明
$parent.append($ele) parent.appendChild(ele) 在被选元素的结尾插入内容
$parent.prepend($ele) parent.insertBefore(ele, parent.firstChild) 在被选元素的开头插入内容
$ele.after(html) ele.insertAdjacentHTML("afterend", html) 在被选元素之后插入内容
$ele.before(html) ele.insertAdjacentHTML("beforebegin", html) 在被选元素之前插入内容
$ele.remove() ele.parentNode.removeChild(ele) 删除被选元素及其子元素
$ele.empty() ele.innerHTML = null 从被选元素中删除子元素
$ele.clone() ele.cloneNode(true) 拷贝被选元素
$ele.replaceWith(html) ele.outerHTML = html 指定HTML替换被选元素

设置CSS

允许使用JavaScript改变DOM元素的样式,Native API提供了如下几种方式:
  • ele.setAttribute 直接修改 DOM style 属性改变样式
  • ele.style.cssText 通过 cssText 修改 Style 属性
  • ele.style.property 通过 style 对象读写行内 CSS 样式
// jQuery
var size = $ele.css("font-size"); // 返回第一个匹配元素的 CSS 属性值
$ele.css("font-size", "2rem"); // 为所有元素设置指定的 CSS 属性值

// 原生JS
let size = getComputedStyle(ele)["font-size"]; // 获取当前元素计算后的 CSS 属性值
ele.style.setProperty("font-size", "2rem"); // 设置当前元素的某个内联样式
ele.style.removeProperty("font-size");  // 移除当前元素的某个内联样式
                        
jQuery Native 方法说明
$ele.hasClass(className) ele.classList.contains(className) 检查元素是否包含指定的类名
$ele.addClass(className) ele.classList.add(className) 向元素增加一个或多个类名
$ele.removeClass(className) ele.classList.remove(className) 从元素中移除一个或多个类
$ele.toggleClass(className) ele.classList.toggle(className) 对元素的一个或多个类进行切换

事件处理

//绑定事件
// jQuery
$ele.on("click", function (evt) {
    console.log(evt.target);
});
// 原生JS
ele.addEventListener("click", evt => {
    console.log(evt.target);
});

//解除事件
// jQuery
$ele.off("click");
// 原生JS
ele.removeEventListener("click", func);//func是自定义的点击事件

//模拟触发
// jQuery
$ele.trigger("click");
// 原生JS
let event = document.createEvent("MouseEvents");//第一步:创建 Event 对象
event.initMouseEvent("click");//第二步:初始化
ele.dispatchEvent(event);//第三步:触发 Event 对象
                        
jQuery Native 方法说明
$ele.hasClass(className) ele.classList.contains(className) 检查元素是否包含指定的类名
$ele.addClass(className) ele.classList.add(className) 向元素增加一个或多个类名
$ele.removeClass(className) ele.classList.remove(className) 从元素中移除一个或多个类
$ele.toggleClass(className) ele.classList.toggle(className) 对元素的一个或多个类进行切换

Array数组

jQuery Native 方法说明
$.isArray(array) Array.isArray(array) 判断参数是否为一个数组
$.inArray(item, array) array.includes(item) 判断值是否在指定数组中
$.makeArray(objlist) Array.from(objlist) 将类数组对象转换为数组
$.merge(array1, array2) array1.concat(array2) 合并两个数组(有区别)
$.each(array, function (i, item) {} array.forEach((item, i) => {}) 遍历指定的对象和数组

Method方法

jQuery Native 方法说明
$.now() Date.now() 返回当前时间戳
$.trim(context) context.trim() 移除字符串头尾空白
$.type(parameter) typeof parameter 检测参数的内部类型
$.parseJSON(jsonstr) JSON.parse(jsonstr) 将JSON转换为JS对象
$ele.data("key", "value") ele.dataset.key = "value" 在指定的元素上存储数据
$.map(array, function (item, i) {}) array.map((item, i) => {}) 将数组转化为处理后的新数组

AJAX

XMLHttpRequest 并不是专为 Ajax 而设计的. 虽然各种框架对 XHR 的封装已经足够好用, 但更好用的 API 是 fetch 。关于 fetch API 的文章请点击这里
// jQuery
$.ajax({
    url: "http://www.xxx.com/yyy",
    type: "GET",
    data: {
        "key": "800800900",
        "ip": "192.168.2.3"
    },
    dataType: "json",
    success: function (data) {
        console.log(data);
    }


// 原生JS,XHR 封装
window.ajax = async function (params, callback) {
    let url = params.url;
    let method = params.method;
    let data = params.data;
    let body = new FormData();
    for (let key in data) {
        if (data.hasOwnProperty(key)) {
            body.append(key, data[key]);
        }
    }
    let xhr = new XMLHttpRequest();
    xhr.timeout = 3000;
    xhr.open(method, url, true);
    xhr.addEventListener("readystatechange", evt => {
        if (xhr.readyState === 4) {
            if (xhr.status === 200) {
                callback(xhr.response);
            } else {
                throw xhr.statusText;
            }
        }
    });
    xhr.send(body);
};
 
ajax({
        url: "http://www.xxx.com/yyy",
        method: "GET",
        data: {
            "key": "800800900",
            "ip": "192.168.2.3"
        }
    },function (resp) {
        var json = JSON.parse(resp);
        console.log(json);
    }
)
// 原生JS,XHR 封装
let request = new Request(
    "http://www.xxx.com/yyy",
    {
        method: "GET",
        body: {
            "key": "800800900",
            "ip": "192.168.2.3"
        },
        headers: new Headers()
    }
);

fetch(request)
    .then(response => response.json())
    .then(function (data) {
        console.log(data);
    })
    .catch(function (error) {
        console.log(error);
    });