1、介紹
隨着組件開發大流行,現在三大框架已經基本占領了整個前端。
這時候,我們要是引入一個 jq 是不是先得你的項目非常臃腫,jq 也很不適合。
這個時候,你就需要來增加你 js 的功底。
2、各種操作
1、事件委托
案例分析:
<ul id= "list">
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
</ul>
如上面的頁面機構,我們需要個每一個 li 添加同一個事件。
常規操作:
選擇出所有的 li 標簽,然后為所有的標簽都添加這個事件。
var liList = document.querySelectorAll('#list li')
liList.foreach(function(item,index)=>{
item.addEventListener('click',doSomething)
})
很簡單,也是非常好的。
但是當這里的 li 標簽多了之后,那么你獲取所有的 li 標簽並綁定事件就會變慢,也就是說性能就會不好了。
這個時候該如何處理呢?
事件委托:
解釋下事件委托吧,可能新手不知道。
就是把子元素想要綁定的事件,綁定到子元素的父元素上面。
然后當事件觸發的時候,通過事件冒泡來獲取到當前事件源對應的的元素。(事件冒泡和捕獲如果不知道還是需要補習下的)
代碼展示:
var liList = document.querySelectorAll('#list')
liList.addEventListener('click',function(e)=>{
if(e.target && e.target.nodeName.toUpperCase == 'LI'){
console.log('你點擊了'+e.target.innerText )
}
})
給一個比較完整的例子,沒有驗證...
function delegate(element, eventName, name, func) {
element.addEventListener(eventName, function (e) {
var target = e.target, parent = target;
while (target && parent != element) {
if (parent.nodeName.toLowerCase() == name) {
e.target = parent
func.apply(parent,e);
break;
}
parent = parent.parentNode;
}
});
}
上面的例子,name 字段可以是 類命,id 的值,也可以是 標簽。
自行修改,更靈活。。
總結:
事件代理委托主要是通過給父元素綁定事件。
通過事件的冒泡來確定當前的事件源。
確定事件源,並執行具柄。
2、es5 的元素獲取、class 的操作
es5 的元素獲取
在之前我一直都是使用的 es3 做元素獲取的,如:
document.getElementById(id) document.getElementsByClassName(class)
上面的相信是大家以前最熟悉的 js 獲取方法。
但是在 es5 出來后,你會驚奇的覺得 Jquery 選擇器可以被替代了
document.querySelector(selector)
document.querySelectorAll(selector)
// 例如
document.querySelector('.classs p') // 獲取 class 類下面的 p 標簽
// 可以看到和 jquery 選擇器差不多,只是功能精簡了
上面很清楚的可以知道:
querySelector 是獲取單個元素
querySelectorAll 是獲取多個匹配元素
最大的變化就是 selector。
它可以是 .className 、 #id 、也可以是多級選擇 .className p
class 類的一些 es5 操作
Dom 的 classList 屬性:
<div id = "test" class = "red big hot"></div>
獲取樣式類列表
document.querySelector('test').classList
這里會返回一個 TokenList 也就是是個類數組:
{
0:red,
1:big,
2:hot,
length:3,
value:'red big hot'
}
添加類名
document.querySelector('test').classList.add('good','new')
添加類 good , new 。如果類名已經存在,則不添加
移除某類
document.querySelector('test').classList.remove('good','new')
移除 good , new 類。移除不存在的類,會報錯
切換類
document.querySelector('test').classList.toggle('good')
切換 good 類。如果 good 存在返回true,否則false
判斷是否存在某類
document.querySelector('test').classList.contains('good')
返回 boolean 值。
3、獲取元素在父元素中第幾個
其實這個在現在的組件模式中很容易實現。
但是 js 中是如是實現的呢 ?
<ul> <li>1</li> <li>2</li> <li>3</li> </ul>
獲取方法及其封裝:
function index(parent,son) {
return [].indexOf.call(parent.children,son);
}
如上面:
parent 是父元素,son 很顯然是子元素
4、元素相對於文檔 / 窗口視圖的位置
相對於文檔的位置
在 jquery 中我們實現的方法是 $(s).offset() 來回去相對於文檔的位置。
那 js 中如何實現的呢?
代碼:
const getDocPosition = (element) => {
let eleCom = element;
if (typeof element === 'string') eleCom = document.querySelector(eleCom);
let x = eleCom.offsetLeft;
let y = eleCom.offsetTop;
let parent = eleCom.offsetParent;
while (parent) {
x += parent.offsetLeft;
y += parent.offsetTop;
parent = parent.offsetParent;
}
return {
x,
y,
};
};
代碼很簡單:
可以看出,通過不斷的獲取 offsetLeft / offsetTop ,並且與它的父元素相加。
直到相加到頂級元素為止。
相對於窗口視圖位置
getBoundingClientRect用於獲取某個元素相對於視窗的位置集合。集合中有top, right, bottom, left等屬性。

rectObject = object.getBoundingClientRect();
rectObject.top:元素上邊到視窗上邊的距離;
rectObject.right:元素右邊到視窗左邊的距離;
rectObject.bottom:元素下邊到視窗上邊的距離;
rectObject.left:元素左邊到視窗左邊的距離;
如果你看過 lazyImg 圖片的懶加載,你們就會發現,他的實現原理就是這個。
當它圖片出現在窗口的視圖中,就會加載真的圖片資源。
后續繼續添加常用的、容易忘的一些 js 功能。
https://www.cnblogs.com/jiebba/p/9663268.html
我的博客 : XiaoLong's Blog
博客園小結巴巴: https://www.cnblogs.com/jiebba
