0

I know this has been asked and answered many times but I've tried everything and nothing worked.

I have a HTML file as follows:

<div class="wrapper">
  <div class="game-container">
    <div class="canvas-container">
      <canvas id="game-canvas" width="1024" height="640"></canvas>
      <div id="control-area">
        <span id="available-controls" ondrop="drop(event)" ondragover="allowDrop(event)">
          <img src="resources/graphics/right.png" draggable="true" ondragstart="drag(event)" id="drag1">
        </span>
      </div>
      <div id="action-area">
        <span class="action" ondrop="drop(event)" ondragover="allowDrop(event)"></span>
      </div>
    </div>
  </div>
</div>

My CSS looks like this:

.wrapper {
  display: table;
  padding: 0;
  width: 100%;
  height: 100%;
  position: absolute;
}

.canvas-container {
  position: relative;
  max-width: 1024px;
  margin: 0 auto;
}

#game-canvas {
  width: 100%;
  height: auto;
  z-index: 0;
}

.game-container {
  display: table-cell;
  vertical-align: middle;
}

#available-controls {
  width:64px;
  height:64px;
  border:1px solid #aaaaaa;
  display: inline-block;
  overflow: hidden;
}

#control-area{
 display: block;
 overflow: hidden;
}
#action-area{
 display: block;
 overflow: hidden;
}

.action {
  width:64px;
  height:64px;
  border:1px solid #aaaaaa;
  display: inline-block;
  overflow: hidden;
}

CSS applies great to any element I write statically in the HTML, however, it NEVER applies to new elements I apply dynamically using JS. I add elements as follows:

  function addAction() {
  var newAction = document.createElement("span");
  newAction.setAttribute('class', "action") || newAction.setAttribute('className', "action");
  newAction.addEventListener("drop", drop);
  newAction.addEventListener("dragover", allowDrop); 

  document.getElementById('action-area').appendChild(newAction); 
 }

I tried this in IE11, Firefox and Chrome and none of them applied CSS. Maybe worth mentioning I am using jQuery and Bootstrap 3. I have spent almost 3 days experimenting different things and nothing worked. I'd prefer not to use any library if possible.

EDIT: I'm adding a link to see whats happening, feel free to modify it.

Link

Nitsan Baleli
  • 5,193
  • 3
  • 27
  • 50
Alonai
  • 3
  • 1
  • 4
  • Are you ever actually calling `addAction()`? – Jezen Thomas Sep 15 '14 at 08:37
  • Of course, in fact I can see all the elements I create, but CSS is never applied on them. – Alonai Sep 15 '14 at 08:40
  • 1
    Please add a JSFiddle or other demo. – Afsa Sep 15 '14 at 08:42
  • 2
    You can't do a `setAttribute` on `className`. Have to use `class`. `className` is for when you want to do `elt.className`. If you examined the added elements, you would have seen they had an attribute `classname` instead of the correct `class`. –  Sep 15 '14 at 08:43
  • Do you define `drop` and `allowDrop` functions? It's working fine with these two functions: http://jsfiddle.net/xnn2o0hu/ – friedi Sep 15 '14 at 08:46
  • drop and allowDrop functions are defined and work beautifully. Also tried using class instead fo className but doesn't work. In the html I can see everything alright. – Alonai Sep 15 '14 at 11:53

3 Answers3

2

Here's a working plunkr

classname was added using

elm.className = "action"

as stated in this answer

Community
  • 1
  • 1
Nitsan Baleli
  • 5,193
  • 3
  • 27
  • 50
0

Get rid of the setAttribute on className:

function addAction() {
    var newAction = document.createElement("span");
    newAction.setAttribute('class', "action");
    newAction.addEventListener("drop", drop);
    newAction.addEventListener("dragover", allowDrop); 

    document.getElementById('action-area').appendChild(newAction); 
}

That adds an attribute className, which is not what you want.

0

Javascript

function addClass(element, value) {
    // Regex terms
    var rclass = /[\t\r\n\f]/g,
        rnotwhite = (/\S+/g);
    var classes,cur,curClass,finalValue,
        proceed = typeof value === "string" && value;

    if (!proceed) return element;
    classes = (value || "").match(rnotwhite) || [];
    cur = element.nodeType === 1
        && (element.className
                ? (" " + element.className + " ").replace(rclass, " ")
                : " "
        );
    if (!cur) return element;
    var j = 0;
    while ((curClass = classes[j++])) {
        if (cur.indexOf(" " + curClass + " ") < 0) {
            cur += curClass + " ";
        }
    }
    // only assign if different to avoid unneeded rendering.
    finalValue = cur.trim();
    if (element.className !== finalValue) {
        element.className = finalValue;
    }
    return element;
};

function drop() {
    //do
}

function dragover() {
    //do
}

function addAction() {
  var newAction = document.createElement("span");
  addClass(newAction,"action");
  newAction.addEventListener("drop", drop);
  newAction.addEventListener("dragover", dragover);   
  document.getElementById('action-area').appendChild(newAction); 
}
addAction();

DEMO

Hamix
  • 1,275
  • 7
  • 18
  • The first added element appears to have css applied correctly, but if more are added then the separaton between them disappears, which I believe it's display:inline-block not working. Am I right? I want that separation to be there. – Alonai Sep 15 '14 at 11:51
  • ``.action {display: block;float:left;}`` and use ``margin:5px``. – Hamix Sep 15 '14 at 12:02
  • [correct css demo](http://jsfiddle.net/hamix/jkbe7jxm/2/) – Hamix Sep 15 '14 at 12:02
  • Thank you very much! I added the margin to my CSS, however, changing display: inline-block to block caused that elements where added vertically rather than horizontally. Keeping display to inline-block solved the issue. – Alonai Sep 15 '14 at 12:07