className yalnızca diğer tüm sınıfları değiştiriyor

getElementsByClassName() ile JavaScript ile küçük bir metin yapıyorum ve bazı istenmeyen sonuçlar alıyorum. Komut dosyasının her CSS sınıfını yeni bir sınıfa değiştirmesini istiyorum. Mesele şu ki, diğer her sınıf sadece değişiyor ...

Bu konuyu pratik amaçlı olduğu gibi saf JS kullanmak istiyorum.

Akla gelen ilk şey beyaz boşluklardı, bunu kaldırırken herhangi bir fark yaratmadı.

Birisi yanlış yaptığımı mı gösterebilir?

<html>
    <head>
       <link rel="stylesheet" type="text/css" href="default.css">
    </head>
    <body>
        <div class="block-default">BLOCK1</div>
        <div class="block-default">BLOCK2</div>
        <div class="block-default">BLOCK3</div>
        <div class="block-default">BLOCK4</div>
        <div class="block-default">BLOCK5</div>
        <div class="block-default">BLOCK6</div>
        <div class="block-default">BLOCK7</div>
        <div class="block-default">BLOCK8</div>
        <script>

    var blockSet = document.getElementsByClassName("block-default");
    var blockSetLength = blockSet.length;

    blockSet[0].className = "block-selected";
    blockSet[1].className = "block-selected";
    blockSet[2].className = "block-selected";
    blockSet[3].className = "block-selected";
    blockSet[4].className = "block-selected";
    blockSet[5].className = "block-selected";
    blockSet[6].className = "block-selected";
    blockSet[7].className = "block-selected";   

        </script>
    </body>
</html>

CSS Sınıfları:

.block-default {
    width: 100px;
    height:50px;
    background-color: green;
    border: 1px solid red;
    padding:10px;
}

.block-selected {
    width: 100px;
    height:50px;
    background-color: blue;
    border: 1px solid white;
    padding:10px;
 }
24
katma yazar Drakes, kaynak
Bu, birçok sorunun kopyasıdır: 1 , 2 , 3 , 4 , 5 . Sormadan önce sorunuzu araştırdınız mı?
katma yazar Anonymous, kaynak
blockSetLength ne için?
katma yazar Yaakov Ainspan, kaynak
Sınıf değiştirmek istediğiniz zaman ve hangi eleman sınıfının değişeceğini açıklar mısınız? click olayındaki sınıfı değiştirmek istiyorsanız?
katma yazar Mitul, kaynak
Eğer kodunuzu saklamak istiyorsanız, sadece yükselmek yerine alçaltabilirsiniz. BlockSet [7] ile başlayın ve blockSet [0] 'a gidin
katma yazar Lain, kaynak

15 cevap

Çünkü bir HTMLCollection . Öğeleri aynı güncelleştirmelerden geçtiğinde aynı sınıfa sahip öğelere sahip koleksiyon ( blok-varsayılan ).

Başka bir deyişle, bir öğenin .className öğesini değiştirdiğinizde, koleksiyonu bu öğeyi dışlar. . Bu, HTMLCollection öğesinin boyutunun azalacağı anlamına gelir. Ayrıca, söz konusu sınıfa sahip bir öğe DOM’e eklenirse boyut artar .

Bunu çözmek için her zaman yalnızca .className ilk öğesini değiştirebilirsiniz.

