最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

class - Javascript onclick stops working, multiple dynamically created divs - Stack Overflow

programmeradmin0浏览0评论

I have run into a strange problem, i am creating a lot of dynamically divs. And i recently found out that some of my divs doesn't fire the onclick event? All the divs are created using the same template, so why are some not working? Most of the time, its the 4-5 from the bottom. If you click on one of the others and then try again, you might get one of those to trigger. But only sporadically.

Code to create the divs:

// Code to loop thru the number of players and create the divs accordingly
for (fieldNumber = 0; fieldNumber < 18; fieldNumber++) {
        var holderDiv = CreateDiv('gameCellLarge', '');
        holderDiv.style.width = 150 + extraCellWidth + 'px'; // Ändra storleken beroende på antalet spelare

        if (fieldNumber == 0 || fieldNumber == 6 || fieldNumber == 8 || fieldNumber == 17)
            newField = CreateDiv('gameCellMedium borderFull gameText', gameText[fieldNumber]);
        else
            newField = CreateDiv('gameCellMedium borderWithoutTop gameText', gameText[fieldNumber]);
        holderDiv.appendChild(newField);

        for (playerNumber = 0; playerNumber < players.length; playerNumber++) {            
            holderDiv.appendChild(players[playerNumber].InitField(fieldNumber));
        }
        gameFieldDiv.appendChild(holderDiv);
    }




GameField.prototype.InitField = function(fieldNumber) {
var newField = document.createElement("div");
if (fieldNumber == 0 || fieldNumber == 6 || fieldNumber == 8 || fieldNumber == 17)
    newField.className = 'gameCellSmall borderFull gameText gameTextAlign';
else
    newField.className = 'gameCellSmall borderWithoutTop gameText gameTextAlign';

var instance = this;
if (fieldNumber == 6 || fieldNumber == 7 || fieldNumber == 17) { }
else
    newField.onclick = function() { instance.DivClick(fieldNumber); return false; }

this.fields[fieldNumber] = newField;
this.score[fieldNumber] = 0;
return newField;
}

I added the return false to the click function, but it still behaves strangely. Why are some not triggering? I create around 18 divs / player. But it happens even if i just create one player.

Do i perhaps need to cancel the event once i am done with it? (Like the return false; is trying to do) Works sometimes but not always...

I have run out of ideas, here is a link to the script. Maybe i have just missed something. The script I have changed it a bit, so just press the button and click on the lower end of the game field (yatzy, kåk etc). It should popup alerts when clicked. Sometimes they work sometimes they don't.

I have run into a strange problem, i am creating a lot of dynamically divs. And i recently found out that some of my divs doesn't fire the onclick event? All the divs are created using the same template, so why are some not working? Most of the time, its the 4-5 from the bottom. If you click on one of the others and then try again, you might get one of those to trigger. But only sporadically.

Code to create the divs:

// Code to loop thru the number of players and create the divs accordingly
for (fieldNumber = 0; fieldNumber < 18; fieldNumber++) {
        var holderDiv = CreateDiv('gameCellLarge', '');
        holderDiv.style.width = 150 + extraCellWidth + 'px'; // Ändra storleken beroende på antalet spelare

        if (fieldNumber == 0 || fieldNumber == 6 || fieldNumber == 8 || fieldNumber == 17)
            newField = CreateDiv('gameCellMedium borderFull gameText', gameText[fieldNumber]);
        else
            newField = CreateDiv('gameCellMedium borderWithoutTop gameText', gameText[fieldNumber]);
        holderDiv.appendChild(newField);

        for (playerNumber = 0; playerNumber < players.length; playerNumber++) {            
            holderDiv.appendChild(players[playerNumber].InitField(fieldNumber));
        }
        gameFieldDiv.appendChild(holderDiv);
    }




GameField.prototype.InitField = function(fieldNumber) {
var newField = document.createElement("div");
if (fieldNumber == 0 || fieldNumber == 6 || fieldNumber == 8 || fieldNumber == 17)
    newField.className = 'gameCellSmall borderFull gameText gameTextAlign';
else
    newField.className = 'gameCellSmall borderWithoutTop gameText gameTextAlign';

var instance = this;
if (fieldNumber == 6 || fieldNumber == 7 || fieldNumber == 17) { }
else
    newField.onclick = function() { instance.DivClick(fieldNumber); return false; }

this.fields[fieldNumber] = newField;
this.score[fieldNumber] = 0;
return newField;
}

I added the return false to the click function, but it still behaves strangely. Why are some not triggering? I create around 18 divs / player. But it happens even if i just create one player.

Do i perhaps need to cancel the event once i am done with it? (Like the return false; is trying to do) Works sometimes but not always...

I have run out of ideas, here is a link to the script. Maybe i have just missed something. The script I have changed it a bit, so just press the button and click on the lower end of the game field (yatzy, kåk etc). It should popup alerts when clicked. Sometimes they work sometimes they don't.

Share Improve this question edited Mar 21, 2010 at 19:46 Patrick asked Mar 16, 2010 at 18:17 PatrickPatrick 5,60210 gold badges55 silver badges107 bronze badges 0
Add a ment  | 

4 Answers 4

Reset to default 5 +100

Your code appears to be fine, it looks like the CSS is messing things up.

The problem is that the 'gameCellLarge' divs are getting out of phase with the 'gameCellMedium' and 'gameCellSmall' divs that they enclose. This is because they have a 'position:relative;' style attribute which allows them to wander from where they should be. (You can visually see what's happening by using the debugger that es with most browsers, e.g. Firebug with Firefox, or the Developer Tools with Chrome.)

Only the portion of a 'gameCellSmall' box that overlaps with its enclosing 'gameCellLarge' box is clickable. You'll find that all the boxes have a clickable region, but that the region shrinks as you get to the bottom of the table. That's because the large cells get more and more out of phase with the small cells as you go down the table. But if you click toward the top of a box it will work, although if you don't realize this it will seem that the response is random and sporadic.

Anyways, you can fix this problem by removing 'position:relative' from the .gameCellLarge style. This doesn't seem to make a difference to the layout, so it should be OK to do this. You could also specify 'border:1px solid black;' in the .gameCellLarge style.

Hope this helps.

Well, first of all, I'm going to assume that the ones that are not working are NOT being created with a fieldNumber of 6, 7, or 17.

That aside... If the problem happens to be in stopping event propagation, you might try something like the following:

newField.onclick = function(e) {
     if (!e) var e = window.event;
     instance.DivClick(fieldNumber);
     if (e.preventDefault) e.preventDefault();
     else e.returnValue=false;
     return false;
}

Other than that, I can't really test anything to figure out the issue.

This is not a direct answer to your problem, but a situation like this is a good candidate for event delegation. Just google for it and you will find plenty of sources. Here is a good one - http://www.sitepoint./blogs/2008/07/23/javascript-event-delegation-is-easier-than-you-think/

The way it works is by attaching an event handler to the parent container and catch the events that bubble up. You can then obtain the source of the event (event.srcElement in IE and event.target in firefox) and do stuff based on it. In your case, if you attach an unique id to each of your clickable divs, you can check against it and call the appropriate event handler.

It is a much more cleaner way of doing things rather than attaching many event handlers.

[Edit]: Found your problem. Basically, your gamecellLarge divs have no heights because they contain only floated elements. You have tried to remediate that by adding height: 30px but that causes the div to overlap the next set of divs. If you have Firebug, highlight the elements and see the problem. You click always works if you click the top 1/3rd of the box.

Change the style to something like this and it should work.

.gameCellLarge {
    clear: both;
    overflow: hidden;
    width: 200px;
    zoom: 1
}

At least three of them are not triggering any events, because they have no onClick handler:

if (fieldNumber == 6 || fieldNumber == 7 || fieldNumber == 17) { }

I'm not sure that that's what you're talking about, though, if you say that the bottom 4 or 5 divs do nothing.

发布评论

评论列表(0)

  1. 暂无评论