Heim  >  Artikel  >  Web-Frontend  >  Ausführliche Erläuterung, wie die data-*-Attribute des HTML5-Beispielcodes automatisch abgerufen werden

Ausführliche Erläuterung, wie die data-*-Attribute des HTML5-Beispielcodes automatisch abgerufen werden

黄舟
黄舟Original
2017-03-11 16:37:551389Durchsuche

Im Projekt muss eine Reihe benutzerdefinierter Tags entworfen werden. Dabei geht es darum, wie auf die Attribute der Tags zugegriffen wird. Wenn Sie das data-*-Attribut von HTML5 verwenden, können Sie nach Erhalt des Elements direkt auf den Namen dataset.attribute zugreifen. Der Typ des Datensatzes ist DOMStringMap {}, ein MAP-Objekt, das immer noch ein Schlüssel-/Wertobjekt ist, was mehr ist bequem zu verwenden. Wir sind jedoch auf ein Kompatibilitätsproblem gestoßen und es wird von einigen alten Browsern wie Android 2.3 nicht unterstützt.

Wir können hierfür einen Kompatibilitätspatch schreiben. Das Hauptprinzip besteht darin, Methoden wie document.querySelector/querySelectorAll zu „kapern“, um Elemente abzurufen, und dann ein benutzerdefiniertes Feld dataset = {....} bereitzustellen, um eine ähnliche Standardschrift zu erreichen. Natürlich können Sie einfach eine API-Methode wie getDataAttrib() bereitstellen, um das Attribut abzurufen, und der Effekt ist derselbe. Der Grund, warum wir diese Methode nicht übernehmen, sondern eine andere Methode, besteht darin, näher an den Standard heranzukommen und eine einheitliche Zugriffsmethode für alle zu verwenden.

Meine Implementierung ist wie folgt:

// 如浏览器不支持 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(&#39;data-&#39;) != -1){
	            hash[attribute.nodeName.slice(5)] = attribute.nodeValue;
            }
        }
        
        return hash;
    }
})();

Da die Methode von querySelector zum Abrufen von Elementen ausreichend ist, wird die Methode „documeny.getElementByID(“#id”) derzeit nicht bereitgestellt.

Bitte beachten Sie: Die Ausführung von querySelector /querySelectorAll für Nicht-Dokumentobjekte wird nicht unterstützt und der Datensatz wird nicht zurückgegeben. Dieses Problem wurde durch Umschreiben der Element.prototype-Methode am 16.01.2013 gelöst. Der detaillierte Ablauf ist wie folgt:

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;
    };
}

Testbeispiel:

<listview id="foo" data-id="1">
    Hello World
    <p data-id="2"></p>
</listview>

<script>
var el = document.querySelector(&#39;#foo&#39;);
alert(el.querySelector(&#39;p&#39;).dataset.id);
</script>

Problemzusammenfassung:

  1. Der Browser muss sein kann die Methode querySelector/querySelectorAll unterstützen, andernfalls ist diese Methode bedeutungslos.

  2. kann nur Datensätze aus der Methode zum Abrufen von Elementen bereitstellen. Beispielsweise ist e.tartget.dataset des Parameters e im Ereignishandler ein leeres Objekt.

  3. Wie im obigen Code gezeigt, durchläuft ein einzelner querySelector() querySelectorAll(), der den Vorgang des Durchlaufens des Arrays umfasst. Kann er entsprechend optimiert werden und den nativen verwenden?

  4. Für Schüler, die empfindlich auf die Geschwindigkeit der CSS Selector Engine reagieren, ist diese Methode nicht anwendbar. Da die Systemmethode geändert wird, ist ersichtlich, dass die Leistung zwangsläufig abnimmt. Es kann jedoch garantiert werden, dass dieser Rückgang gering ist.

  5. unterstützt documenteny.getElementByID noch nicht und wird hinzugefügt.

Das obige ist der detaillierte Inhalt vonAusführliche Erläuterung, wie die data-*-Attribute des HTML5-Beispielcodes automatisch abgerufen werden. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn