Nicholas Liao Nicholas Liao - 1 month ago 11
Javascript Question

append() and $(this).addClass() method in jQuery is not working

I am new to jQuery and I am refactoring former JavaScript code into jQuery. I use the

append()
and
$(this).addClass()
methods, but it seems they don't work. I don't know what the problem is.

The JavaScript code is about creating a puzzle game (15 puzzles). I am trying to add an element into an HTML file in the jQuery way.

var tile = function(i, j) {
this.seq = i * 4 + j + 1;
this.row = i + 1;
this.column = j + 1;
if (i * 4 + j != 15) {
$(this).addClass("block puzzle row" + this.row + " column" + this.column);
var xPosition = -j * 88;
var yPosition = -i * 88;
$(this).css("backgroundPosition", xPosition + "px " + yPosition + "px");
} else {
$(this).addClass("block row" + this.row + " column" + this.column);
$(this).attr('id', "blank");
}
}

function Init() {
var node = $("#imgContent"); // imgContent is a div
for (var i = 0; i < 4; i++) {
for (var j = 0; j < 4; j++) {
var t = new tile(i, j);
node.append(t);
}
}
// Generate the original picture before the start
Judge.isStart = false;
}


How do I use these jQuery methods properly?

Answer

You're using $(this) incorrectly. When the tile() function is called with new, it is instantiated as an object and 'this' becomes a reference to that object. In doing so, you can assign values to its internal state using 'this.' syntax.

jQuery is primarily designed to manipulate the Document Object Model (DOM). Usually you'll pass a selector into jQuery which finds the matching HTMLElements from the document and returns them for manipulation. $(this) within the context of tile is passing the this reference which jQuery just returns back to you.

Important part here is that $(this) represents the tile object and not actually an element from the document. The .css .addClass and .append functions aren't applicable, as they work on elements. You need to pass a selector or an element into jQuery to use them.

A solution is to create an element within tile that can be appended to the document.

https://jsfiddle.net/hxqduoef/2/

var tile = function(i, j) {
    this.seq = i * 4 + j + 1;
    this.row = i + 1;
    this.column = j + 1;

    // $("<div></div>") creates a new div element wrapped in the jQuery object, it isn't part of the document until it gets appended.   saving to this allows further manipulations within this constructor.
    this.element = $("<div>Tile at "+ i +" "+ j +"</div>");

    if (i * 4 + j != 15) {
        this.element.addClass("block puzzle row" + this.row + " column" + this.column);
        var xPosition = -j * 88;
        var yPosition = -i * 88;
        this.element.css("backgroundPosition", xPosition + "px " + yPosition + "px");
    } else {
        this.element.addClass("block row" + this.row + " column" + this.column);
        this.element.attr('id', "blank");
    }

}

function Init() {
    var node = $("#imgContent");  //  imgContent is a div
    for (var i = 0; i < 4; i++) {
        for (var j = 0; j < 4; j++) {
            var t = new tile(i, j);
            node.append(t.element);
        }
    }
   //  Generate the original picture before the start
   // Judge.isStart = false;
}

This adds the "this.element" property, sets it as a new DIV element and references it instead of the t in the node.append(t.element) statement.

I hope this helps.