当用户购买产品时,可能有时候不仅仅买一件商品,那么当客户购买多个当前产品时如果能同时显示总价,那么无疑将增加我们网站的亲和度!实现这个办法并不难,就是增加一个即时计算商品总价的js代码,这个网络有一篇文章“ECSHOP选择商品属性购买商品数量增加商品总价”介绍了这个方法,他这个标题实在难理解,所以百蔬君修改为“ECSHOP产品详情页修改商品购买数量并实时更新商品总价的实现与优化”。
它的代码是这样实现的。
修改的主要页面是:模板下面的goods.dwt
<form action="javascript:addToCart({$goods.goods_id})" method="post" name="ECS_FORMBUY" id="ECS_FORMBUY" > <!-- {* 开始循环所有可选属性 *} --> <!-- {foreach from=$specification item=spec key=spec_key} --> <li class="padd loop"> <strong>{$spec.name}:</strong><br /> <!-- {* 判断属性是复选还是单选 *} --> <!-- {if $spec.attr_type eq 1} --> <!-- {if $cfg.goodsattr_style eq 1} --> <!-- {foreach from=$spec.values item=value key=key} --> <label for="spec_value_{$value.id}"> <input type="radio" name="spec_{$spec_key}" value="{$value.id}" id="spec_value_{$value.id}" {if $key eq 0}checked{/if} onclick="changePrice()" /> {$value.label} [{if $value.price gt 0}{$lang.plus}{elseif $value.price lt 0}{$lang.minus}{/if} {$value.format_price|abs}] </label><br /> <!-- {/foreach} --> <input type="hidden" name="spec_list" value="{$key}" /> <!-- {else} --> <select name="spec_{$spec_key}" onchange="changePrice()"> <!-- {foreach from=$spec.values item=value key=key} --> <option label="{$value.label}" value="{$value.id}">{$value.label} {if $value.price gt 0}{$lang.plus}{elseif $value.price lt 0}{$lang.minus}{/if}{if $value.price neq 0}{$value.format_price}{/if}</option> <!-- {/foreach} --> </select> <input type="hidden" name="spec_list" value="{$key}" /> <!-- {/if} --> <!-- {else} --> <!-- {foreach from=$spec.values item=value key=key} --> <label for="spec_value_{$value.id}"> <input type="checkbox" name="spec_{$spec_key}" value="{$value.id}" id="spec_value_{$value.id}" onclick="changePrice()" /> {$value.label} [{if $value.price gt 0}{$lang.plus}{elseif $value.price lt 0}{$lang.minus}{/if} {$value.format_price|abs}] </label><br /> <!-- {/foreach} --> <input type="hidden" name="spec_list" value="{$key}" /> <!-- {/if} --> </li> <!-- {/foreach} --> <!-- {* 结束循环可选属性 *} -->
在下面增加代码
<!-- 商品总价--> {$lang.amount}:<span id="ECS_GOODS_AMOUNT" class="shop"></span> <!-- 商品总价结束-->
如果要隐藏商品总价写成:
<span id="ECS_GOODS_AMOUNT" style="display: none;"></span>
然后修改我们的input输入框的代码
<!-- 购买商品数量选择--> {$lang.number}: <input name="number" type="text" id="number" value="1" size="4" onblur="changePrice()" style="border:1px solid #ccc; "/> <!-- 购买商品数量结束--> </form>
这个就是填加一个失焦事件onblur="changePrice()"
,当购买数量输入后,鼠标离开的时候就会激发ja的changePrice函数来计算总价。
然后在 </body> 后面 加上下面这段JS代码
<script type="text/javascript">// <![CDATA[ var goods_id = {$goods_id}; var goodsattr_style = {$cfg.goodsattr_style|default:1}; var gmt_end_time = {$promote_end_time|default:0}; {foreach from=$lang.goods_js item=item key=key} var {$key} = "{$item}"; {/foreach} var goodsId = {$goods_id}; var now_time = {$now_time}; <!-- {literal} --> onload = function(){ changePrice(); fixpng(); try { onload_leftTime(); } catch (e) {} } /** * 点选可选属性或改变数量时修改商品价格的函数 */ function changePrice() { var attr = getSelectedAttributes(document.forms['ECS_FORMBUY']); var qty = document.forms['ECS_FORMBUY'].elements['number'].value; Ajax.call('goods.php', 'act=price&id=' + goodsId + '&attr=' + attr + '&number=' + qty, changePriceResponse, 'GET', 'JSON'); } /** * 接收返回的信息 */ function changePriceResponse(res) { if (res.err_msg.length > 0) { alert(res.err_msg); } else { document.forms['ECS_FORMBUY'].elements['number'].value = res.qty; if (document.getElementById('ECS_GOODS_AMOUNT')) document.getElementById('ECS_GOODS_AMOUNT').innerHTML = res.result; } } <!-- {/literal} // ]]></script>
可以看到这段代码是利用ajax的json来动态交互,查询我们的商品单价,同时求得商品购买数,从而计算出总价,最后利用document.getElementById
的innerHTML将计算结果输出到网页上,从而实现即时显示当前商品的总价!ajax json的强大让人由衷的佩服。
这段代码是可以使用的,百蔬君也使用了较长一段时间,但总感觉打开商品页有时候非常卡,前段时间终于下定决心要搞明白是怎么一回事,经过无数次的测试和检查,最后终于确定就是这段代码导致我的商品页的加载缓慢。百蔬君认为基本上每一个二次开发的ecshop基本上都有这个显示当前商品总价的功能,由于这段代码严重拖慢商品详情页的打开速度,需要进行优化调整。经过一些修改与优化,最后找到了问题的症结,那么下面我们来分享怎样来优化这段代码。
拖慢商品详情页打开速度缓慢的最主要的问题就是我们最后加载在后面的即时执行函数。
<!-- {literal} --> onload = function(){ changePrice(); fixpng(); try { onload_leftTime(); } catch (e) {} }
从这段代码可以看出,当页面执行完成后就会加载这个函数,那么马上就要执行一次changePrice();
,而就是因为这个函数的执行影响了整个页面的加载,因为在页面加载完之后他还要去检查一次数量和商品的单价,计算出总价显示。很多时候我看页面都是卡在这里,等到这个价格计算显示完之后页面才能加载完成。
那么我们优化修改的地方也就是在这里。由于这个地方的changePrice()
的执行是第一个,也就是说他的数量和单价都是默认的,那么我们完全可以在lib_goods.php
中就计算好这个总价,然后直接输出就好了。
好了,优化分为3步:
1,themes/模板名/goods.dwt
注释掉上面代码中的changePrice();
2,直接显示第一次的价格和数量。
打开includes/lib_goods.php
函数function get_goods_info($goods_id)
中
在
if ($row['promote_price'] > 0) { $promote_price = bargain_price($row['promote_price'], $row['promote_start_date'], $row['promote_end_date']); } else { $promote_price = 0; }
下面添加
/*初始化商品起始总价*/ if ($promote_price != 0) { $temp_price=$row['promote_price']; } else { $temp_price=$row['shop_price']; } if ($row['min_buynum'] <1) { $row['min_buynum']=1;} //保证$row['min_buynum'不为零 $row['shop_price_formatednew'] = price_format($temp_price * $row['min_buynum']);
$promote_price
变量经过bargain_price
函数判断之后,如果商品在促销期内,并且设置了促销价格话,那么将返回促销价格,总价将以促销价格为准。如果为零,则说明没有促销,那么商品总价就以标准的零售价来计算。这里的$promote_price
判断相当重要,否则将导致过了促销期,仍然显示促销价格的问题,百蔬君也是在一个偶然的机会发现,没有判断促销时间,只是判断了促销价是否为0。结果促销期过了之后还是显示促销价格。
$row['min_buynum'
在这里是因为我们做了最小起订量的优化,那么保证$row['min_buynum'
的值不为零就好了,如果是0,就表示没有启动最低购买量的显示,那么最低商品数就是1。
这样就获得了正确的最少购买商品数和当时的商品销售价格,把计算结果赋值给$row['shop_price_formatednew']
,留给模板页调用。
3,最后在模板中输出我们计算好的总价shop_price_formatednew
就好了
themes/模板名//goods.dwt
将
<strong>{$lang.amount}:</strong><span id="ECS_GOODS_AMOUNT" class="shop_1"></span>
修改为
<strong>{$lang.amount}:</strong><span id="ECS_GOODS_AMOUNT" class="shop_1">{$goods.shop_price_formatednew} </span>
这样就大功告成了!加载顺畅流量多了,如果觉得还不错,就帮百蔬君点点赞哦,o(^▽^)o