1.页面拥有ID的元素会创建全局变量
在一张HTML页面中,所有设置了ID属性的元素会在JavaScript的执行环境中创建对应的全局变量,这意味着document.getElementById像人的阑尾一样显得多余了。但实际项目中最好老老实实该怎么写就怎么写,毕竟常规代码出乱子的机会要小得多。
<div id="myElement"></div>
<script type="text/javascript"> console.log(myElement); </script>
2.正确的隐私元素方式
你是否曾经为了隐藏某个元素而使用过 myElement.style.display = 'none' 这种方法呢?如果是的话,请别再这么做了! 只需调用 myElement.hidden = true ,即可实现元素隐藏的功能。
3.给元素添加class正确方式
toggle 也不算是元素的方法,它实际上是元素属性上的一个方法。严格来说,这是一种为元素添加或删除某个 class 的方法,具体做法是 myElement.classList.toggle('some-class') 。 如果你曾经通过 if 条件语句为元素添加 class,那就应该赶紧改用这种做法。 正确的方式是为 toggle 方法传入第二个参数,如果该参数返回 true ,则指定的 class 就会添加至元素上。 el.classList.toggle('some-orange-class', theme === 'orange')。
4.检查某元素class值
假设我需要检查某个元素是否包括一个特定的 class。 这是最复杂的方式:
if (myElement.className.indexOf('some-class') > -1) { // do something }
或者可以用:
if ( myElement.classList.contains ('some-class')) { // do something }
最佳方式: if (myElement.matches('.some-class')) { // do something }
5.检查某元素的子元素
你有没有遇到过这样的情形,需要知道某个元素是否被包含在另一个元素中?至少我本人经常会遇到这样的问题。 打个比方,假设我在处理一个鼠标点击事件时,需要知道它是发生在一个模态窗口中还是发生在外面(这样我才能够关闭这个窗口),我大概会这么做:
const handleClick = e => { if (!modalEl.contains(e.target)) modalEl.hidden = true; };
代码中的 modalEl 是模态窗口的引用,而 e.target 则代表各种发生点击事件的元素。
6.array.filter(Boolean)
ECMAScirpt5 中 Array 类中的 filter 方法使用目的是移除所有的 “false”类型元素 (false, null, undefined, 0, NaN or an empty string):
var a=[1,2,"b",0,{},"",NaN,3,undefined,null,5];
var b=a.filter(Boolean); // [1,2,"b",{},3,5]
Boolean 是一个函数,它会对遍历数组中的元素,并根据元素的真假类型,对应返回 true 或 false.
例如: Boolean(0); // false Boolean(true); // true Boolean(1); // true Boolean(""); // false Boolean("false"); // true. "false"是一个非空字符串 实际上,下面这样的写法是一种简写模式 b = a.filter(Boolean);
它等价于 b = a.filter(function (x) { return Boolean(x); });
7.Array.from
你知道Array.from可以接受第二个参数吗?其作用类似于数组的map方法,用来对每个元素进行处理,将处理后的值放入返回的数组。
Array.from(arrayLike, x => x * x);
等同于
Array.from(arrayLike).map(x => x * x); Array.from([1, 2, 3], (x) => x * x) // [1, 4, 9]
8.利用a标签自动解析URL
很多时候我们有从一个URL中提取域名,查询关键字,变量参数值等的需要,而万万没想到可以让浏览器方便地帮我们完成这一任务而不用我们写正则去抓取。方法就在JS代码里先创建一个a标签然后将需要解析的URL赋值给a的href属性,然后就得到了一切我们想要的了。
var a = document.createElement(‘a');
a.href = 'http://www.haorooms.com/post/mailto_link_html?name=1';
console.log(a.host)
9.使用事件委托
一个简单的需求,比如想给ul下面的li加上点击事件,点击哪个li,就显示那个li的innerHTML。这个貌似很简单!代码如下!
<ul id="ul-test"> <li>0</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> </ul>
<script type="text/javascript">
var oUl=document.getElementById("ul-test");
var oLi=oUl.getElementsByTagName("li");
for(vari=0,len=oLi.length;i<len;i++) {
oLi[i].addEventListener("click",function(){ alert(this.innerHTML) }) } </script>
for循环,循环的是li,10个li就循环10次,绑定10次事件,100个就循环了100次,绑定100次事件!
如果li不是本来就在页面上的,是未来元素,是页面加载了,再通过js动态加载进来了,上面的写法是无效的,点击li是没有反应的! 所以就者需要用事件委托(即使不考虑上面的第二种情况,也是建议使用事件委托)!代码如下
<ul id="ul-test"> <li>0</li> <li>1</li> <li>2</li> <li>3</li> <li>4</li> <li>5</li> <li>6</li> <li>7</li> <li>8</li> <li>9</li> </ul> <script type="text/javascript">
var oUl=document.getElementById("ul-test");
oUl.addEventListener("click",function(ev){
var ev=ev||window.event; var target=ev.target||ev.srcElement; //如果点击的最底层是li元素
if(target.tagName.toLowerCase()==='li'){ alert(target.innerHTML) } }) </script>
这样写,即使是动态添加进来的li点击也有反应,还有一个就是ul只有一个,事件绑定在ul上,无论li多少个,都是添加一次事件!但是也是可能会有问题,如果li下面还有子元素,那么点击的时候,target可能不是li,而是鼠标点击那个位置的最底层元素!
10.减少dom操作
这里我用jquery来讲解,比较容易理解,原生js也是这个道理!如下代码
$('.div1').click(function(){ ... })
//--------------------------分割线
var $div1=$('.div1'); $div1.click(function(){ ... })
上面的代码,改变的也是缓存了$('.div1'),但是这里就建议是第二种写法了, 因为第一种点击一次就要查询一次.div1,Dom的操作还是能减少就减少!
11.字符串补全
日期,我们多采用4-2-2的表示形式 例如:2018-07-23 当我们使用时间戳进行月份获取的时候,是没有前面的0的,
var month = new Date().getMonth() + 1; // 结果是7 此时,就需要进行补全,
通常做法是这样: if (month < 10) { month = '0' + month; }
padStart()方法,我们代码可以简化成下面这一行
var month = String(new Date().getMonth() + 1).padStart(2, '0');
str.padStart(targetLength [, padString])
当targetLength小于str字符串长度时 则原本的字符串原封不动返回
'zhangxinxu'.padStart(5); // 结果还是'zhangxinxu'