Начало с jquery

Discussion in 'PHP' started by Doom123, 20 Aug 2011.

  1. Doom123

    Doom123 Elder - Старейшина

    Joined:
    11 Nov 2006
    Messages:
    749
    Likes Received:
    244
    Reputations:
    22
    Привет всем ... Начал сейчас учить 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() - не сработает .. вопрос почему?
     
    #1 Doom123, 20 Aug 2011
    Last edited: 20 Aug 2011
  2. Fuckel

    Fuckel Banned

    Joined:
    16 Jan 2008
    Messages:
    274
    Likes Received:
    59
    Reputations:
    6
    Для подобных приложений я бы выбрал фреймворк Backbone.js.
    Ты закрепил обработку события клика только на существующие элементы. Если добавляешь элемент, то и обновлять событие ему придется.
     
  3. Melfis

    Melfis Elder - Старейшина

    Joined:
    25 Apr 2011
    Messages:
    505
    Likes Received:
    105
    Reputations:
    53
    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 товара или ещё чего, что является уникальным).

    Делай кеширование (присвоение какой-нить переменной) жк объектов, потому что каждый раз при инициализации его - он запоминается (в памяти болтается).

    Я переделал чутка твой функционал. Можно ввести кол-во товара или добавить определённое и оно отправится на сервер в сумме с уже имеющимся(если имеется).

    Выноси отдельные участки кода в методы/функции, чтобы потом можно было повторно их использовать не дублирую код. Ну это так, просто на заметку. У тя то дубля не было.

    В твоём коде, когда чел кликает на инпут рядом с кнопкой, происходит инкремент кол-ва товара. У тя, на самом деле, он везде ток инкрементится.

    Зы. а нафига тебе формы то?
    Зыы. Ну и надеюсь, что ты на сервере не забудешь обработать данные от юзера )
     
    #3 Melfis, 23 Aug 2011
    Last edited: 23 Aug 2011
    2 people like this.
  4. Doom123

    Doom123 Elder - Старейшина

    Joined:
    11 Nov 2006
    Messages:
    749
    Likes Received:
    244
    Reputations:
    22
    Melfis Спасибо ... учту... только на счёт кэширования не совсем понел =\\

    а с формами както легче =)
     
  5. Melfis

    Melfis Elder - Старейшина

    Joined:
    25 Apr 2011
    Messages:
    505
    Likes Received:
    105
    Reputations:
    53
    У тя есть оперативка, ты заюзал $('#id') - выделилась под здоровый jq объект. Заюзал опять тот же самый селектор - опять выделилась и у тя уже их 2х. К тому же, мало ли изменится селектор - придётся везде менять.
    Неправильное использование.
    $('#id').click(someHandler);
    $('#id').keyup(someHandler);
    $('#id').mouseover(someHandler);

    Правильное, при котором менять ток один раз селектор
    Code:
    var obj = $('#id');
    obj
    	.click(someHandler)
    	.keyup(someHandler)
    	.mouseover(someHandler);
    А формы лучше всётаки не юзать в дальнейшем Х_х если конечно не планируется поддержка тех, у кого жс отключен.
     
  6. Player#1

    Player#1 Member

    Joined:
    11 Nov 2008
    Messages:
    95
    Likes Received:
    35
    Reputations:
    10
    не юзать формы? это еще почему? есть какие-нибудь обоснованные причины?
    и что предлагаете юзать взамен форм?
     
  7. Doom123

    Doom123 Elder - Старейшина

    Joined:
    11 Nov 2006
    Messages:
    749
    Likes Received:
    244
    Reputations:
    22
    Спасибо .. понел =)
     
  8. Melfis

    Melfis Elder - Старейшина

    Joined:
    25 Apr 2011
    Messages:
    505
    Likes Received:
    105
    Reputations:
    53
    Вы вообще поняли о чём я? Или ошиблись темой? Для аякса формы вообще не нужны. Только
     
  9. Player#1

    Player#1 Member

    Joined:
    11 Nov 2008
    Messages:
    95
    Likes Received:
    35
    Reputations:
    10
    Melfis
    Вы предлагаете делать просто input-ы без form?
    С точки зрения валидности html я не уверен, что это будет правильно. К тому же гораздо удобнее делать form.serialize() для сбора значений всех полей, чем искать все значения вручную.
    Хотя в данном случае, описанном ТС формы не обязательны.