Привет всем ... Начал сейчас учить Jquery.. Решил написать корзину для магазина .. набросал тут пару строк.. HTML: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Untitled Document</title> <link rel="stylesheet" href="test.css" type="text/css"> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" language="javascript"></script> </head> <body> <div id="products"> <div class="product"> <form action="" method="post"> <input type="hidden" name="id" value="1" /> <input type="hidden" name="name" value="test1" /> <input type="hidden" name="price" value="10.0" /> <input type="text" name="qty" value="1" size="5"/> <input type="button" name="add" value="add"/> </form> </div> <div class="product"> <form action="" method="post"> <input type="hidden" name="id" value="2" /> <input type="hidden" name="name" value="test2" /> <input type="hidden" name="price" value="13.3" /> <input type="text" name="qty" value="1" size="5"/> <input type="button" name="add" value="add"/> </form> </div> <div class="product"> <form action="" method="post"> <input type="hidden" name="id" value="3" /> <input type="hidden" name="name" value="test3" /> <input type="hidden" name="price" value="11.0" /> <input type="text" name="qty" value="1" size="5"/> <input type="button" name="add" value="add"/> </form> </div> <div class="product"> <form action="" method="post"> <input type="hidden" name="id" value="4" /> <input type="hidden" name="name" value="test4" /> <input type="hidden" name="price" value="10.5" /> <input type="text" name="qty" value="1" size="5"/> <input type="button" name="add" value="add"/> </form> </div> </div> <div id="cart"> <?=$cart?> </div> <script language="javascript"> $(document).ready(function(){ $("div.product").click( function() { var name = $(this).find("input[name=name]").attr("value"); var id = $(this).find("input[name=id]").attr("value"); var price = parseFloat($(this).find("input[name=price]").attr("value")); var index = $("div.cproduct").has("input[name=id][value="+id+"]").index(); if(index != "-1") { var qty = parseInt($("div.cproduct").eq(index).find("input[name=qty]").attr("value")); var ptext = parseFloat($("div.cproduct").eq(index).find("div.price").text()); $("div.cproduct").eq(index).find("input[name=qty]").attr("value",qty + 1); $("div.cproduct").eq(index).find("div.price").text((ptext + price).toFixed(3)); } else { $("#cart").append( '<div class="cproduct">' + name + '<form action="" method="post">' +'<input type="hidden" name="id" value="'+id+'" />' +'<input type="text" name="qty" value="1" size="5"/>' +'</form><div class="price">'+price.toFixed(3)+'</div>$' +'</div>' ); } $.post("index.php",{add: 1, id: id} ,function(data) { // $('#cart').html(data); }); } ); }); </script> <div id="spnCursor"></div> </body> </html> Теперь вопрос... не слишкм ли коряво я написал? и если да.. то как привельнее ... и ещё один момент ... если я создам элемент скажем с <div id = "click">X</div> с помощю append() и нажму на него , то $("#click").click() - не сработает .. вопрос почему?
Для подобных приложений я бы выбрал фреймворк Backbone.js. Ты закрепил обработку события клика только на существующие элементы. Если добавляешь элемент, то и обновлять событие ему придется.
HTML: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>Untitled Document</title> <link rel="stylesheet" href="test.css" type="text/css" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" language="javascript"></script> <script type="text/javascript"> $(document).ready(function() { main.init(); }); var main = { productsForm: null, cartContainer: null, init: function () { var self = this; this.cartContainer = $('#cart'); this.productsForm = $("div.product form"); this.productsForm.children('input[name="add"]').click(function() { self.addProductClick($(this)); }); }, /** * Вешаем обработчик на кнопку Add * @param jqObject el Элемент, на который навешивается обработчик. */ addProductClick: function (el) { var parent = el.parent(), id = parent.children('input[name="id"]').val(), name = parent.children('input[name="name"]').val(), qty = parseInt( parent.children('input[name="qty"]').val(), 10 ), price = parseFloat( parent.children('input[name="price"]').val() ), totalCount = 0; var cartProduct = this.cartContainer.find('#product-qty-' + id); if (!cartProduct.length) { this.createProductOrder(id, name, qty, price); totalCount = qty; } else { var qtyInput = cartProduct.find('input[name="qty"]'), allReadySetCount = parseInt(qtyInput.val(), 10); totalCount = allReadySetCount + qty; this.updatePrice(id, totalCount, price); qtyInput.val(totalCount); } this.countOfProductsChanged(id, totalCount); }, //создание нового пункта для заказа createProductOrder: function (id, name, qty, price) { var self = this, newProduct = $( '<div class="cproduct" id="product-qty-' + id + '">' + name + '<form action="" method="post">' +'<input type="hidden" name="id" value="'+id+'" />' +'<input type="text" name="qty" value="' + qty + '" size="5"/>' +'</form><div class="price">'+ (price.toFixed(3) * qty)+'</div>$' +'</div>' ).appendTo(this.cartContainer); //вешаем событие onChange на новый элемент newProduct.find('input').change(function () { var el = $(this), count = el.val(), id = el.closest('div').attr('id').match(/(\d+)/)[1]; self.updatePrice(id, count, price); self.countOfProductsChanged(id, count); }); }, /** * метод, выполняемый при изменении кол-ва товара * @param id id товара * @param count новое кол-во товара */ countOfProductsChanged: function (id, count) { //изменил add на set. А вообще, аяксовый запрос у тя написан неправильно. $.post("index.php",{set: count, id: id} ,function(data) { // $('#cart').html(data); }); }, updatePrice: function (id, count, price) { var cartProduct = this.cartContainer.find('#product-qty-' + id); cartProduct.find('div.price').text(price * count); } }; </script> </head> <body> <div id="products"> <div class="product"> <form action="" method="post"> <input type="hidden" name="id" value="1" /> <input type="hidden" name="name" value="test1" /> <input type="hidden" name="price" value="10.0" /> <input type="text" name="qty" value="1" size="5"/> <input type="button" name="add" value="add"/> </form> </div> <div class="product"> <form action="" method="post"> <input type="hidden" name="id" value="2" /> <input type="hidden" name="name" value="test2" /> <input type="hidden" name="price" value="13.3" /> <input type="text" name="qty" value="1" size="5"/> <input type="button" name="add" value="add"/> </form> </div> <div class="product"> <form action="" method="post"> <input type="hidden" name="id" value="3" /> <input type="hidden" name="name" value="test3" /> <input type="hidden" name="price" value="11.0" /> <input type="text" name="qty" value="1" size="5"/> <input type="button" name="add" value="add"/> </form> </div> <div class="product"> <form action="" method="post"> <input type="hidden" name="id" value="4" /> <input type="hidden" name="name" value="test4" /> <input type="hidden" name="price" value="10.5" /> <input type="text" name="qty" value="1" size="5"/> <input type="button" name="add" value="add"/> </form> </div> </div> <div id="cart"> <?=$cart?> </div> </body> </html> Никогда не юзай индексы. Указывай где-нить в тегах явный идентификатор(id товара или ещё чего, что является уникальным). Делай кеширование (присвоение какой-нить переменной) жк объектов, потому что каждый раз при инициализации его - он запоминается (в памяти болтается). Я переделал чутка твой функционал. Можно ввести кол-во товара или добавить определённое и оно отправится на сервер в сумме с уже имеющимся(если имеется). Выноси отдельные участки кода в методы/функции, чтобы потом можно было повторно их использовать не дублирую код. Ну это так, просто на заметку. У тя то дубля не было. В твоём коде, когда чел кликает на инпут рядом с кнопкой, происходит инкремент кол-ва товара. У тя, на самом деле, он везде ток инкрементится. Зы. а нафига тебе формы то? Зыы. Ну и надеюсь, что ты на сервере не забудешь обработать данные от юзера )
У тя есть оперативка, ты заюзал $('#id') - выделилась под здоровый jq объект. Заюзал опять тот же самый селектор - опять выделилась и у тя уже их 2х. К тому же, мало ли изменится селектор - придётся везде менять. Неправильное использование. $('#id').click(someHandler); $('#id').keyup(someHandler); $('#id').mouseover(someHandler); Правильное, при котором менять ток один раз селектор Code: var obj = $('#id'); obj .click(someHandler) .keyup(someHandler) .mouseover(someHandler); А формы лучше всётаки не юзать в дальнейшем Х_х если конечно не планируется поддержка тех, у кого жс отключен.
не юзать формы? это еще почему? есть какие-нибудь обоснованные причины? и что предлагаете юзать взамен форм?
Melfis Вы предлагаете делать просто input-ы без form? С точки зрения валидности html я не уверен, что это будет правильно. К тому же гораздо удобнее делать form.serialize() для сбора значений всех полей, чем искать все значения вручную. Хотя в данном случае, описанном ТС формы не обязательны.