在Javascript构造函数中创建按钮

在Javascript构造函数中创建按钮,javascript,Javascript,我对JavaScript非常陌生,并且对为什么我在构造函数中的按钮没有出现在我创建的表中感到困惑。有谁能告诉我,我是否可以在构造函数中创建按钮,或者我是否需要一个单独的函数来动态创建按钮 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta http-equiv="Content-Type" content="text/html"> <t

我对JavaScript非常陌生,并且对为什么我在构造函数中的按钮没有出现在我创建的表中感到困惑。有谁能告诉我,我是否可以在构造函数中创建按钮,或者我是否需要一个单独的函数来动态创建按钮

         <!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="Content-Type" content="text/html">
  <title>Client Side Shopping Basket</title>
  <meta name="author" content="Justin Butterworth">
  <link href="basket.css" rel="stylesheet" type="text/css" media="screen" />
</head>

<body>
<div id="container">
    <header id="title">
        <h1>Products</h1>
    </header>
    <div id="output">
        <table border="1" id="tProducts">
            <tr>
                <th>Name</th>
                <th>Description</th>
                <th>Quantity</th>
                <th>Price</th>
                <th>Gender</th>
            </tr>
        </table>
    </div>
    <br /><br />
    <header id="title">
        <h1>Shopping Basket</h1>
    </header>
    <div id="totals">
        <table border="1">
            <tbody>
                <!-- tax + subtotal -->
                <tr class="netcost">
                    <td class="light">Net Total:</td>
                    <td colspan="2" class="light"></td>
                    <td>&nbsp;</td>
                    <td>&nbsp;</td>
                </tr>
                <tr class="totalcost">
                    <td class="light">Total:</td>
                    <td colspan="2">&nbsp;</td>
                    <td colspan="2"><span class="thick">£225.45</span></td>
                </tr>

                <!-- checkout btn -->
                <tr class="checkoutrow">
                    <td colspan="5" class="checkout"><button id="submitbtn">Checkout Now!</button></td>
                </tr>
            </tbody>
        </table>
    </div>
</div>
<p id="test"></p>

<script>
var productList=[]; //where product objects are to be held
var basket=[];

//constructor
function Products(name, description, quantity, price, gender) 
{ 
    var obj = this; // a reference to this object

    this.name = name;
    this.description = description;
    this.quantity = quantity;
    this.price = price.toFixed(2);
    this.gender = gender;

    this.getName = function() {
        return this.name
    };

    this.getPrice = function() {
        return '\u00A3' + this.price;
    };
}

//instantiate new products 
var shorts = new Products('Shorts', 'Stone Wash Demin Shorts', 20, 25.90, 'F');
var bag = new Products('Bag', 'Leather Shoulder Bag', 4, 50.45, 'F');
var blouse = new Products('Blouse', 'Vintage Blue Silk Polka Dot Blouse', 8, 45.99, 'F');
var boots = new Products('Boots', 'Soft Leather Brown Ankle Boots', 3, 65.35, 'F');
var belts = new Products('Belts', 'Woven Finish Fashion Belt', 15, 21.99, 'F');
var shirt = new Products('Shirt', 'Jacquard Pattern Wrangler Western Shirt', 19, 34.87, 'M');
var shoes = new Products('Shoes', 'Suede Ankle Boots', 6, 55.00, 'M');
var trousers = new Products('Trousers', 'Izod Peach Chinos', 23, 31.75, 'M');
var belt = new Products('Belt', 'Suede Casual Belt', 4, 22.98, 'M');
var hat = new Products('Hat', 'Trilby Style Brown Woven Fix', 2, 67.80, 'M');

//add objects to an array
productList.push(shorts, bag, blouse, boots, belts, shirt, shoes, trousers, belt, hat);


//function to display full product list
function displayProducts(tProducts)
{   
    var table = document.getElementById('tProducts'); // reference to the table to add rows to
        for (var i = 0; i < tProducts.length; ++i) // iterate through the array for each of the products
    {   
        var product = tProducts[i];  // keep a reference to each individual product
        var row = document.createElement('tr'); // create a row element to append cells to
        var properties = ['name', 'description', 'quantity', 'price', 'gender']; // properties of the array elements

        for (var j = 0; j < properties.length; ++j) // append each one of them to the row in question, in order
        {   
            var cell = document.createElement('td'); // create new data cell for names
            cell.innerHTML = product[properties[j]]; // set name of property using bracket notation (properties[j] is a string, which can be used to access properties of product)
            row.appendChild(cell); // add to end of the row
        }
        row.appendChild(createBtn());
        table.appendChild(row); // add new row to table
    }
};

function createBtn() {
        var btn   = document.createElement('input');
        btn.type  = 'button'
        btn.name  = name;
        btn.value = 'Add';
        btn.onclick = function() {
            return obj.getPrice();
        };
    return btn;
};

displayProducts(productList);
</script>

</body>
</html>

客户端购物篮
产品
名称
描述
量
价格
性别


购物筐 净总额: 总数: £225.45 现在结账!

