專案中需要設計一系列的自訂標籤,於是涉及標籤的屬性如何存取。使用 HTML5 的 data-* 屬性的話,取得元素後直接存取 dataset.屬性名稱 即可,dataset 的類型為 DOMStringMap {},一個 MAP 對象,仍是 key / value 式的對象,使用上比較方便。但卻遇到一個相容性的問題, 在 Android 2.3 等的一些舊有瀏覽器上尚不支援。
對此,我們可以寫一個相容性的補丁。主要原理是在「劫持」 document.querySelector/querySelectorAll 這類取得元素的方法之後,透過提供自訂的欄位 dataset = {....} 即可實現類似標準寫法。當然,簡單地,你可以透過一個 API 方法來提供類似 getDataAttrib() 取得屬性,效果一樣。我們之所以不採取這種方式,而採用另一種方式,是為了更好向標準靠攏,使用大家都一致的存取方式。
我的實作如下:
// 如浏览器不支持 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; } })();
考慮到 querySelector 取得元素的方式已經足夠,故所以目前沒有提供 documeny.getElementByID(“#id”) 方法。
請注意:對於非 document 物件身上執行的 querySelector /querySelectorAll 將不支持,仍不會傳回 dataset。 針對此問題,已於2013.1.16 透過重寫 Element.prototype 方法解決。詳細流程如下:
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; }; }
測試範例:
<listview id="foo" data-id="1"> Hello World <p data-id="2"></p> </listview> <script> var el = document.querySelector('#foo'); alert(el.querySelector('p').dataset.id); </script>
問題小結:
以上是如何自動取得HTML5的data-*屬性範例程式碼詳解的詳細內容。更多資訊請關注PHP中文網其他相關文章!