我可以使用getElementsByTagName选择多个标签吗?

问题描述 投票:51回答:4

我正在使用JavaScript代码段,以便访问我网站的访问者使用以下JavaScript来增加所有段落的字体大小:

function increaseFontSize() {  

    var paragraphs = document.getElementsByTagName('p'); 

    for(i=0;i<paragraphs.length;i++) {   

        if(paragraphs[i].style.fontSize) { 
            var s = parseInt(paragraphs[i].style.fontSize.replace("px",""));
        } else {   
            var s = 14;
        }

        if(s != max) {  
            s += 1; 
        } 
        paragraphs[i].style.fontSize = s+"px"
    } 
} 

我还如何在此代码中包含“ li”,以使“ p”和“ li”成为受影响的所选元素?

我还希望避免在我的“ li”或“ ul”中添加类或ID。是否可以一次选择两个标签?

javascript html getelementsbytagname
4个回答
77
投票
JSFiddle

var elems = document.querySelectorAll('p,li')


2
投票
simple扩展Node对象,功能:

JavaScript

/** * @param {Array} tags - The array of tagNames to search for. * @return {Array} - The elements with matching tagNames. */ Node.prototype.getElementsByTagNames = function (tags) { var elements = []; for (var i = 0, n = tags.length; i < n; i++) { // Concatenate the array created from a HTMLCollection object elements = elements.concat(Array.prototype.slice.call(this.getElementsByTagName(tags[i]))); } return elements; }; Working demo on JSFiddle.

它所做的就是遍历标记名数组,然后为每次迭代使用getElementsByTagName()获得相应的元素。

然后,当然可以在

any元素上使用与使用类似函数完全相同的方式-例如,在任何getElementById()对象上使用Node,而不仅限于document


2
投票
我可以使用getElementsByTagName选择多个标签吗?

A

是,但是您将不得不多次使用getElementsByTagName。

尽管您的示例仅指定了Document.getElementsByTagName(),但我假设您也希望将其与element.getElementsByTagName()一起使用。

getElementsByTagName返回一个HTMLCollection对象,所以理想的结果将是为提供的所有标记名返回元素的HTMLCollection对象的方法。

HTMLCollection's的注意事项>

无法修改。

    它们是DOM节点的live列表
  • 只有三种方法可以直接创建自己getElementsByTagNamegetElementsByClassNamegetElementsByTagNameNS
  • 您可以创建一个对象,该对象可能具有HTMLCollection类型的属性,例如nodeList.children
  • 由于HTMLCollection's不能被最好地修改,我们要么返回一个尽可能类似于HTMLCollection's的对象,请参见Create a HTMLCollection,要么创建一个nodeList并返回children属性。] >
  • 首先,我们需要收集

    HTMLCollection

的所有匹配元素。

最简单的方法是使用返回querySelectorAllnodeList函数。

var nodeList = document.querySelectorAll(selector);

一种替代方法是对每个标签使用getElementsByTagName方法,将返回的HTMLCollection对象转换为数组,以便可以将它们合并在一起。

像这样。

var HTMLCollectionArray = []; var names = selector.split(","); for (var i = 0, n = names.length; i < n; i++){ HTMLCollectionArray = HTMLCollectionArray.concat(Array.prototype.slice.call(document.getElementsByTagName(names[i]))); }

nodeList也可以使用相同的方法转换为数组。

HTMLCollectionArray = Array.prototype.slice.call(nodeList);

我们现在可以将所有元素作为数组返回,也可以尝试返回HTMLCollection。

如果要返回HTMLCollection,则必须将其移动或将元素复制到单个parentNode以便访问parentNode.children

我发现使用document.createDocumentFragment效果最佳。

var createDocumentFragment = document.createDocumentFragment(); for (var i = 0; i < HTMLCollectionArray.length; i++) { createDocumentFragment.appendChild(HTMLCollectionArray[i]); }; HTMLCollection = createDocumentFragment.children; return HTMLCollection;

尽管这将返回正确的类型(HTMLCollection),但在调用该方法时,它不会返回元素的实际状态。 DOM已被修改以实现此目的。这不是一个好主意。

所以这使我们可以制作伪造的HTMLCollection

window.MyNodeList = function(elements) { for ( var i = 0; i < elements.length; i += 1 ) { this[i] = elements[i]; } Object.defineProperty( this, 'length', { get: function () { return elements.length; } }); Object.freeze( this ); }; window.MyNodeList.prototype.item function ( i ) { return this[i] != null ? this[i] : null; } window.MyHTMLCollection = function(elements) { MyNodeList.call(this, elements); } MyHTMLCollection.prototype = Object.create(MyNodeList.prototype); MyHTMLCollection.prototype.constructor = MyHTMLCollection; window.MyHTMLCollection.prototype.namedItem = function ( name ) { for ( var i = 0; i < this.length; i += 1 ) { if ( this[i].id === name || this[i].name === name ) { return this[i]; } } return null; }

用法

var HTMLCollection = new MyHTMLCollection(elementsArray);

现在将所有内容拼凑在一起。

我还实现了'getElementsByClassNames'方法和'getElementsByTagNames',它们都使用相同的核心方法getElementsBySelector

Element.prototype.getElementsByTagNames = Document.prototype.getElementsByTagNames = function(selector){ return this.getElementsBySelector(selector, 'getElementsByTagName'); } Element.prototype.getElementsByClassNames = Document.prototype.getElementsByClassNames = function(selector){ return this.getElementsBySelector(selector, 'getElementsByClassName'); }

[我们只希望DocumentElement接口继承我们的新方法,因为它们调用并非在所有Node接口中都存在的原型方法。例如getElementsByClassNamequerySelectorAll

如果要缩小代码,则可以使用Node.prototype代替声明Element.prototype.Document.prototype.

Node.prototype.getElementsByTagNames = function(selector){ return this.getElementsBySelector(selector, 'getElementsByTagName'); } Node.prototype.getElementsByClassNames = function(selector){ return this.getElementsBySelector(selector, 'getElementsByClassName'); }

只需确保您不尝试在不是DocumentElement的任何节点上使用它。

Element.prototype.getElementsBySelector = Document.prototype.getElementsBySelector = function (selector, HTMLCollectionType) {

    var HTMLCollectionArray = [];

    if(typeof this.querySelectorAll !== 'undefined'){

        var nodeList = this.querySelectorAll(selector);
        HTMLCollectionArray = Array.prototype.slice.call(nodeList);

    } else {

        if(typeof HTMLCollectionType !=='undefined' && typeof this[HTMLCollectionType] !== 'undefined'){

            var names = selector.split(",");
            for (var i = 0, n = names.length; i < n; i++){
                HTMLCollectionArray = HTMLCollectionArray.concat(Array.prototype.slice.call(this[HTMLCollectionType](names[i]))); 
            }
        }
    }

    return new MyHTMLCollection(HTMLCollectionArray);

    /* 
    var createDocumentFragment = document.createDocumentFragment();
    for (var i = 0; i < HTMLCollectionArray.length; i++) {
        createDocumentFragment.appendChild(HTMLCollectionArray[i]);
    };
    HTMLCollection = createDocumentFragment.children;
    return HTMLCollection;
    */
}

用法

var element = document.getElementById('id');
element.getElementsbyClassNames('class1,class2,class2'); 
element.getElementsbyTagNames('li,div,p'); 

document.getElementsbyClassNames('class1,class2,class2'); 
document.getElementsbyTagNames('li,div,p'); 

同时选择两个标签?是的,我们可以同时创建一个循环。这是您的整个示例。但是一个循环(一个数组)同时具有P和LI:
function increaseFontSize() { Array.from(document.getElementsByTagName('p')) .concat(Array.from(document.getElementsByTagName('li'))).forEach(el => { if(el.style.fontSize) { var s = parseInt(el.style.fontSize.replace("px","")); } else { var s = 14; } if(s != max) { s += 1; } el.style.fontSize = s+"px" }); }

说明:Array.from()这是从集合中制作真实数组的官方方法。某些浏览器可能在HTMLCollection上支持forEach,但未在规范中。即使这样,他们也可能不支持concat()方法。使用from()将创建集合的浅表副本。这是HTMLCollection的优势,因为可以在迭代过程中修改项目并且对Array内部元素的修改仍将是对原始对象的修改。

现在我们有两个标准数组,可以使用concat()将它们连接起来,并且forEach可以迭代连接的结果。

0
投票
function increaseFontSize() { Array.from(document.getElementsByTagName('p')) .concat(Array.from(document.getElementsByTagName('li'))).forEach(el => { if(el.style.fontSize) { var s = parseInt(el.style.fontSize.replace("px","")); } else { var s = 14; } if(s != max) { s += 1; } el.style.fontSize = s+"px" }); }
© www.soinside.com 2019 - 2024. All rights reserved.