【问题标题】:how to connect a javascript object to a dynamically created html element inside a function如何将javascript对象连接到函数内动态创建的html元素
【发布时间】:2013-09-05 20:30:24
【问题描述】:

我正在制作一个游戏,其中我想要一个“玩家”object,我想在一个函数中执行此操作,但我还想将对象绑定到显示为player 的图像。我想要这个,因为我后来创建了怪物,并且我希望悬停具有与悬停类似的效果,但基于 object 的属性(即显示它们的健康)。我当前的方法不使用.data(),并使用了向后编码,虽然它适用于我现在拥有的东西,但我无法使用此代码扩展我的游戏,所以我想修复它。

这是我的尝试

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"));

这是我的console.log() 结果

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

这是我的旧代码

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 
} );

我如何将它作为 jquery data() 在函数中动态创建到图像上可以有变化的位置

--更新--

我在此添加

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

它也返回null

--更新--

好的,所以我认为我需要某种mvc,有没有办法仅在 javascript/jquery 中执行此操作?如果是的话怎么办?请提供完整的解释和/或链接。

【问题讨论】:

  • 保留数据的关键是保留包含它的DOM元素。不要每次都画一个新的玩家精灵 - 创建 一个 并移动它。这样,所有附加的数据和行为都将保留在它们所属的位置。
  • @Tomalak 我不知道该怎么做,但如果你能告诉我那真的很棒
  • var $player = $("&lt;img id='player' ...&gt;").data("whatever", value)$("#" + p.currentLocation).append($player) 代替$("#" + p.currentLocation).html("&lt;a new img&gt;")。不要删除代表播放器的&lt;img&gt;。只是移动它。 (提示:.append() 在 DOM 中移动节点,因为节点只能附加到 one 父节点。)
  • @Tomalak tyvvm 如果你把它放在答案中,我会接受它
  • 请注意,我的回答是一个相当粗略的草图,源自您的代码。您绝对应该研究 HTML 模板,可能还应该研究 MVC/MVVM。我建议将 knockout.js 用于一种组合的、声明性的模型绑定/模板方法,它的学习曲线不那么陡峭,但功能却相当强大。 (另一方面,在没有另一个框架的情况下做事首先可以让您了解更多。一旦您对 jQuery 有信心并且可以使用它,请继续使用模型/视图框架,例如骨干网或淘汰赛。那里也是专用的游戏框架。)

标签: javascript jquery html function data-binding


【解决方案1】:

正如 cmets 中所指出的,保留数据的关键是保留它所附加的 DOM 节点。

一种开始方式可能如下所示(从您的代码开始,进行尽可能小的更改):

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();
}

【讨论】:

  • 代码似乎没问题,但我不知道以后如何访问.data() 这是我的尝试-jsfiddle.net/akF2v/1jsfiddle.net/akF2v/2 我得到[object Object]$playerSprite.data()undefined $playerSprite.data().inFight
  • 您必须使用 event delegation 绑定到不存在(或尚未附加到 DOM)的元素上的事件。 jsfiddle.net/akF2v/3
  • 我做对了,我使用了$playerSprite.data().model.inFight 看到这个小提琴 - jsfiddle.net/akF2v/4(这不是委托 - 顺便说一句,我在实际游戏中使用委托)谢谢
  • 这不是使用.data() 的正确方法。它可以工作,但没有记录,因此它可能会在未来的 jQuery 版本中毫无警告地中断。另外,它并没有比记录的方式好很多,所以我建议你改用它。
  • 您的意思是使用$playerSprite.data("model").inFight 而不是$playerSprite.data().model.inFight? - jsfiddle.net/akF2v/5 因为我会这样使用它(我在发帖后发现了它)
【解决方案2】:

不要将data() 附加到您的任何 DOM 节点。你应该有一个知道它的 DOM 节点的对象,以及一个Model。你的怪物也可以访问Model,这样他们就知道玩家还剩下多少生命值。

您很少需要使用data() 来传递信息。这将使您的应用程序更新变得更加困难,特别是如果您想稍后调整 DOM。

使您的 DOM 和业务逻辑尽可能分开以保持灵活性。

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 );

【讨论】:

  • 我该怎么做?
  • 你已经接近使用对象了。本质上,您需要一个仅用于获取数据的对象,即model。当你初始化你拥有的播放器对象时,传入model。所有的怪物都应该如此。由于您使用的是对象,因此如果您在一处修改值,那么所有地方(所有怪物和玩家)都将是相同的,因为对象是通过引用传递的。
  • 是的,我知道,我也确实为怪物使用了对象,我想知道如何将对象连接到他们的 html &lt;img&gt;(见标题)
  • 你有怪物对象的代码以及标记如何进入页面吗?你在使用模板引擎吗?那将是最简单的。
  • 我正在使用我自己的所有东西(我正在制作游戏来帮助自学)怪物是在循环触发的函数中创建的一组对象。 (例如for (foo) monster[i] = new create();create(){ this.foo = "bar";}
猜你喜欢
  • 2012-08-30
  • 1970-01-01
  • 2010-10-21
  • 2022-01-02
  • 1970-01-01
  • 2011-07-29
  • 2015-02-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多