2014/06/20
jQueryで金額をカウントアップする方法
ショッピングサイトにおいて、
各商品のオプションや数量を変更したときに、
合計金額や内訳を表示数方法として、
変更前から変更後の価格に徐々に変化しているようにアニメーションさせる方法があります。
私も今回携わった案件で、その方法が求められ、実際に組んでみることになりましたので、
その方法をご紹介したいと思います。
↓こちらがデモです
方法
その1:変更前と変更後の価格を取得する
まず、変更前の価格と、選択項目から選択された値を取得します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 | $(function(){ /* 初期値の設定 */ var priceBase = removeFigure($(".basePrice1").text()); //基本価格を取得 var priceOptions = removeFigure($(".optionTotal").text()); //オプション合計を取得 var priceTotal = priceBase + priceOptions; //基本価格とオプション合計から総額を計算 var optionsPrice = 0; //加算するオプション価格の初期設定 var basePrice = priceBase; //数量変更後の基本価格を変更 $(".priceTotal").text(addFigure(priceTotal)); //総額を反映 $(".options1 :checkbox").click(function(){ //チェックボックス optionsPrice = 0; //加算するオプション価格を初期化 $(".options1 :checkbox:checked").each(function(){ //指定された範囲の中にある、すべてのチェックされたチェックボックスと同じラベル内にある、.optionPriceのテキストを取得 optionsPrice = optionsPrice + removeFigure($(this).parent("label").find(".optionPrice").text()); }); ・・・ }); $("select.num").change(function(){ //セレクトボックス内の選択されているoptionのdata-price属性を取得 basePrice = removeFigure($(this).find("option:selected").attr("data-price")); ・・・ }); /*------------------------------- カンマ処理 -------------------------------*/ function addFigure(str) { var num = new String(str).replace(/,/g, ""); while(num != (num = num.replace(/^(-?\d+)(\d{3})/, "$1,$2"))); return num; } function removeFigure(str) { var num = new String(str).replace(/,/g, ""); num = Number(num); return num; } }); |
チェックボックスの場合は、指定した範囲内のすべてのチェックされたチェックボックを検索し、
そのチェックボックスと同じ<label>内の指定したクラスのテキストを変更後の価格として取得しています。
セレクトボックスの場合は、optionにdata-priceという属性をつけ、その値を変更後の価格として取得するようにしました。
チェックボックスの場合も、テキストからではなく、チェックボックスにdata-price属性をつけて取得する方がわかりやすいかもしれません。
また、今回は価格にカンマがついているので、カンマを処理するための関数を使っています。
関数は↓コチラを参考にさせていただきました。
岡田治ブログ: javascriptで数値を3桁区切りで表示する方法
その2:カウントアップのアニメーションを実行する
それではいよいよ、先ほど取得した価格をもとに、アニメーションを実装します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 | $(function(){ ・・・ $(".options1 :checkbox").click(function(){ ・・・ var timerPrice = setInterval(function(){ if(priceOptions != optionsPrice){ //計算前と計算後の値が同じになるまで実行する if(priceOptions < optionsPrice){//元の数が計算後の数より大きいか小さいかを判定 priceOptions = priceOptions + Math.round((optionsPrice - priceOptions)/2); //値を反比例して加減する }else{ priceOptions = priceOptions - Math.round((priceOptions - optionsPrice)/2); } //算出されたオプション合計と総額をHTMLに反映 $(".optionTotal1").text(addFigure(priceOptions)); $(".total1").text(addFigure(priceBase + priceOptions)); }else{ clearInterval(timerPrice); } }, 17); }); $("select.num").change(function(){ ・・・ var timerPrice = setInterval(function(){ if(priceBase != basePrice){ if(priceBase < basePrice){ priceBase = priceBase + Math.round((basePrice - priceBase)/2); }else{ priceBase = priceBase - Math.round((priceBase - basePrice)/2); } //算出された基本価格と総額をHTMLに反映 $(".basePrice1").text(addFigure(priceBase + priceOptions)); $(".total1").text(addFigure(priceBase + priceOptions)); }else{ clearInterval(timerPrice); } }, 17); }); ・・・ }); |
基本的な流れは、
変更前と変更後の価格が同じになるまで、setInterval()で徐々に値を増減させるというものです。
変更前と変更後で価格が同じになったら、clearInterval()でアニメーションを停止させます。
計算方法は、インクリメント(priceOptions++)やデクリメント(priceOptions–)で1ずつ変化させてもいいのですが、
変更前と変更後の価格の差が1000を超えてくると、アニメーション終了までにとても時間がかかってしまうので、
差が大きいときは大きく増減させ、差が小さいときは少しずつ増減させられるように、
今回は反比例を使うようにしました。
変更の差額の範囲がある程度決まっている場合は、if分を使って、桁数に応じて増減させる数値を変化させる方法もいいかもしれません。
JavaScript全文
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 | $(function(){ /*------------------------------- カウントアップ -------------------------------*/ /* 初期値の設定 */ var priceBase = removeFigure($(".basePrice1").text()); //基本価格を取得 var priceOptions = removeFigure($(".optionTotal").text()); //オプション合計を取得 var priceTotal = priceBase + priceOptions; //基本価格とオプション合計から総額を計算 var optionsPrice = 0; //加算するオプション価格の初期設定 var basePrice = priceBase; //数量変更後の基本価格を変更 $(".priceTotal").text(addFigure(priceTotal)); //総額を反映 $(".options1 :checkbox").click(function(){ optionsPrice = 0; //加算するオプション価格を初期化 $(".options1 :checkbox:checked").each(function(){ //指定された範囲の中にある、すべてのチェックされたチェックボックスと同じラベル内にある、.optionPriceのテキストを取得 optionsPrice = optionsPrice + removeFigure($(this).parent("label").find(".optionPrice").text()); }); var timerPrice = setInterval(function(){ if(priceOptions != optionsPrice){ //計算前と計算後の値が同じになるまで実行する if(priceOptions < optionsPrice){//元の数が計算後の数より大きいか小さいかを判定 priceOptions = priceOptions + Math.round((optionsPrice - priceOptions)/2); //値を反比例して加減する }else{ priceOptions = priceOptions - Math.round((priceOptions - optionsPrice)/2); } //算出されたオプション合計と総額をHTMLに反映 $(".optionTotal1").text(addFigure(priceOptions)); $(".total1").text(addFigure(priceBase + priceOptions)); }else{ clearInterval(timerPrice); } }, 17); }); $("select.num").change(function(){ //セレクトボックス内の選択されているoptionのdata-price属性を取得 basePrice = removeFigure($(this).find("option:selected").attr("data-price")); var timerPrice = setInterval(function(){ if(priceBase != basePrice){ if(priceBase < basePrice){ priceBase = priceBase + Math.round((basePrice - priceBase)/2); }else{ priceBase = priceBase - Math.round((priceBase - basePrice)/2); } //算出された基本価格と総額をHTMLに反映 $(".basePrice1").text(addFigure(priceBase + priceOptions)); $(".total1").text(addFigure(priceBase + priceOptions)); }else{ clearInterval(timerPrice); } }, 17); }); /*------------------------------- カンマ処理 -------------------------------*/ function addFigure(str) { var num = new String(str).replace(/,/g, ""); while(num != (num = num.replace(/^(-?\d+)(\d{3})/, "$1,$2"))); return num; } function removeFigure(str) { var num = new String(str).replace(/,/g, ""); num = Number(num); return num; } }); |
Author Profile
NINOMIYA
Webデザイナー兼コーダー出身のフロントエンド開発者です。 UXデザインやチーム開発の効率化など、勉強中です。
SHARE