2013-06-04 2 views
0

У меня есть некоторые проблемы при расческе DOM, вызывающего два атрибута - id и name - когда в for-loop.javascript: ошибка объединения DOM «id» и «name»

У меня есть HTML раздел с таблицей, где каждая ячейка имеет свой собственный идентификатор, но тот же атрибут имени: <td id="p1" name="f" ></td> <td id="p2" name="f" ></td> ... <td id="p47" name="f" ></td>

Теперь я хочу, чтобы случайно поместить изображения в этих клетках с помощью следующей функции:

function begintest() { 
    var i; 
    var randnum; 
    var randnum2; 
    for(i=1;i<48;i++) {document.getElementById("p" + i).name="f"; 
    for(i=1;i<22;i++) { 
     randnum = Math.floor(Math.random() * 6) + 1; //picture of one sort 
     randnum2 = Math.floor(Math.random() * 47) + 1; //random position between 1-47 
     while(document.getElementById("p" + randnum2).name=="t") { //check whether position taken 
      randnum2 = Math.floor(Math.random() * 47) + 1; //random position between 1-47 
     } 
     document.getElementById("p" + randnum2).name = "t"; //true 
     document.getElementById("p" + randnum2).style.backgroundImage = "url(i" + randnum + ".png)"; //put in image first sort 
    } 

    for(i=1;i<48;i++) { //picture of second sort 
     if(document.getElementById("p" + i).name=="f") { //if not filled with first sort 
      randnum = Math.floor(Math.random() * 26) + 7; //take second sort 
      document.getElementById("p" + i).style.backgroundImage = "url(i" + randnum + ".png)"; //put in image second sort 
     } 
    } 

} 

Но я всегда получаю информацию отладки:

TypeError: document.getElementById(...) is null for the functions where a DOM reference with 2 attributes is used, such as: if(document.getElementById("p" + i).name=="f")

Как это может быть? Есть ли другой способ справиться с этим?

+0

Там нет ничего плохого с кодом * само по себе *. Если * document.getElementById * возвращает 'null', это означает, что он не нашел элемент. Попытка получить доступ к любому свойству «null» вызовет ошибку. – RobG

+0

совершенно правый. Спасибо большое! – user2451428

+0

Когда и где вы называете 'begintest()'? Он может быть вызван до того, как DOM будет готов. –

ответ

0

Я бы предложил использовать несколько иной подход.

  1. имя атрибута: Почему не использовать свой тег? Как «активировано»? Он будет менее запутанным для системы ...

  2. Библиотека: Я бы использовал библиотеку для управления этим. jQuery отлично работает.

Например, заносить бы <td> элемент с id = 1, только если он активирован:

jQuery("td#p1[activated]") 

Это скажет вам, является ли выбранный элемент уже заполнено или нет:

jQuery("td#p1").is("[activated]") 
+0

ОК теперь мне стыдно ... Я сделал опечатку. Я просто использовал дважды id = 42, но пропустил id = 41 – user2451428

+0

с jQuery: я использую html-платформу внутри другой платформы, которая не поддерживает jQuery. но ваше предложение действительно намного проще! – user2451428

0

Это может быть только ошибка с копированием, но в вашем первом цикле отсутствует закрывающая фигурная скобка.

+0

это была ошибка копирования-вставки, вы были правы :) – user2451428

0

Вместо использования,

if(document.getElementById("p" + i).name=="f") 

Используйте эту версию

if(document.getElementById("p" + i).getAttribute("name") =="f") 

надежда, что помогает

0

Это работает (jsFiddle):

function beginTest() { 
    var i, 
     randomImage, 
     randomP, 
     p; 
    for (i = 1; i < 48; i += 1) { 
     p = document.getElementById('p' + i); 
     p.name = 'f';  // using the name attribute as a flag 
    } 
    for (i = 1; i < 22; i += 1) { 
     //check whether position taken 
     while (p.name !== 't') { 
      randomImage = Math.floor(Math.random() * 6) + 1; // picture of one sort 
      p.name = 't'; 
      p.style.backgroundImage = 'url(i' + randomImage + '.png)'; // put in image first sort 
      p.innerText = p.style.backgroundImage; 
      randomP = Math.floor(Math.random() * 47) + 1;  // random position between 1-47 
      p = document.getElementById('p' + randomP);   // cache DOM lookup 
     } 
    } 
    for (i = 1; i < 48; i += 1) {        // picture of second sort 
     p = document.getElementById('p' + i);     // cache DOM lookup 
     if (p.name=="f") {  // if not filled with first sort 
      randomImage = Math.floor(Math.random() * 26) + 7;  // take second sort 
      p.style.backgroundImage = 'url(i' + randomImage + '.png)'; //put in image second sort 
      p.innerText = p.style.backgroundImage; 
     } 
    } 
} 
beginTest(); 

Вот более эффективный способ сделать это (и jsFiddle):

function beginTest() { 
    var i, 
     randomImage, 
     randomP, 
     p, 
     randArr =[]; 
    for (i = 1; i < 48; i += 1) { 
     p = document.getElementById('p' + i); 
     p.innerText = p.id // visually distinguish which p elements do not have a background image 
     randArr.push(i); 
    } 
    randArr.sort(function (a, b) { 
     var randA = Math.floor(Math.random() * 47) + 1, 
      randB = Math.floor(Math.random() * 47) + 1; 
     return randA - randB; 
    }); 
    for (i = 0; i < randArr.length; i += 1) { 
     randomImage = Math.floor(Math.random() * 6) + 1; // picture of one sort 
     p = document.getElementById('p' + randArr[i]);   // cache DOM lookup 
     p.style.backgroundImage = 'url(i' + randomImage + '.png)'; // put in image first sort 
     p.innerText = p.style.backgroundImage; 
    } 
} 
beginTest();