html5的data-*属性及dataset的使用
在搞项目的时候,咱们会常常用到一些自定义标签。要是想调换它们的属性咋办?别慌,HTML5给你支了个绝招——用那个叫做data-*的属性。只要把这个搞好,那个叫dataset的小帮手就可以任由你玩儿~而且,它是domstringmap{}型的,简单来说就是一张“地图”,特好用!但是,如果你碰到的是跟Android 2.3那样老的设备,可能就要小心,因为这些家伙可能不认识dataset这个新朋友。
兼容性问题及解决方案
// 如浏览器不支持 HTML5 data-* 属性,设置一个。 ;(function(){ // 测试元素 var el; el = document.createElement('p'); el.setAttribute('data-id', '111'); if(!el.dataset){ Element.prototype.dataset = {}; var querySelectorAll = document.querySelectorAll; // 保存一个 document.querySelectorAll = function(){ var resultEls = querySelectorAll.apply(this, arguments); for(var resultEl, i = 0, j = resultEls.length; i < j; i++){ resultEl = resultEls[i]; resultEl.dataset = getAttrib(resultEl.attributes) } return resultEls; } // 也就是单个的 document.querySelectorAll()。不保存,直接覆盖 document.querySelector = function(){ var resultEls = document.querySelectorAll.apply(this, arguments); return resultEls ? resultEls[0] : null; }; } el = null; // 要完全移除 dummy 元素,是否这样就 ok? /** * 把元素保存为 JSON 对象 * @param {Element.attributes} 元素属性集合 * @return {Object} */ function getAttrib(attributes) { if (!attributes) return; var hash = {}; for (var attribute, i = 0, j = attributes.length; i < j; i++) { attribute = attributes[i]; if(attribute.nodeName.indexOf('data-') != -1){ hash[attribute.nodeName.slice(5)] = attribute.nodeValue; } } return hash; } })();
别着急,那个老掉牙的浏览器未必听得懂dataset啥意思,我们稍微处理一下就好了。你知道,网页上有这么一个能查东西在哪儿的魔法工具 document.querySelector,咱们可以用它来修复这个问题。很简单的办法,先把想要的信息找出来,然后把它们塞到Dataset里面去就搞定了。或者用一种叫getDataAttrib的API方法也行,原理是一样的。为啥不用第一种方法?因为它简单又明了,还是官方推荐的
实现方式
要是用老版浏览器找不着 Dataset 咋办呀?放心只需要在 Element.prototype 加个稍微特殊点的代码就行。这样的话,querySelector 和 getElementById 这俩查找元素的常用方法也知道怎么应对 dataset,所以即便用老版浏览器,设置好的参数也都能读出来!
if(!canSupportDataSet()){ Element.prototype.dataset = {}; modifyQuerySelectorAll_By(document); // document 的好像不一样…… modifyQuerySelectorAll_By(Element.prototype); } /** * 覆盖系统的 querySelector/querySelectorAll 方法。 * @param host {Element.prototype/Document} */ function modifyQuerySelectorAll_By(host){ var querySelectorAll = host.querySelectorAll; // 保存一个 host.querySelectorAll = function(){ var resultEls = querySelectorAll.apply(this, arguments); for(var resultEl, i = 0, j = resultEls.length; i < j; i++){ resultEl = resultEls[i]; resultEl.dataset = getAttrib(resultEl.attributes) } return resultEls; } // 也就是单个的 document.querySelectorAll()。不保存,直接覆盖 host.querySelector = function(){ var resultEls = host.querySelectorAll.apply(this, arguments); return resultEls ? resultEls[0] : null; }; }
优化与性能考量
别忘了,无论是啥选框或怎么选,咱们最终都得用querySelectorAll()把它们变成数组才能继续。但是,有没有可能,我们直接借助浏览器的函数,岂不是方便又快捷?可问题在于,这样会不会影响速度?毕竟,咱们乱改系统功能,搞不好反倒拖慢了速度所以,大家还是谨慎点好。
其他相关问题探讨
Hello World var el = document.querySelector('#foo'); alert(el.querySelector('p').dataset.id);
想用这个浏览器嗷?第一步要确定它能用querySelector跟queryselectall!
记得,如果用querySelector或querySelectorAll找一些不是文档对象的东西,就无法用到Dataset。
瞧见没?那个叫做event.target.dataset的家伙,在处理某些情况下的事件时,它可能是个啥都没有的空壳!
急啥?眼下暂无getElementById的功能,不过以后可能会加。
你只需了解下如何用HTML5里的data-*属性和 dataset 对象搞定自定义标签,首先肯定要注意到老旧浏览器可能不支持 dataset,这时候就得自己想办法操作了,比如重写Element. prototype方法。但是,这也得根据实际情况来看,不能简单地说怎么做或者不怎么做。还有很多其他小细节也要多留意并寻找解决方法!
评论0