Подтвердить что ты не робот

Можно ли выбрать несколько тегов с помощью getElementsByTagName?

Я использую фрагмент 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". Есть ли способ сразу выбрать два тега?

4b9b3361

Ответ 1

Нет, вы не можете выбрать несколько тегов с одним вызовом getElementsByTagName. Вы можете выполнить два запроса с помощью getElementsByTagName или использовать querySelectorAll.

JSFiddle

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

Ответ 2

Через год, но если вы намерены использовать требуемую функциональность несколько раз в своем проекте, и у вас нет доступа к querySelector(), возможно, стоит расширить объект Node с помощью функции simple:

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

Рабочая демонстрация на JSFiddle.

Все, что он делает, это итерация по массиву имен тегов, а затем получение соответствующих элементов с помощью getElementsByTagName() для каждой итерации.

Это, конечно, можно использовать для любого элемента точно так же, как вы используете аналогичные функции - например, getElementById() - на любом объекте Node, вы не ограничены document.

Ответ 3

Q

Можно ли выбрать несколько тегов с помощью getElementsByTagName?

А

Да, но вам придется использовать getElementsByTagName несколько раз.

Хотя ваш пример указывает только Document.getElementsByTagName() Я предположил, что вы хотели бы, чтобы это работало с элементом element.getElementsByTagName(),

getElementsByTagName возвращает объект HTMLCollection, поэтому идеальным результатом будет метод, который возвращает HTMLCollection объект элементов для всех предоставленных имен тегов.

Заметки о HTMLCollection

  • Они не могут быть изменены.
  • Это live список узлов DOM
  • Есть только три способа создать их непосредственно getElementsByTagName, getElementsByClassName и getElementsByTagNameNS
  • вы можете создать объект, который может иметь свойства типа HTMLCollection, например nodeList.children

Как HTMLCollection не может быть изменено, мы можем только вернуть объект, похожий на HTMLCollection как можно больше, см. Создать HTMLCollection или создать nodeList и вернуть свойство children.

Во-первых, нам нужно собрать все соответствующие элементы для нашего HTMLCollection

Самый простой способ - использовать функцию querySelectorAll, которая возвращает nodeList.

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, он должен был бы либо переместить, либо скопировать элементы в один родительскийNode, чтобы мы могли получить доступ к 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 был изменен. Не хорошая идея.

Итак, это оставляет нас с созданием Fake 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);

Теперь, чтобы собрать все это вместе.

Ive также реализовал метод 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');
}

Мы ТОЛЬКО хотим Document и Element, чтобы наследовать наши новые методы, потому что они называют прототипы, которые не существуют во всех Node интерфейсах. например getElementsByClassName, querySelectorAll и т.д.

Если вы хотите уменьшить свой код, вы можете использовать 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');
}

Просто убедитесь, что вы не пытаетесь использовать его на любом node, который не является Document или Element.

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');