saber酱的抱枕

转卖“saber.我爱你”域名和“lovesaber.com”域名

@saber1月前

04/11
09:03
学习

JavaScript回收DOM节点的内存

如果我们要删除一个DOM节点,可能大家都会想到remove方法。如下:

var a=document.createElement("a");
// 设置内容等代码 ...
a.parentNode.removeChild(a);

Node.removeChild() 方法从DOM中删除一个子节点。返回删除的节点。

从返回值是个节点我们可以知道,removeChild之后,这个节点虽然在DOM里去掉了,但是它仍然存在在内存里。

虽说过一段时间不用,它就会被浏览器回收掉,但如果要重复的创建这个节点的话,那么每次removeChild时使用delete操作符,可以略微优化内存占用(大概……)。

如下:

var a=document.createElement("a");
// 设置内容等代码 ...
delete a.parentNode.removeChild(a);

今天我在chrome上做了多次实验,有一些发现:

1.使用delete之后,chrome浏览器并不会立即回收这部分内存,而是等差不多二十秒之后才回收。

2.使用delete之后,内存回收的比只remove要多一些。

3.即使使用delete,内存也不能完全回收,内存占用还是会一直增加。只是情况略有缓解。

4.有人说delete回收内存只能回收由JavaScript创建的节点,如果是原本html文档里的节点,delete是回收不了的。我试了试,对于原本html文档里的节点,用delete和只用remove没看出明显区别,大概这个说法是对的。

JavaScript回收DOM节点的内存

@saber4月前

01/9
08:00
学习

使用js的insertAdjacentHTML方法插入元素

以往我们插入、移动DOM元素经常是使用appendChild和insertBefore方法。

appendChild:在父级元素内追加新元素。
insertBefore:在父级元素内的某个元素之前插入新元素。

但是这两个方法的参数只能接收元素对象,不能使用字符形式的html代码,而且它们插入元素的位置也不够灵活。我们可以使用insertAdjacentHTML方法来更方便的插入元素。

insertAdjacentHTML可以将字符串形式的html代码(需要能解析为DOM元素)解析为一个节点,并将其追加到指定元素的指定位置。

insertAdjacentHTML方法的语法如下:

element.insertAdjacentHTML(position, text);

position参数有以下四个值(都是字符串形式):

beforebegin:在元素的开始位置之前插入。
beforeend:在元素的结束位置之前插入。
afterbegin:在元素的开始位置之后插入。
afterend:在元素的结束位置之后插入。

text参数则是字符串形式的html代码。

根据position参数,我们可以将新元素插入到到指定元素的四个位置:

使用js的insertAdjacentHTML方法插入元素

示例:

<div id="a">
	<div></div>
</div>
<script type="text/javascript" defer>
	var a=document.querySelector("#a");
	a.insertAdjacentHTML("afterbegin","<a href='' >xxx</a");
</script>

结果如下:

<div id="a">
	<a href="">xxx</a>
	<div></div>
</div>

insertAdjacentHTML方法的兼容性表现良好,主流浏览器均已支持。我们也可以如下语句来检查浏览器是否支持方法:

document.documentElement.insertAdjacentHTML

此外,由于insertAdjacentHTML是根据位置插入元素的,因此它不能把新元素插入到img、input等单标签元素里(想这么做的人才是有毛病吧)。

相关文档:《https://developer.mozilla.org/zh-CN/docs/Web/API/Element/insertAdjacentHTML》


ps:与insertAdjacentHTML系列“同一系列”的还有insertAdjacentElement方法和insertAdjacentText方法。

insertAdjacentElement方法除了第二个参数是DOM节点(不能是字符串形式)外和insertAdjacentHTML方法都一样。

insertAdjacentText方法则只接收字符串格式的参数,并输出为字符串。其他地方也和insertAdjacentHTML方法一样。

使用js的insertAdjacentHTML方法插入元素

@saber1年前

05/15
08:00
学习

原生js中的利器——querySelectorAll

昨天发表的那个网站地图助手里,有几个输入框都需要在鼠标经过时自动选中其中的内容。

实现起来没有难度,但类似于getElementBy...这样的选择器难以在不写重复代码的情况下选中几个不同id的元素。所以我的代码写成了这样:

document.getElementById("a").onmouseover=function (argument) {
    this.select();
}
document.getElementById("b").onmouseover=function (argument) {
    this.select();
}
document.getElementById("y").onmouseover=function (argument) {
    this.select();
}
document.getElementById("c").onmouseover=function (argument) {
    this.select();
}

感觉这样实在无法见人,于是去贴吧求助。终于知道了一个好办法:js现在有了一个原生的querySelectorAll方法,可以接受一组css选择器风格的字符串来作为选择器(这点和jQuery很像),如下:

document.querySelectorAll('#a,#b,#c,#y');

这样就解决了重复获取元素的问题了。querySelectorAll简直是一个福音啊。

querySelectorAll和querySelector是HTML5中新增的属性,但是IE8也支持。所以放心的用吧~

由于我们是无法对一个元素集合直接添加事件的,只能用循环来加了(所以jQuery用起来还是更方便啊)。使用for循环就可以,forEach也可以(使用forEach更有逼格?)。不过元素集合并不是数组,要使用forEach的话需要借用数组的属性。于是最后的代码如下:

function selectS(s){
    return document.querySelectorAll(s);
}
[].forEach.call(selectS('#a,#b,#c,#y'),function(e){
    e.onmouseover=function (argument) {
        this.select();
    }
});

原生js中的利器——querySelectorAll