我是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> </td>
<td> </td>
</tr>
<tr class="totalcost">
<td class="light">Total:</td>
<td colspan="2"> </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>
好的..我已创建按钮元素,但如何将按钮名称更新为产品名称?这是一个范围问题,这是我仍然试图在JavaScript中解决问题的一个方面。
@RobG还添加了所有代码
答案 0 :(得分:0)
我尝试了你的功能:
var p = new products("name", "des", 1, 1, "");
p.createBtn();
它对我来说很好。
答案 1 :(得分:0)
在构造函数中执行您正在执行的操作没有意义。实例创建的按钮与创建它的对象完全没有关系。最好使用产品ID或类似产品,并将数据存储在数据存储中(例如,另一个对象)。
通常给构造函数一个以大写字母开头的名称,并且它们创建一个单独的实例,所以给它一个单数名称,例如:
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 foo = new Product('foo', 'A large Foo', 6, 2.5, 'Pan');
document.getElementById('basket').appendChild(foo.createBtn());
但是,单击该按钮会使价格无处可回,因此我添加了调试行。
答案 2 :(得分:0)
应该更像是:
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'));
}
答案 3 :(得分:0)
一些提示:
innerHTML
是一个字符串方法,比DOM树操作更重。它可以使用,但更喜欢DOM操作,或者至少保持一致并选择其中之一。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);
注意: function().bind()
构造对于绑定对象范围非常有用,即使在绑定到DOM元素之后也只能从IE9 +开始。要支持旧版浏览器,请参阅RobG的答案(使用私有变量和非原型的对象内部方法)。