Почему этот массив игнорирует порядок операций? [Дубликат]

Мое обходное решение (JavaScript)

    var s1 = " SELECT "

 + "FROM   table t "

 + "  where t.field in ";

  var s3 = '(';

  for(var i =0;i<searchTerms.length;i++)
  {
    if(i+1 == searchTerms.length)
    {
     s3  = s3+'?)';
    }
    else
    {
        s3  = s3+'?, ' ;
    }
   }
    var query = s1+s3;

    var pstmt = connection.prepareStatement(query);

     for(var i =0;i<searchTerms.length;i++)
    {
        pstmt.setString(i+1, searchTerms[i]);
    }

SearchTerms - это массив, который содержит ваши входные / ключи / поля и т. д.

24
задан royhowie 13 June 2015 в 08:51
поделиться

15 ответов

Поскольку вы меняете .className blockSet, который является HTMLCollection . Коллекция, которая имеет элементы с одним и тем же классом (block-default), изменится, когда элементы будут испытывать некоторые обновления.

Другими словами, когда вы меняете .className элемента, коллекция исключает этот элемент. Это означает, что размер HTMLCollection уменьшится. Также размер будет увеличиваться, если элемент с этим классом добавлен в DOM.

Чтобы решить эту проблему, вы всегда можете изменить только первый элемент .className.

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

Примечания: Integer для изменения элемента класса по элементу, вы можете перебирать элементы с помощью for и изменять .className.

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

console.log(blockSet);

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

Если вы добавите новый элемент в DOM (а не в коллекцию), размер увеличится, как показано в примере ниже.

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>

21
ответ дан adricadar 17 August 2018 в 12:05
поделиться

Это сработало для меня

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>

1
ответ дан Akshay 17 August 2018 в 12:05
поделиться
  • 1
    Ребята, спасибо, что поняли это для меня! Так как процесс был вживую, вывод, указывающий на первый элемент в массиве, изменил бы весь раздел на основе длины! Приветственные ребята - Райан – EvilGenius82 13 April 2015 в 09:37
  • 2
    Вы можете использовать цикл for или цикл while, правильно? – sag 15 June 2015 в 18:49
  • 3
    @NarawaGames Да – Akshay 16 June 2015 в 08:47

Во-первых, приведенный ниже код должен сделать трюк самым простым способом.

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

Далее, что не так с вашим кодом, или, скорее, что интересно, что происходит:

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

делает первый элемент набора блоков больше не элементом набора блоков. Это оставляет вам 7 оставшихся. Теперь

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

Выбирает второй из оставшихся. Это будет третий из ваших полных списков. Теперь у вас осталось 6.

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

Это делает третий среди остальных, который будет вашим BLOCK5 в выбранном блоке. И результат в том, что у вас осталось 5.

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

Это снова находит ваш четвертый, который BLOCK7, когда вы считаете четвертым среди оставшихся. И теперь у вас осталось 4.

blockSet [4] не находит такого элемента и не может выполнить. Это то, что происходит с вашим кодом. Довольно интересно. :).

Вот jsfiddle, предупреждающий о ваших значениях при запуске: https://jsfiddle.net/xz7h57jv/

0
ответ дан Arathi Sreekumar 17 August 2018 в 12:05
поделиться

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>

то, что вы делали неправильно, - каждый раз, когда вы меняете класс, коллизия повторно оценивает и уменьшает размер.

0
ответ дан Asheesh Kumar 17 August 2018 в 12:05
поделиться

document.getElementsByClassName возвращает объект HTMLCollection , который является живым

HTMLCollection в HTML DOM является живым; он автоматически обновляется при изменении базового документа.

Поэтому, когда вы вызываете

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

Вы изменили базовый документ, и этот элемент больше не находится в коллекции (blockSet [0] теперь второй элемент в вашем исходном выборе).

3
ответ дан Jan Turoň 17 August 2018 в 12:05
поделиться
  • 1
    Используйте var blockSet = Array.slice.call (document.getElementsByClassName("block-default"));, чтобы сделать коллекцию HTML регулярным массивом. – HBP 12 April 2015 в 09:28
  • 2
    В точку. Стоит упомянуть, что jQuery работает с массивами, а не с HTMLCollection при вызове $(".block-default"), поэтому вы не можете добиться такого поведения с этой библиотекой. – Jan Turoň 12 April 2015 в 09:35

Самый простой способ сделать это - использовать приведенный ниже код:

while(blockSetLength--){ 
    //this will change the class of n-1 dom object 
    blockSet[blockSetLength].className='block-selected';
}
2
ответ дан jmarkmurphy 17 August 2018 в 12:05
поделиться

Ваша ошибка возникает из-за того, что .className возвращает живой HTMLCollection. Поэтому, когда вы делаете что-то вроде этого:

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

Ваша коллекция blockSet[0] станет blockSet[1]. Поэтому, когда вы выполняете строку:

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

Вы не меняете blockSet[1], который вы думаете, но вы меняете стартовый blockSet[2].

Итак, вы можете сделать это:

var blockSet = document.getElementsByClassName("block-default");
var blockSetLength = blockSet.length;
for(var i=0;i<blockSetLength;i++){
    blockSet[0].classList.add('block-selected'); //add the new class first
    blockSet[0].classList.remove('block-default'); //delete the old one
}

http://jsfiddle.net/94dqffa7/

Я думаю, что это лучший способ сделать это. Поскольку classList.add() и classList.remove() помогут вам изменить свой класс, не выбирая класс других, которые у вас есть на вашем div (если у вас есть). Кроме того, вам нужно добавить новый, прежде чем удалить старый, или у вас будет такая же проблема, как и раньше.

