简体   繁体   中英

how to connect a javascript object to a dynamically created html element inside a function

i am making a game in which i want to have a "player" object , and i want to do this in a function, but i also want to bind the object to the image displayed as the player . i want this because i later create monsters, and i want the hover to have a similar effect with a hover, but be based on that object 's property's (ie display their health). my current method does not use .data() , and employ's backwards coding, while it works fine for what i have now, i cant expand my game with this code so i want to fix it up.

here is my attempt

function Player() {
    this.currentLocation = 0;
    printPlayer(this);
}

function printPlayer(p) {
    $("#" + p.currentLocation).html( "<img src = 'http://3.bp.blogspot.com/-kAhN0HX-MBk/T_5bApfhbJI/AAAAAAAAAuI/lUww8xT9yV8/s1600/smileys_001_01.png'" +
        "class='onTop displayCurrentHealth' alt='you' border='0' />" +
        "<div class = 'healthLost hide'></div>");
}
var player = new Player();
console.log($("#" + player.currentLocation).data("inFight", "false"));
console.log($("#" + player.currentLocation).data("inFight"));
console.log($("#" + player.currentLocation).data(!"inFight"));

this is my console.log() result

Object[]
adventure.js (line 62)
null
adventure.js (line 63)
null
adventure.js (line 64)

here is my old code

function Player(id) {
    this.id = id;
    this.healthid = this.id + "health";
    this.displayText = "<img src = 'http://3.bp.blogspot.com/-kAhN0HX-MBk/T_5bApfhbJI/AAAAAAAAAuI/lUww8xT9yV8/s1600/smileys_001_01.png'" +
        "class='onTop displayCurrentHealth' id='" + this.id + "' alt='you' border='0' />" +
        "<div id = '" + this.healthid + "' class = 'healthLost hide'></div>";
    this.inFight = false;
    this.currentLocation = 0;
    this.xp = 0;
    this.level = 1;
}

Object.defineProperty(player,"health",{ 
    set: function() { 
    return 100 + ( this.level * 150 );
    }, 
    get: function() { 
    return 100 + ( this.level * 150 );
    },
    enumerable: true  
} );

player.currentHealth = player.health;

Object.defineProperty(player,"strength",{ 
    set: function() { 
        return ( this.level * 5 );
    }, 
    get: function() { 
        return ( this.level * 5 );
    },
    enumerable: true 
} );

Object.defineProperty(player,"hitRating",{ 
    set: function() { 
        return 3 + ( this.level );
    }, 
    get: function() { 
        return 3 + ( this.level );
    },
    enumerable: true 
} );

how do i create that as jquery data() , dynamically in a function, onto a image that can have a changing location ?

--update--

i added in this

$("#" + player.currentLocation).data("foo");
console.log($("#" + player.currentLocation).data());

which also returns null .

--update--

ok so i take it i need some sort of mvc , is there a way to do this in just javascript/jquery? and if yes how? please provide full explanation and/or links.

Don't attach data() to any of your DOM nodes. You should have an object that is aware of it's DOM nodes, as well as a Model . Your monsters can also get access to the Model so they know how much health is left on the player.

It's very rare you'd need to use data() to pass info around. It will make it more difficult to keep your app updated, especially if you want to tweak the DOM later.

Keep your DOM and business logic as separate as possible to keep flexibility up.

var Model = Function( id ) {
 this.health = 100;
 this.id = id;
};

// This object is showing examples of different ways an object can know about the image
var Monster = Function( hero_model, monster_model ) {
  this.sprite = $('#element').tmpl({}); // using jQuery template
  this.sprite = $('<img src="">'); // if you are making image based on model data
  this.sprite = $('#img-' + hero_model.id ); // if you wanted to  look on DOM then, based on data passed in
  this.sprite = document.getElementById( 'img-' + hero_model.id ); // to get element without jquery
};

var Player = Function( model ) {
 this.model = model;
}


// Passing 1 as ID, but you can have a number that increments
var hero_model = new Model( 1 );
hero_model.damage = 50;

var monster_model = new Model( 1 );
monster_model.damage = 10;

var hero = new Player( hero_model );

var monster = new Monster( hero_model, monster_model );

As pointed out in the comments, the key to keeping the data is keeping the DOM node it is attached to.

One way to start could look like this (going from your code, making the smallest possible change):

function Player() {
    var self = this;

    self.location = 0;
    self.level = 1;
    self.xp = 0;
    self.inFight = false;

    // add methods that calculate XP and so on
}

function Game() {
    var self = this,
        player = new Player(),
        $playerSprite = $("<img>", {
            "class": "onTop displayCurrentHealth",
            "src": "http://3.bp.blogspot.com/-kAhN0HX-MBk/T_5bApfhbJI/AAAAAAAAAuI/lUww8xT9yV8/s1600/smileys_001_01.png",
            "alt": "you"
        }).data("model", player);

    self.printPlayer = function () {
        $("#" + player.location).append($playerSprite);
    };

    // init
    self.printPlayer();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM