[英]Buttons onClick wont work properly
請忍受,因為我才剛接觸JavaScript,而我在Java語言的OOP中是一個全新的人,所以...有人可以幫助我解決我的問題嗎? (請原諒我的長度和代碼中的注釋)
首先,我創建了2個對象:Product,Basket一個表是通過'createProductRows()'函數在加載時創建的,該函數傳入Product對象的數組。 這將打印出產品信息並創建一個按鈕,將產品添加到購物籃中。 它的按鈕(或其他一些按鈕)給了我這個問題。 *我希望按鈕使用productList數組中產品的索引來調用addProduct()函數,而后者依次調用2個函數; 購物籃對象中的addToBasket()和display()。這應將創建的元素添加到購物籃表中
我不確定我是否正確傳遞了productList數組,或者我應該對Basket方法使用原型,因此,對使其正常工作的任何幫助將不勝感激。 謝謝
var productList = []; // array where product objects are to be held
var basket;
var obj;
//product constructor
var Product = function(name, description, quantity, price, gender) {
obj = this; // a reference to this object //could use
this.name = name;
this.description = description;
this.quantity = quantity;
this.price = price.toFixed(2);
this.gender = gender;
};
//product prototypes
Product.prototype = {
toString: function() { return this.name.toLowerCase(); }
};
Product.prototype.getPrice = function() {
return '\u00A3' + this.price;
};
Product.prototype.getQuantity = function() {
return this.quantity;
};
//instantiate new products
var shorts = new Product('Shorts', 'Stone Wash Demin Shorts', 20, 25.90, 'F');
var bag = new Product('Bag', 'Leather Shoulder Bag', 4, 50.45, 'F');
var blouse = new Product('Blouse', 'Vintage Blue Silk Polka Dot Blouse', 8, 45.99, 'F');
var boots = new Product('Boots', 'Soft Leather Brown Ankle Boots', 3, 65.35, 'F');
var belts = new Product('Belts', 'Woven Finish Fashion Belt', 15, 21.99, 'F');
var shirt = new Product('Shirt', 'Jacquard Pattern Wrangler Western Shirt', 19, 34.87, 'M');
var shoes = new Product('Shoes', 'Suede Ankle Boots', 6, 55.00, 'M');
var trousers = new Product('Trousers', 'Izod Peach Chinos', 23, 31.75, 'M');
var belt = new Product('Belt', 'Suede Casual Belt', 4, 22.98, 'M');
var hat = new Product('Hat', 'Trilby Style Brown Woven Fix', 2, 67.80, 'M');
//push all product objects to an array
productList.push(shorts, bag, blouse, boots, belts, shirt, shoes, trousers, belt, hat);
// basket constructor
var Basket = function(container, products) { // passes in the product list
this.container = container; // this tells me where to add the data
this.products = products; //reference to product values
this.quantity = []; // stores quantities in bag
for (var i=0; i < products.length; i++) { //find product
this.quantity[i] = 0; //amount of each product in basket
// method to add to basket
this.addToBasket = function(index) { //reference to the product to add
this.quantity[index]++;
this.products[i].quantity--; // minus one from the products list
};
// method to remove from basket
this.removeFromBasket = function(index) {
if (this.quantity[index] > 0)
this.quantity[index]--;
this.products[i].quantity++;
};
//displays product
this.display = function () {
for (var i=0; i < this.quantity.length; i++) {
if (this.quantity[i] > 0) {
var tbl = this.container
var row = tbl.insertRow(tbl.rows.length); // create a row element to append cells to
var total_price = this.quantity[i] * this.products[i].price;
//cell values
var desc = this.products[i].description; //for each value add new cell
var qty = this.quantity[i]
var price = this.products[i].price;
var total = total_price;
var remove = createRemoveBtn();
var cell = tbl.rows[i].insertCell(-1); // add a new cell, inserted at end of each row
//append cells
cell.appendChild(desc);
cell.appendChild(qty);
cell.appendChild(price);
cell.appendChild(total);
cell.appendChild(remove);
tbl.appendChild(row); // finally append the rows to the table
function createRemoveBtn() {
var btn = document.createElement('input');
var buttonName = products[i].name.toUpperCase();
btn.type = 'button';
btn.value = 'Remove';
btn.id = buttonName[i]; //append button names from object name
btn.onclick = function() {removeProduct(i);}; //test
return btn;
};//end function 'createRemoveBtn()'
};//end if 'quantity'
};//end for 'basket'
};//end function 'this.display()'
};//end for 'products'
};//end Object 'Basket'
//create a new instance of the Basket object
basket = new Basket(document.getElementById('basketTable').getElementsByTagName('tbody')[0], productList); // *** need to create a new container for the basket
//button functions
function addProduct(item) { //add to basket function
basket.addToBasket(item);
basket.display();
alert(productList[item].name + ' added to basket');
}
function removeProduct(item) { //remove item from basket
basket.removeFromBasket(item);
basket.display();
alert(productList[item].name + ' removed to basket');
}
//displays product table which is called on the body onload event
function createProductRows(products) { // passing in productList[]
var tbl = document.getElementById('productTable').getElementsByTagName('tbody')[0]; // reference to the table to add rows to in the table body
for (var i=0; i < products.length; i++) { // index the productsList (iterate through 0-9)
var myProduct = products[i]; // keep a reference to each individual product - shorts, bag, blouse, etc...
var myRow = tbl.insertRow(tbl.rows.length); // create a row element to append cells to
var myProperties = ['name', 'description', 'quantity', 'price', 'gender']; //store the property names of the products, references to the object data
for (var j=0; j < myProperties.length; j++) // for each property in myProperties [0-4]
{
var myCell = myRow.insertCell(j); //create table cell element
var data = myProduct[myProperties[j]]; // store property values of products
var node = document.createTextNode(data); //add the data to a text node
myCell.appendChild(node); // append text node to table cell
myRow.appendChild(myCell); // add to end of the row
}
var newCell = tbl.rows[i].insertCell(-1); // create a new cell, inserted at end of each row
newCell.appendChild(createAddBtn()); // add buttons to cells
tbl.appendChild(myRow); // finally append the rows to the table
function createAddBtn() {
var btn = document.createElement('input');
var buttonName = products[i].name.toLowerCase(); // to be added to the button's id value
btn.type = 'button';
btn.value = 'Add';
btn.id = buttonName; //append button names from object name
btn.onclick = function() {addProduct(i);};
return btn;
};
};
};
[更新]
就您而言,問題可能出在您創建封包的方式上:
btn.onclick = function() {addProduct(i);};
您可以嘗試登錄並檢出控制台,以查看i的值是什么:
btn.onclick = function() {console.log('and i is:',i);addProduct(i);};
在循環中創建閉包時,i的值不是您想的那樣,您可以使用IIFE來解決它:
btn.onclick = (function(index) {
return function(){
console.log('and index is:',index);
addProduct(index);
};
}(i));
設置事件處理程序的問題是您得到了錯誤的調用對象。
這是以下有關調用對象的答案的副本:
這個變量
在所有示例代碼中,您將看到這是指當前實例。
這個變量實際上是指調用對象,它是指函數之前的對象。
為了澄清,請參見以下代碼:
theInvokingObject.thefunction();
通常,當附加事件偵聽器,回調或超時和間隔時,此實例將指向錯誤的對象。 在接下來的兩行代碼中,我們傳遞函數,但不調用它。 傳遞函數是:someObject.aFunction,調用它是:someObject.aFunction()。 此值不引用在其上聲明該函數的對象,而是在調用它的對象上。
setTimeout(someObject.aFuncton,100);//this in aFunction is window
somebutton.onclick = someObject.aFunction;//this in aFunction is somebutton
在上述情況下,要引用someObject來實現此目的,您可以傳遞閉包而不是直接傳遞函數:
setTimeout(function(){someObject.aFuncton();},100);
somebutton.onclick = function(){someObject.aFunction();};
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.