Мое обходное решение (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
- это массив, который содержит ваши входные / ключи / поля и т. д.
Поскольку вы меняете .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>
Это сработало для меня
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>
Во-первых, приведенный ниже код должен сделать трюк самым простым способом.
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/
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>
то, что вы делали неправильно, - каждый раз, когда вы меняете класс, коллизия повторно оценивает и уменьшает размер.
document.getElementsByClassName возвращает объект HTMLCollection , который является живым
HTMLCollection в HTML DOM является живым; он автоматически обновляется при изменении базового документа.
blockquote>Поэтому, когда вы вызываете
blockSet[0].className = "block-selected";
Вы изменили базовый документ, и этот элемент больше не находится в коллекции (blockSet [0] теперь второй элемент в вашем исходном выборе).
var blockSet = Array.slice.call (document.getElementsByClassName("block-default"));
, чтобы сделать коллекцию HTML регулярным массивом.
– HBP
12 April 2015 в 09:28
$(".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';
}
Ваша ошибка возникает из-за того, что .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
}
Я думаю, что это лучший способ сделать это. Поскольку classList.add()
и classList.remove()
помогут вам изменить свой класс, не выбирая класс других, которые у вас есть на вашем div (если у вас есть). Кроме того, вам нужно добавить новый, прежде чем удалить старый, или у вас будет такая же проблема, как и раньше.
Эта ошибка возникает из-за того, что вам нужно выполнить
blockSet[0].className = 'block-selected'
Вы не должны писать blockSet [1], blockSet [2] ...
blockquote>Вы можете сделать:
for (var s=0;s<blockSetLength;s++) { blockSet[0].className = 'block-selected'; }
Здесь вы можете найти рабочий код
<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/
Определение и использование
Использование этого свойства не рекомендуется из-за последствий для производительности (из-за живого DOMCollection, где любые изменения документа должны отражаться на возвращаемом объекте немедленно) и сложность (удаление элемента из документа приведет к немедленным изменениям в коллекции).
blockquote>И просто добавив только
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>
Или мы можем использовать его используйте
blockquote>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>
Надеюсь, мой пост это поможет, сообщите мне, если у вас есть какие-либо вопросы.
Назначив значение .className
, вы переписываете каждый класс этого элемента.
Удалить класс:
blockSet[0].classList.remove('block-default');
Добавить новый класс:
blockSet[0].classList.add('block-selected');
Хороший момент для начала, когда вы пытаетесь сделать что-то, jQuery, как правило, для вас, http://youmightnotneedjquery.com/
Element.classList
.
– royhowie
13 June 2015 в 09: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>
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 ]
Надеюсь, что это поможет!
Используйте это для вашего 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>
У вас уже есть хорошие решения.
Я думаю, что лучший из них - тот, который у Рика Хичкока.
Но решение, которое я часто использую, чтобы быть в безопасности, когда делаете такие вещи, как перемещение коллекции назад
var nmax = blockSet.length - 1;
for (var n=nmax; n>=0; n--) {
blockSet[n].className = 'block-selected';
}
Это изолирует вас от изменений в коллекции
getElementsByClassName
вы взаимодействуете с живой структурой данных, которая будет немедленно обновляться ... цикл назад не повлияет на ваши индексы.
– maioman
16 June 2015 в 13:42