for(var i = 0; i

Notes: Intead of changing class element by element, you can iterate through elements with for and change .className.

<div class="snippet" data-lang="js" data-hide="true"> <div class="snippet-code snippet-currently-hidden">

var blockSet = document.getElementsByClassName("block-default");
var blockSetLength = blockSet.length;

console.log(blockSet);

for(var i = 0; i
.block-default {
    width: 100px;
    height:50px;
    background-color: green;
    border: 1px solid red;
    padding:10px;
}

.block-selected {
    width: 100px;
    height:50px;
    background-color: blue;
    border: 1px solid white;
    padding:10px;
 }
<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>
</div> </div>

DOM'a yeni bir öğe eklerseniz (koleksiyon değil) boyut aşağıdaki örnekte gösterildiği gibi artacaktır.

<div class="snippet" data-lang="js" data-hide="true"> <div class="snippet-code snippet-currently-hidden">

var blockSet = document.getElementsByClassName("block-default");
var blockSetLength = blockSet.length;

alert("Current size: " + blockSet.length);
document.body.innerHTML += '<div class="block-default">BLOCK9</div>';
alert("After adding an element in DOM size: " + blockSet.length);
.block-default {
    width: 100px;
    height:50px;
    background-color: green;
    border: 1px solid red;
    padding:10px;
}

.block-selected {
    width: 100px;
    height:50px;
    background-color: blue;
    border: 1px solid white;
    padding:10px;
 }
<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>
</div> </div>
21
katma
çok yararlı bir açıklama!
katma yazar Mel Viso Martinez, kaynak

getElementsByClassName() , className değişikliği değiştikçe live HTMLCollection döndüren
> querySelectorAll() ,
değişmeyecek bir canlı olmayan NodeList döndürür.

querySelectorAll() has better IE support than getElementsByClassName() (IE8+ vs. IE9+).
It's also much more flexible since it supports CSS selectors (CSS2 for IE8+ and CSS3 for IE9+).

Bununla birlikte, querySelectorAll() , getElementsByClassName() öğesinden daha yavaş olur.
Binlerce DOM öğesi işliyorsanız bunu aklınızda bulundurun.

Pasaj

<div class="snippet" data-lang="js" data-hide="true"> <div class="snippet-code snippet-currently-hidden">

var blockSet = document.querySelectorAll(".block-default");
var blockSetLength = blockSet.length;

blockSet[0].className = "block-selected";
blockSet[1].className = "block-selected";
blockSet[2].className = "block-selected";
blockSet[3].className = "block-selected";
blockSet[4].className = "block-selected";
blockSet[5].className = "block-selected";
blockSet[6].className = "block-selected";
blockSet[7].className = "block-selected";
.block-default {
  width: 100px;
  height: 50px;
  background-color: green;
  border: 1px solid red;
  padding: 10px;
}
.block-selected {
  width: 100px;
  height: 50px;
  background-color: blue;
  border: 1px solid white;
  padding: 10px;
}
<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>
</div> </div>
10
katma
Bu muhtemelen en güvenli yöntemdir. Diğer tüm çözümler, ilk öğeyi çok özel durumlarda hala sorunlu olabilen canlı bir koleksiyonda ayarlamanızı önerir.
katma yazar light, kaynak
Herhangi bir nedenle querySelectorAll kullanmak istemiyorsanız veya alternatif bir çözüm istiyorsanız, Array.from (liveNodeList) veya [] 'ı kullanabilirsiniz. slcode.call (liveNodeList) , liveNodeList 'i statik değişken bir diziye dönüştürmek için.
katma yazar Awal Garg, kaynak

.className 'a bir değer atayarak, o öğedeki her sınıfın üzerine yazarsınız. Bakmak isteyebileceğiniz şey .classList niteliğidir.

Bir sınıfı kaldır:

blockSet[0].classList.remove('block-default');

Yeni sınıfı ekle:

blockSet[0].classList.add('block-selected');

A good point to start with, when your trying to do stuff, jQuery usually did for you, is http://youmightnotneedjquery.com/

6
katma
Gerçekten mantıklı bir şey önerdiğiniz için + 1'leyin: Element.classList .
katma yazar royhowie, kaynak

Zaten bazı iyi çözümleriniz var.

Bence en iyisi Rick Hitchcock'dan olanı.

Ancak, sık sık kullandığım, böyle şeyler yaparken güvende olmak için kullandığım bir çözüm, koleksiyonun geriye doğru gitmesini sağlamak.

var nmax = blockSet.length - 1;
for (var n=nmax; n>=0; n--) {
    blockSet[n].className = 'block-selected';
}

Bu sizi koleksiyondaki değişikliklerden izole eder

5
katma
bu en iyi çözümdür; Mesele şu ki, getElementsByClassName ile çalışmak, derhal güncellenecek canlı bir veri yapısıyla etkileşime giriyorsunuzdur ... geriye doğru geri döngü indekslerinizi etkilemez.
katma yazar maioman, kaynak

document.getElementsByClassName returns a HTMLCollection object, which is live

HTML DOM’deki bir HTMLCollection yayında; otomatik olarak güncellenir   temel belge değiştiğinde.

Yani aradığında

blockSet[0].className = "block-selected";

Temel dokümanı değiştirdiniz ve bu öğe artık koleksiyonda değil (blokSet [0] şimdi orijinal seçiminizdeki ikinci öğedir).

3
katma
Kesinlikle. JQuery'nin $ (". Block-default") olarak adlandırılan HTMLCollection ile değil, Dizilerle çalıştığından bahsetmeye değer, bu nedenle bu davranışa bu kitaplıkla erişemezsiniz.
katma yazar Jan Turoň, kaynak
HTML koleksiyonunu düzenli bir diziye dönüştürmek için var blockSet = Array.slice.call (document.getElementsByClassName ("block-default")); öğesini kullanın.
katma yazar HBP, kaynak

Bu hata, blockSet öğesinin "canlı" olan bir HTMLCollection olması nedeniyle oluşur. HTMLCollections , sayfa güncellemesindeki öğeler olarak güncellenir.

Bir className 'i her değiştirdiğinizde, blockSet tek tek kısaltırsınız.

Bu sorunu çözmek için bunun yerine şunu yapın:

for (var i = 0; i < 8; i += 1) {
    blockSet[ 0 ].className = "block-selected";
}

Bu şekilde, HTMLCollection 'ınızı tek tek keserek ayırırsınız.

Iteration 1: [ div1, div2, div3, div4, div5, div6, div7, div8 ]

Iteration 2: [ div2, div3, div4, div5, div6, div7, div8 ]

Iteration 3: [ div3, div4, div5, div6, div7, div8 ]

Iteration 4: [ div4, div5, div6, div7, div8 ]

Iteration 5: [ div5, div6, div7, div8 ]

Iteration 6: [ div6, div7, div8 ]

Iteration 7: [ div7, div8 ]

Iteration 8: [ div8 ]

Umarım yardımcı olur!

2
katma

Bunu yapmanın en basit yolu aşağıdaki kodu kullanmaktır:

while(blockSetLength--){ 
    //this will change the class of n-1 dom object 
    blockSet[blockSetLength].className='block-selected';
}
2
katma

Bu benim için çalıştı

<div class="snippet" data-lang="js" data-hide="false"> <div class="snippet-code">

var blockSet = document.getElementsByClassName("block-default");
    var blockSetLength = blockSet.length;
 blockSet[0].className = "block-selected";
 blockSet[0].className = "block-selected";
 blockSet[0].className = "block-selected";
 blockSet[0].className = "block-selected";
 blockSet[0].className = "block-selected";
 blockSet[0].className = "block-selected";
 blockSet[0].className = "block-selected";
 blockSet[0].className = "block-selected";

   
.block-default {
    width: 100px;
    height:50px;
    background-color: green;
    border: 1px solid red;
    padding:10px;
}

.block-selected {
    width: 100px;
    height:50px;
    background-color: blue;
    border: 1px solid white;
    padding:10px;
 }
<div class ="block-default">BLOCK1</div>
<div class ="block-default">BLOCK2</div>
<div class ="block-default">BLOCK3</div>
<div class ="block-default">BLOCK4</div>
<div class ="block-default">BLOCK5</div>
<div class ="block-default">BLOCK6</div>
<div class ="block-default">BLOCK7</div>
<div class ="block-default">BLOCK8</div>
</div> </div>
1
katma
@NarawaGames Evet
katma yazar Akshay, kaynak
döngüsü için bir veya bir iken döngü kullanabilirsiniz.
katma yazar sag, kaynak
Çocuklar, bunu temizlediğiniz için teşekkür ederim! İşlem devam ederken, dizideki ilk öğeyi işaret eden pim uzunluğa bağlı olarak tüm bölümü değiştirir! Şerefe beyler - Ryan
katma yazar EvilGenius82, kaynak

İlk olarak, aşağıdaki kod hileyi en basit şekilde yapmalıdır.

var blockSet = document.getElementsByClassName("block-default").className = "block-selected";

Daha sonra kodunuzla ilgili yanlış giden veya daha doğrusu olan şey nedir:

blockSet[0].className = 'block-selected';

ilk blok set öğesini artık bir blok set öğesi yapmaz. Bu seni 7 kişi kaldı. Şimdi,

blockSet[1].className = 'block-selected';

Kalanlardan ikincisini seçer. Tam listenizin üçüncüsü hangisi? Şimdi 6 tane kaldı.

blockSet[2].className = 'block-selected';

Bu, kalanı üçüncü seçenektir, ki BLOCK5'iniz seçilen bir bloğa dönüştürülür. Ve 5 kalmanızla sonuçlanır.

blockSet[3].className = 'block-selected'; 

Bu, kalanlar arasında dördüncü saydığınızda yine BLOK7 olan dördüncü olanı bulur. Ve şimdi 4 tane kaldı.

blockSet [4] daha sonra böyle bir eleman bulamıyor ve çalıştırılamıyor. Kodunuzda olan budur. Oldukça ilginç. :).

Here is a jsfiddle alerting you the values as they run: https://jsfiddle.net/xz7h57jv/

0
katma

Çalışma kodunu burada bulabilirsiniz.

<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>


var blockSet = document.getElementsByClassName("block-default");
var blockSetLength = blockSet.length;

for (i = 0; i < blockSetLength; i++) {
    blockSet[0].className = "block-selected";
}

Demo link http://jsfiddle.net/patelmit69/9koxfaLq/1/

0
katma
Başka cevaplardan yeni neler getirdin?
katma yazar adricadar, kaynak
Bu kod bir hata içeriyor, blockSet [0] .className yerine blockSet [i] .className olmalı. Eğer kasıtlıysa, o zaman for döngüsü gereksizdir.
katma yazar Karanvir Kang, kaynak

Bu hata yapmanız gereken çünkü

blockSet[0].className = 'block-selected'

blockSet [1], blockSet [2] ...

yazmazsınız

Yapabilirsin:

for (var s=0;s
0
katma
Şu anki cevaplardan farklı olanı ne?
katma yazar adricadar, kaynak

Tanım ve Kullanım

  1. getElementsByClassName() yöntemi, hepsinden oluşan bir koleksiyon döndürür Belgedeki, belirtilen sınıf adına sahip öğeler NodeList nesnesi.

  2. NodeList nesnesi, bir düğüm koleksiyonunu temsil eder. Düğümler olabilir     Dizin numaralarıyla erişilebilir. Dizin 0'dan başlar.

Bu özelliğin kullanımı performans nedeniyle önerilmez   çıkarımlar (herhangi bir değişiklik yapılan canlı DOMCollection nedeniyle)   belge derhal iade edilen nesneye yansıtılmalıdır) ve   karmaşıklık (bir öğenin belgeden kaldırılması,   derhal yapılan değişiklikler).

Ve sadece sadece blockSet [0] .className = "block-selected"; ekleyerek ve düğmesine tıklamak suretiyle her tıklama için her div'i renklendirin, böylece hepsini renklendirmek için 8 kez tıklamamız gerekir divs ve aşağıdaki canlı örneği görün

<div class="snippet" data-lang="js" data-hide="true"> <div class="snippet-code snippet-currently-hidden">

function myFunction() {
  var blockSet = document.getElementsByClassName('block-default');

  blockSet[0].className = "block-selected";

}
.block-default {
  width: 100px;
  height: 50px;
  background-color: green;
  border: 1px solid red;
  padding: 10px;
}
.block-selected {
  width: 100px;
  height: 50px;
  background-color: blue;
  border: 1px solid white;
  padding: 10px;
}
<button onclick="myFunction()">change</button>

<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>
</div> </div>

Ve sadece var ekleyerek var blockSet = document.getElementsByClassName ('block-default'); alert ("Length are:" + blockSet.length + "\ nİlk öğe:" + blockSet [0] .childNodes [0] .nodeValue);;

  • Uzunluk: 8
  • İlk Öğe: block1

Aşağıdaki canlı örnekte olduğu gibi:

<div class="snippet" data-lang="js" data-hide="true"> <div class="snippet-code snippet-currently-hidden">

function myFunction() {
  var blockSet = document.getElementsByClassName('block-default');

  /*
      blockSet[0].className = "block-selected";
      blockSet[1].className = "block-selected";
      blockSet[2].className = "block-selected";
      blockSet[3].className = "block-selected";
      blockSet[4].className = "block-selected";
      blockSet[5].className = "block-selected";
      blockSet[6].className = "block-selected";
      blockSet[7].className = "block-selected";*/

  alert("Length are: " + blockSet.length + "\nFirst Item is: " + blockSet[0].childNodes[0].nodeValue);
}
.block-default {

  width: 100px;

  height: 50px;

  background-color: green;

  border: 1px solid red;

  padding: 10px;

}

.block-selected {

  width: 100px;

  height: 50px;

  background-color: blue;

  border: 1px solid white;

  padding: 10px;

}
<button onclick="myFunction()">change</button>

<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>
</div> </div>

Veya ile birlikte document.getElementsByClassName öğesini kullanabiliriz.   döngü bu yüzden yakın bir alternatif, Rick Hitchcock'un yanıtladığı gibi querySelectorAll olur.   o.

<div class="snippet" data-lang="js" data-hide="true"> <div class="snippet-code snippet-currently-hidden">

function myFunction() {
  var blockSet = document.querySelectorAll('.block-default');
  blockSet[0].className = "block-selected";
  blockSet[1].className = "block-selected";
  blockSet[2].className = "block-selected";
  blockSet[3].className = "block-selected";
  blockSet[4].className = "block-selected";
  blockSet[5].className = "block-selected";
  blockSet[6].className = "block-selected";
  blockSet[7].className = "block-selected";
}
.block-default {
  width: 100px;
  height: 50px;
  background-color: green;
  border: 1px solid red;
  padding: 10px;
}
.block-selected {
  width: 100px;
  height: 50px;
  background-color: blue;
  border: 1px solid white;
  padding: 10px;
}
<button onclick="myFunction()">change</button>

<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>
</div> </div>

Umarım gönderim yardımcı olur, herhangi bir sorunuz varsa bana bildirin.

0
katma

Bunu JavaScript kodunuz için kullanın. bu senin hatanı düzeltir

<script>
    var blockSet = document.getElementsByClassName("block-default");
    var blockSetLength = blockSet.length;

    for (var i = blockSet.length - 1; i >= 0; i--) {
        blockSet[i].className = "block-selected";
    };
</script>
0
katma

<div class="snippet" data-lang="js" data-hide="false"> <div class="snippet-code">

function change() {
  var blockSet = document.getElementsByClassName("block-default");
  var blockSetLength = blockSet.length;

  for (var i = 0; i < blockSetLength; i++) {

    blockSet[0].className = "block-selected";
  }
}
.block-default {
  width: 100px;
  height: 50px;
  background-color: green;
  border: 1px solid red;
  padding: 10px;
}
.block-selected {
  width: 100px;
  height: 50px;
  background-color: blue;
  border: 1px solid white;
  padding: 10px;
}
<button onclick="change()">change</button>

<div class="block-default">BLOCK1</div>
<div class="block-default">BLOCK2</div>
<div class="block-default">BLOCK3</div>
<div class="block-default">BLOCK4</div>
<div class="block-default">BLOCK5</div>
<div class="block-default">BLOCK6</div>
<div class="block-default">BLOCK7</div>
<div class="block-default">BLOCK8</div>
</div> </div>

yanlış yaptığınız şey, sınıfı her değiştirdiğinizde koleksiyonun yeniden değerlendirdiği ve boyut olarak küçüldüğüdür.

0
katma
Şu anki cevaplardan farklı olanı ne?
katma yazar adricadar, kaynak

Hata, .className, canlı bir HTMLCollection döndürdüğü için oluşur. Yani böyle bir şey yaptığınızda:

blockSet[0].className = "block-selected";

blockSet [0] koleksiyonunuz blockSet [1] olacaktır. Yani satırı çalıştırdığınızda:

blockSet[1].className = "block-selected";

Düşündüğün blockSet [1] 'i değiştirmedin ama başlangıç ​​ blockSet [2] ' yi değiştir.

Yani bunu yapabilirsiniz:

var blockSet = document.getElementsByClassName("block-default");
var blockSetLength = blockSet.length;
for(var i=0;i

http://jsfiddle.net/94dqffa7/

Bunu yapmanın en iyi yolu olduğunu düşünüyorum. Çünkü classList.add() ve classList.remove() , sınıfınızdaki diğer sınıfları elemeden sınıfınızı değiştirmenize yardımcı olacaktır (eğer varsa) . Ayrıca, eskisini çıkarmadan önce yenisini eklemeniz gerekir, aksi takdirde eskisi gibi sorun yaşarsınız.

0
katma