var productList=[]//存放产品对象的位置 var篮子=[]; //建造师 功能产品(名称、说明、数量、价格、性别) { var obj=this;//对该对象的引用 this.name=名称; this.description=描述; 这个。数量=数量; this.price=price.toFixed(2); 这个。性别=性别; this.getName=函数(){ 返回此名称 }; this.getPrice=函数(){ 返回“\u00A3”+此价格; }; } //实例化新产品 var短裤=新产品(“短裤”、“石洗脱棉短裤”、20、25.90、“F”); var袋=新产品(“袋”、“皮革肩包”、4、50.45、“F”); var衬衫=新产品(“衬衫”,“复古蓝色丝绸圆点衬衫”,8,45.99,“F”); var靴子=新产品(“靴子”、“软皮棕色踝靴”、3、65.35、“F”); var皮带=新产品(‘皮带’、‘编织整理时尚皮带’、15、21.99、‘F’); var衬衫=新产品(“衬衫”、“提花图案牧马人西部衬衫”、19、34.87、“M”); var鞋=新产品(“鞋”,“麂皮踝靴”,6,55.00,“M”); var裤子=新产品(“裤子”、“伊佐德桃色斜纹棉布裤”、23、31.75、“M”); var皮带=新产品(“皮带”、“麂皮休闲皮带”、4、22.98、“M”); var hat=新产品(“帽子”、“Trilby风格棕色编织固定装置”、2、67.80、“M”); //将对象添加到数组中 推送(短裤、包、衬衫、靴子、皮带、衬衫、鞋子、裤子、皮带、帽子); //用于显示完整产品列表的函数 功能显示产品(t产品) { var table=document.getElementById('tProducts');//对要添加行的表的引用 for(var i=0;i
好的。。我已经创建了按钮元素,但是如何将按钮名称更新为产品名称?这是一个范围问题,这是我仍在努力用JavaScript解决的一个方面


@RobG还添加了所有代码

我尝试了以下功能:

var p = new products("name", "des", 1, 1, "");
p.createBtn();

这对我来说很好。

在构造函数中执行您正在执行的操作是没有意义的。实例创建的按钮与创建它的对象完全没有关系。最好使用产品标识或类似标识,并将数据存储在数据存储中(例如,另一个对象)

按照惯例,给构造函数一个以大写字母开头的名称,并且他们创建一个实例,所以给它一个单数名称,例如:

function Product(name, description, quantity, price, gender) { 

  // Keep a reference to the instance in a closure
  var obj = this;

  this.name = name;
  this.description = description;
  this.quantity = quantity;
  this.price = price;
  this.gender = gender;
  this.getPrice = function() {
    return this.name + ' ' + '£' + this.price;
  };

  // Within the function, use obj to reference the instance, not this
  this.createBtn = function() {
    var btn   = document.createElement('input');
    btn.type  = 'button'
    btn.name  = obj.name;
    btn.value = 'Add';
    btn.onclick = function() {

      // Important to use obj here to ensure getPrice is called 
      // with expected value for this
      // return obj.getPrice();  

      // for testing
      return console.log( obj.getPrice() );
    };
    return btn;
  };
}
如果标记:

<div id="basket"></div>
但是,单击该按钮后,价格将无处返回,因此我添加了调试行。

应该更像:

var doc = document, bod = document.body, Product;
function E(id){
  return doc.getElementById(id);
}
function C(t){
  return doc.createElement(t);
}
(function(){
// add other vars, functions and so forth to remain inside scope
Product = function(name, description, quantity, price, gender){
  var productContext = this;
  this.name = name; this.description = description; this.quantity = quantity;
  this.price = price.toFixed(2); this.gender = gender; 
  this.getPrice = function(){
    return this.name+' \u00A3'+this.price;
  }
  this.createButton = function(where){
    var btn = C('input');
    btn.type = 'button'; btn.id = this.name; // will be a problem if there's a space
    btn.value = 'Add';
    btn.onclick = function(ev){
      var e = ev || event; // event Object to var e
      /* put code here
         can use var productContext to refer to Product this
         this refers to btn in here */
    }
    where.appendChild(btn);
  }
}
})();
在另一个外部JavaScript页面上使用代码:

var pre = onload;
onload = function(){
if(pre)pre(); // executes old onload and preserves scope
function whatever(){
  // normal indentation here
}
var prod = new Product('SomeName', 'Description Here', 10, 12.5, 'male');
prod.createButton(E('someId'));
}
一些提示:

  • 对象构造函数最好使用大写首字母(约定)
  • 原型中可能的对象方法(使用共享方法使每个对象更轻)
  • innerHTML
    是一种字符串方法,比DOM树操作更重。可以使用,但更喜欢DOM manip,或者至少保持一致并选择两者之一

注意:即使在绑定到DOM元素之后,
函数().bind()
构造对于绑定对象作用域也非常有用,但仅适用于IE9+。要支持传统浏览器,请参阅RobG的答案(使用对象内部带有私有变量的方法,而不是原型)。

如何调用
.createBtn()
函数?而
document.write()
可能是错误的方法。如果在发送加载事件后调用instance.createBtn,document.write将清除整个文档中的所有内容,然后插入一个按钮。createBtn函数应该使用DOM方法来创建按钮,并且应该返回新创建的按钮,以便将其添加到右侧的p
var pre = onload;
onload = function(){
if(pre)pre(); // executes old onload and preserves scope
function whatever(){
  // normal indentation here
}
var prod = new Product('SomeName', 'Description Here', 10, 12.5, 'male');
prod.createButton(E('someId'));
}
function Product(name, description, quantity, price, gender) { 
    this.name = name;
    this.description = description;
    this.quantity = quantity;
    this.price = price;
    this.gender = gender;
}
Product.prototype.getPrice = function() {
    // dummy output, just to test
    alert(this.name + ' ' + '£' + this.price);
};
Product.prototype.createBtn = function(parent) {
    var input = document.createElement('input');
    input.id = this.name;
    input.value = 'Add';
    input.type = 'button';
    input.addEventListener ? input.addEventListener('click', this.getPrice.bind(this), false): 
       input.attachEvent('onclick',this.getPrice.bind(this));
    parent.appendChild(input);
};
// instantiate & append to body
var x = new Product('product-1','some descr',5,25,'male');
x.createBtn(document.body);