0
ответ дан Maltir 17 August 2018 в 12:05
поделиться

Эта ошибка возникает из-за того, что вам нужно выполнить

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

Вы не должны писать blockSet [1], blockSet [2] ...

Вы можете сделать:

for (var s=0;s<blockSetLength;s++) {
  blockSet[0].className = 'block-selected';
}
0
ответ дан McOussKing 17 August 2018 в 12:05
поделиться

Здесь вы можете найти рабочий код

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

Демо-ссылка http://jsfiddle.net/patelmit69/9koxfaLq/1/

0
ответ дан Mitul 17 August 2018 в 12:05
поделиться
  • 1
    Что вы получаете от других ответов? – adricadar 16 June 2015 в 15:51
  • 2
    Этот код содержит ошибку, он должен быть blockSet [i] .className вместо blockSet [0] .className. Если это преднамеренно, то цикл for не нужен. – Karanvir Kang 18 June 2015 в 03:34

Определение и использование

  1. Метод getElementsByClassName () возвращает коллекцию всех элементов документа с указанным именем класса в качестве объекта NodeList.
  2. NodeList object представляет собой набор узлов. К узлам можно обращаться по номерам индексов. Индекс начинается с 0.

Использование этого свойства не рекомендуется из-за последствий для производительности (из-за живого DOMCollection, где любые изменения документа должны отражаться на возвращаемом объекте немедленно) и сложность (удаление элемента из документа приведет к немедленным изменениям в коллекции).

И просто добавив только blockSet[0].className = "block-selected"; и нажав на кнопку it colord каждый div на каждый щелчок, поэтому нам нужно щелкнуть 8 раз, чтобы покрасить все div и посмотреть живой пример ниже

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>

И добавив только var blockSet = document.getElementsByClassName('block-default'); alert("Length are: " + blockSet.length + "\nFirst Item is: " + blockSet[0].childNodes[0].nodeValue); без остального, он будет предупреждать

  • Длина: 8
  • Первый элемент: block1

Как в приведенном ниже примере:

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>

Или мы можем использовать его используйте document.getElementsByClassName с for loop, поэтому близкой альтернативой является querySelectorAll, как ответил Рик Хичкок.

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>

Надеюсь, мой пост это поможет, сообщите мне, если у вас есть какие-либо вопросы.

0
ответ дан Mohammed Moustafa 17 August 2018 в 12:05
поделиться

Назначив значение .className, вы переписываете каждый класс этого элемента.

Удалить класс:

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

Добавить новый класс:

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

Хороший момент для начала, когда вы пытаетесь сделать что-то, jQuery, как правило, для вас, http://youmightnotneedjquery.com/

6
ответ дан naeramarth7 17 August 2018 в 12:05
поделиться

Вместо использования getElementsByClassName() , который возвращает live HTMLCollection, который изменится с изменением className s, вы можете использовать querySelectorAll() , который возвращает неживой NodeList, который не изменится.

querySelectorAll() имеет лучшую поддержку IE, чем getElementsByClassName() (IE8 + против IE9 +). Он также намного более гибкий, поскольку он поддерживает селектор CSS (CSS2 для IE8 + и CSS3 для IE9 +).

Однако querySelectorAll() является медленнее , чем getElementsByClassName(). Помните об этом если вы обрабатываете тысячи элементов DOM.

Snippet

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>

10
ответ дан Rick Hitchcock 17 August 2018 в 12:05
поделиться
  • 1
    Вероятно, это самый безопасный метод. Все другие решения рекомендуют устанавливать первый элемент в живой коллекции, что может быть проблематичным в очень конкретных случаях. – light 13 June 2015 в 02:45
  • 2
    Если вы не хотите использовать querySelectorAll по какой-либо причине или просто хотите альтернативное решение, вы можете использовать Array.from(liveNodeList) или [].slice.call(liveNodeList) для преобразования liveNodeList в статический изменяемый массив. – Awal Garg 13 June 2015 в 09:13

Эта ошибка возникает, потому что blockSet является HTMLCollection, который является «живым». HTMLCollections обновлять как элементы обновления страницы.

Каждый раз, когда вы меняете className, вы делаете blockSet короче один за другим.

Чтобы решить эту проблему проблема: просто сделайте это вместо:

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

Таким образом вы один раз запустите свой HTMLCollection.

Итерация 1: [ div1, div2, div3, div4, div5, div6, div7, div8 ]

Итерация 2: [ div2, div3, div4, div5, div6, div7, div8 ]

Итерация 3: [ div3, div4, div5, div6, div7, div8 ]

Итерация 4: [ div4, div5, div6, div7, div8 ]

Итерация 5: [ div5, div6, div7, div8 ]

Итерация 6: [ div6, div7, div8 ]

Итерация 7: [ div7, div8 ]

Итерация 8: [ div8 ]

Надеюсь, что это поможет!

2
ответ дан sag 17 August 2018 в 12:05
поделиться

Используйте это для вашего javascript-кода. это исправит вашу ошибку

<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
ответ дан Tharaka Arachchige 17 August 2018 в 12:05
поделиться

У вас уже есть хорошие решения.

Я думаю, что лучший из них - тот, который у Рика Хичкока.

Но решение, которое я часто использую, чтобы быть в безопасности, когда делаете такие вещи, как перемещение коллекции назад

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

Это изолирует вас от изменений в коллекции

5
ответ дан vals 17 August 2018 в 12:05
поделиться
  • 1
    это лучшее решение; Дело в том, что при работе с getElementsByClassName вы взаимодействуете с живой структурой данных, которая будет немедленно обновляться ... цикл назад не повлияет на ваши индексы. – maioman 16 June 2015 в 13:42
Другие вопросы по тегам:

Похожие вопросы: