Hola chicos escribí el siguiente código:

 function flyoutFirstHeadline() {
    document.querySelectorAll('.category-top-navigation__item--column-1 .category-top-navigation__item__headline')[0].classList.add('category-top-navigation__item__headline--first');
    document.querySelectorAll('.category-top-navigation__item--column-2 .category-top-navigation__item__headline')[0].classList.add('category-top-navigation__item__headline--first');
    document.querySelectorAll('.category-top-navigation__item--column-3 .category-top-navigation__item__headline')[0].classList.add('category-top-navigation__item__headline--first');
 }

Básicamente, solo estoy agregando alguna clase a la primera aparición de .category-top-navigation__item__headline para cada columna que tengo en el diseño. Tengo un máximo de 3 columnas a partir de 1.

Estoy pensando en formas de optimizar y hacer mi código más bonito.

Estoy pensando que tal vez sea mejor realizar un ciclo que recorra los números de columna de categoría e incremente en 1 cada vez que se ejecute hasta llegar a 3. ¿O tal vez hay una mejor manera de hacerlo?

1
Mikkel Fennefoss 10 sep. 2018 a las 10:59

4 respuestas

La mejor respuesta

¿Por qué no obtener los elementos de título y asignar la clase? No parece haber ninguna necesidad de incluir la clase de columna también.

function flyoutFirstHeadline() {
  const
    headLines = document.querySelectorAll('.category-top-navigation__item__headline:first-child');
    
  for(let index=0; index < headLines.length; index++) {
    headLines[index].classList.add('category-top-navigation__item__headline--first');
  }
}


flyoutFirstHeadline();
.category-top-navigation__item__headline--first {
  color: blue;
}
<div class=".category-top-navigation__item--column-1">
  <h1 class="category-top-navigation__item__headline">Col 1 / headline 1</h1>
  <h2 class="category-top-navigation__item__headline">Col 1 / headline 2</h2>
</div>

<div class=".category-top-navigation__item--column-2">
  <h1 class="category-top-navigation__item__headline">Col 2 / headline 1</h1>
  <h2 class="category-top-navigation__item__headline">Col 2 / headline 2</h2>
</div>

<div class=".category-top-navigation__item--column-3">
  <h1 class="category-top-navigation__item__headline">Col 3 / headline 1</h1>
  <h2 class="category-top-navigation__item__headline">Col 3 / headline 2</h2>
</div>

He actualizado mi respuesta. Aplica una clase al primer elemento de encabezado por columna y hace que su texto sea azul.

0
Thijs 10 sep. 2018 a las 09:40

Al hablar de rendimiento, lo que tienes ya es bueno. Aunque como dijo @BoltClock en los comentarios, .querySelector(...) en lugar de .querySelectorAll(...)[0] sería aún mejor, simplemente elige el primer elemento.

Si estás buscando "más bonita" ..

document
.querySelectorAll('.category-top-navigation__item__headline:first-child')
.forEach(el => el.classList.add('category-top-navigation__item__headline--first'))

Y, aún más bonito, con una legibilidad posiblemente mejor.

const headline = 'category-top-navigation__item__headline'

document.querySelectorAll(`${headline}:first-child`)
.forEach(el => el.classList.add(`${headline}--first`))

Tenga en cuenta que la respuesta anterior utiliza el truco first-child de la respuesta de Thijs.

0
rmn 10 sep. 2018 a las 11:51

Una solución centrada en la claridad y la flexibilidad:

  1. sin valores mágicos
  2. use for..of para iterables
  3. funciones de uso común con alias con nombre corto
  4. el elemento flexible coincide con el selector de atributos
  5. largas cadenas divididas en trozos fáciles de manejar
function flyoutFirstHeadline() {
  const firstHeadlineSelector = [
    '[class^="category-top-navigation__item--column-"]',
    '.category-top-navigation__item__headline:first-child'
  ].join(' ');

  const newClass = 'category-top-navigation__item__headline--first';

  for (const el of $$(firstHeadlineSelector)) {
    el.classList.add(newClass);
  }
}


// helpers

const $$ = document.querySelectorAll.bind(document);

flyoutFirstHeadline()
[class^="category-top-navigation__item--column-"] {
  margin-bottom: 1rem;
}

.category-top-navigation__item__headline--first {
  color: red;
}
<div class="category-top-navigation__item--column-1">category 1
  <div class="category-top-navigation__item__headline">headline 1</div>
  <div class="category-top-navigation__item__headline">headline 2</div>
</div>
<div class="category-top-navigation__item--column-2">category 2
  <div class="category-top-navigation__item__headline">headline 1</div>
  <div class="category-top-navigation__item__headline">headline 2</div>
</div>
<div class="category-top-navigation__item--column-3">category 3
  <div class="category-top-navigation__item__headline">headline 1</div>
  <div class="category-top-navigation__item__headline">headline 2</div>
</div>
0
marzelin 10 sep. 2018 a las 10:45

Puede seleccionar un nombre de clase que comience con alguna subcadena particular con la cadena de selección [class^=someStartingSubStr"]. Por lo tanto, puede seleccionar y cambiar todos los elementos que desee a la vez con:

function flyoutFirstHeadline() {
  Array.prototype.forEach.call(
    document.querySelectorAll(
      '[class^="category-top-navigation__item--column-"] .category-top-navigation__item__headline'
    ), (headline) => {
      headline.classList.add('category-top-navigation__item__headline--first');
    }
  );
}

Demo:

function flyoutFirstHeadline() {
  Array.prototype.forEach.call(
    document.querySelectorAll('[class^="column-"] .headline'),
    (headline) => {
      headline.classList.add('highlight');
    }
  );
}
flyoutFirstHeadline();
.highlight {
  background-color: yellow;
}
<div class="column-1">
  <div class="headline">headline</div>
</div>
<div class="column-2">
  <div class="headline">headline</div>
</div>
<div class="column-3">
  <div class="headline">headline</div>
</div>

También tenga en cuenta que si solo desea seleccionar el primer elemento que coincida con un selector (como lo estaba haciendo con su código original), debe usar querySelector y no querySelectorAll más [0].

0
CertainPerformance 10 sep. 2018 a las 08:35