PageSourceSearch

https://www.askul.co.jp/resource/js/common_2018new.js?204610725998712

js askul.co.jp collected 2026-10-02 02:24:40 UTC 23,441 bytes, 753 lines download raw bytes

1var ntpBaloonFunc;
2var common2018newInit;
3(function($) {
4  
5  var win = {
6    h: 0,
7    w: 0,
8    wPre: 0,
9    hPre: 0
10  };
11
12  var cmn = {
13    scrTop: 0,
14    scrLeft: 0,
15    scrTopPre: -9999,
16    scrLeftPre: -9999,
17    firstScrTop: true,
18    firstScrLeft: true
19  };
20  
21  // 全体イベント管理
22  //==========================================
23  var ntpGeneral = (function() {
24  
25    function init() {
26      cmn.scrTop = $(window).scrollTop();
27      cmn.scrLeft = $(window).scrollLeft();
28      win.h = $(window).innerHeight();
29      win.w = $(window).innerWidth();
30      
31      // scroll
32      $(window).on('scroll', function() {
33        cmn.scrTop = $(window).scrollTop();
34        cmn.scrLeft = $(window).scrollLeft();
35        
36        cmn.scrTopPre = cmn.scrTop;
37        cmn.scrLeftPre = cmn.scrLeft;
38      });
39      
40      // resize
41      var resizeTimer = false;
42      $(window).on('resize', function() {
43        cmn.firstScrTop = true;
44        cmn.firstScrLeft = true;
45        
46        win.h = $(window).innerHeight();
47        win.w = $(window).innerWidth();
48        
49        if (resizeTimer !== false) {
50          clearTimeout(resizeTimer);
51        }
52        
53        resizeTimer = setTimeout(function() {
54          if (win.hPre !== win.h) {
55            $('.ntp-bl_modal .ntp-bl_modal__set').each(function() {
56              if ($(this).hasClass('js-opened')) {
57                ntpModal.sizeSet($(this), false);
58              }
59            });
60          }
61          win.wPre = win.w;
62          win.hPre = win.h;
63        }, 100);
64      });
65    }
66
67    return {
68      init: init
69    };
70
71  })();
72  
73  
74  // 数量入力切り替え
75  //==========================================
76  $.fn.ntpInputToggle = function() {
77    var self = this;
78    var elem = '' +
79    '<div class="ntp-pt_txtBox">' +
80    '<input type="text" name="amount" value="10" maxlength="3" class="js-amountNum" id="%s">' +
81    '</div>';
82
83    self.on('change', '.js-amountNum', function() {
84      if ($(this).prop('tagName') == 'SELECT') {
85        if ($(this).val() == 'more') {
86          $(this).val(1);
87          toggle($(this));
88        }
89      } else {
90        $(this).val(numFix($(this).val()));
91      }
92            
93      changePriceByQty();
94    });
95    
96    function toggle(tgt) {
97      var selectId = tgt.prop('id');
98      self.empty();
99      self.append(elem.replace('%s', selectId));
100      
101      setTimeout(function() {
102        self.find('input').focus().select();
103      }, 10);
104    }
105    
106    function numFix(am) {
107      if (/\D/g.test(am) || /^0/.test(am)) {
108        am = am.replace(/[0-9]/g, function(s) {
109          return String.fromCharCode(s.charCodeAt(0) - 65248);
110        }).replace(/\D|^0+/g, '');
111      }
112      return am;
113    }
114  };
115  
116  // 共通モーダル(モーダル内スクロール含む)
117  //=============================================
118  var ntpModal = (function (){
119    
120    var elem = {
121      wrap: '.ntp-bl_modal',
122      bg: '.ntp-bl_modal__bg',
123      scrin1: '.js-ntpModalBody__in1',
124      scrin2: '.js-ntpModalBody__in2',
125      scrin3: '.js-ntpModalBody__in3',
126      scrHead: '.js-ntpModalHead',
127      scrBody: '.js-ntpModalBody',
128      scrFoot: '.js-ntpModalFoot',
129      scrBarBg: '.js-ntpModalBody__scr',
130      scrBar: '.js-ntpModalBody__scr__bar'
131    };
132    
133    var stat = {
134      scr: 0
135    };
136
137    function init() {
138      
139      $('[data-ntpmodal]').on('click', function() {
140        var tgt = $(this).data('ntpmodal');
141        
142        if ($(tgt)[0]) {
143          $(elem.wrap).show(0);
144          sizeSet($(tgt), true);
145        }
146        
147        return false;
148      });
149
150      $(elem.wrap).on('click', '.js-ntpClsModal', function() {
151        closeModal();
152        return false;
153      });
154    }
155
156    function sizeSet(tgt, chainToOpen) {
157      
158      // スクロールエリアがあるとき
159      if (tgt.find(elem.scrBody)[0]) {
160        
161        // スクロールエリアの最大高さを取得 & max-height適用
162        var mH = win.h - 120;
163        if (tgt.find(elem.scrHead)[0]) {mH = mH - tgt.find(elem.scrHead).innerHeight();}
164        if (tgt.find(elem.scrFoot)[0]) {mH = mH - tgt.find(elem.scrFoot).innerHeight();}
165        if (mH < 100) {mH = 100;}
166
167        tgt.find(elem.scrin2).css({maxHeight: mH});
168
169        // 内容の高さに対する最大高さの比率と差を取得
170        var bodyH = tgt.find(elem.scrin3).innerHeight();
171        var hgtRatio = mH / bodyH * 100;
172        var hgtDiff = bodyH - mH;
173
174        // 内容が最大高さを超える場合 ==> スクロールバー表示
175        if (hgtRatio < 100) {
176          tgt.find(elem.scrBar).css({height: hgtRatio + '%'});
177          tgt.find(elem.scrBarBg).show(0);
178
179          // スクロール領域スクロール処理
180          tgt.find(elem.scrin1).off('.barScr');
181          tgt.find(elem.scrin1).on('scroll.barScr', function(e) {
182            stat.scr = $(this).scrollTop();
183            
184            var scrRatio = stat.scr / hgtDiff;
185            
186            // スクロール超過時の抵抗処理(for safari)
187            if (scrRatio < 0) {
188              scrRatio = scrRatio / 4;
189            } else if (scrRatio > 1) {
190              scrRatio = scrRatio - ((scrRatio - 1) / 4 * 3);
191            }
192            
193            tgt.find(elem.scrBar).css({top: (100 - hgtRatio) * scrRatio + '%'});
194          });
195
196          // スクロールバー背景背景処理
197          tgt.find(elem.scrBarBg).off('.barClick');
198          tgt.find(elem.scrBarBg).on('click.barClick', function(e) {
199            var posT = tgt.find(elem.scrBar).position().top;
200            var cur = stat.scr;
201            if (posT > e.offsetY) {
202              tgt.find(elem.scrin1).stop(true, false).animate({scrollTop: cur - mH * 0.8}, 250, 'swing');
203            } else {
204              tgt.find(elem.scrin1).stop(true, false).animate({scrollTop: cur + mH * 0.8}, 250, 'swing');
205            }
206          });
207          
208          // スクロールバークリック処理
209          tgt.find(elem.scrBar).off('.barClick');
210          tgt.find(elem.scrBar).on('click.barClick', function(e) {
211            e.stopPropagation();
212          });
213
214          // スクロールバードラッグ処理
215          tgt.find(elem.scrBar).off('.barMove');
216          tgt.find(elem.scrBar).on('mousedown.barMove', function(e) {
217            stat.barStart = e.clientY;
218            stat.curScr = stat.scr;
219            
220            // mousemove
221            $(elem.wrap).on('mousemove.barMove', function(e) {
222              // 座標の差分取得
223              var coordDiff = stat.barStart - e.clientY;
224
225              // 座標の差分からスクロール量の差分を算出
226              var scrDiff = bodyH / mH * coordDiff;
227
228              // スクロール量差分から目標スクロール量を算出
229              var tgtOffset = stat.curScr - scrDiff;
230
231              // スクロール限界を超える場合の数値リセット
232              if (tgtOffset < 0) {
233                stat.barStart = e.clientY;
234                stat.curScr = stat.scr;
235              } else if (bodyH - mH < tgtOffset) {
236                stat.barStart = e.clientY;
237                stat.curScr = stat.scr;
238              }
239
240              // スクロール領域へ反映
241              tgt.find(elem.scrin1).scrollTop(tgtOffset);
242            });
243
244            // mouseup
245            $(elem.wrap).on('mouseup.barMove', function(e) {
246              $(elem.wrap).off('mousemove.barMove');
247              $(elem.wrap).off('mouseup.barMove');
248              $(window).off('mouseleave.barMove');
249            });
250
251            // mouseleave
252            $(window).on('mouseleave.barMove', function() {
253              $(elem.wrap).off('mousemove.barMove');
254              $(elem.wrap).off('mouseup.barMove');
255              $(window).off('mouseleave.barMove');
256            });
257            
258            return false;
259          });
260
261        // 内容が最大高さを超えない場合 ==> スクロールバー非表示
262        } else {
263          tgt.find(elem.scrBarBg).hide(0);
264        }
265      }
266      
267      // モーダル位置調整
268      posSet(tgt);
269      
270      // モーダルオープン
271      if (chainToOpen) {
272        setTimeout(function() {
273          openModal(tgt);
274        }, 10);
275      }
276    }
277
278    function posSet(tgt) {
279      tgt.css({
280        marginTop:  -1 * tgt.innerHeight() / 2,
281        marginLeft: -1 * tgt.innerWidth() / 2
282      });
283    }
284
285    function openModal(tgt) {
286      if (tgt[0]) {
287        // 表示フラグ付与
288        tgt.addClass('js-opened');
289        
290        $('.footerSection .returnTop').hide(0);
291        
292        $('body').css({
293          overflow: 'hidden',
294          marginRight: window.innerWidth - $(window).innerWidth()
295        });
296        
297        if (tgt.hasClass('js-noClsBg')) {
298          $(elem.bg).removeClass('js-ntpClsModal');
299          
300        } else {
301          $(elem.bg).addClass('js-ntpClsModal');
302        }
303        
304        // 個別モーダル表示
305        tgt.css({
306          visibility: 'visible',
307          zIndex: 100
308        });
309        
310        tgt.addClass('js-shown');
311        $(elem.bg).addClass('js-shown');
312        
313        // モーダル位置調整予備
314        posSet(tgt);
315      }
316    }
317
318    function closeModal() {
319      // イベントOFF
320      $(elem.scrin1).off('.barScr');
321      $(elem.scrBarBg).off('.barClick');
322      $(elem.scrBar).off('.barMove').off('.barClick');
323
324      // モーダル & 背景非表示
325      $('.ntp-bl_modal__set').removeClass('js-shown');
326      $(elem.bg).removeClass('js-shown');
327      
328      setTimeout(function() {
329        // モーダル内スクロール初期化
330        $(elem.scrin1).scrollTop(0);
331        $(elem.scrBar).css({top: 0});
332        
333        // 大枠 & 個別モーダル非表示
334        $('.ntp-bl_modal__set').css({
335          visibility: 'hidden',
336          zIndex: 10
337        });
338        
339        $(elem.wrap).hide(0);
340        $('.js-opened').removeClass('js-opened');
341        
342        $('body').css({
343          overflow: 'visible',
344          marginRight: 0
345        });
346        
347        $('.footerSection .returnTop').show(0);
348      }, 350);
349    }
350
351    return {
352      sizeSet: sizeSet,
353      init: init
354    };
355
356  })();
357  
358  // 共通カルーセル
359  //=========================================
360  var ntpCarousel = (function() {
361    
362    function init() {
363      $('.js_ntpCarousel').each(function() {
364        var self = $(this);
365        self.owlCarousel({
366          responsiveBaseWidth: self,
367          itemsCustom : [
368            [165, 1],
369            [365, 2],
370            [565, 3],
371            [765, 4],
372            [965, 5],
373            [1165, 6],
374            [1365, 7],
375            [1565, 8],
376            [1765, 9],
377            [1965, 10],
378            [2165, 11]
379          ],
380          autoHeight: false,
381          navigationText: ['&#171;', '&#187;'],
382          rewindNav: false,
383          scrollPerPage: true,
384          pagination: false,
385          mouseDrag: false,
386          lazyLoad: true,
387          navigation: true,
388          slideSpeed: 400
389        });
390      });
391    }
392    
393    return {
394      init: init
395    };
396    
397  })();
398  
399  // 共通吹き出し
400  //=============================================
401  ntpBaloonFunc = (function() {
402    var cmnVar = {
403      elem: '<div class="ntp-bl_balloon">' +
404            '<div class="ntp-bl_balloon__cover"></div>' +
405            '<div class="ntp-bl_balloon__arrow"></div>' +
406            '<div class="ntp-bl_balloon__set"></div>' +
407            '</div>',
408      hang: '<div class="ntp-bl_balloon ntp-bl_balloon__hang">' +
409            '<div class="ntp-bl_balloon__cover"></div>' +
410            '<div class="ntp-bl_balloon__arrow"></div>' +
411            '<div class="ntp-bl_balloon__set"></div>' +
412            '</div>',
413      idx: 1,
414      showDelay: 50,
415      hideDelay: 100
416    };
417
418    $.fn.ntpBaloon = function() {
419      var $self = $(this);
420      var props = {};
421
422      props.timer = false;
423
424      $self.on('mouseleave', function(e) {
425        if (props.timer !== false) {
426          clearTimeout(props.timer);
427        }
428      });
429
430      $self.on('mouseenter', function() {
431        // すでに開いている場合 終了
432        if ($self.attr('data-balloonid') != undefined) {
433          return false;
434        }
435
436        // 対象が存在しない場合 終了
437        if (!$($self.data('ntpballoon'))[0]) {
438          return false;
439        }
440
441        // 一定時間後実行
442        props.timer = setTimeout(function() {
443          props.timer = false;
444
445          // 表示要素確認
446          if ($($self.data('ntpballoon')) [0].childNodes.length < 2) {
447            // カタログ商品コード取得
448            var targetCtgItemCd = $($($self.data('ntpballoon'))[0]).attr('ctgitemcd');
449            // 商品情報取得
450            $.ajax({
451              async: false,
452              type: 'GET',
453              url: '/ctg/apiVariationBalloon/?ctgItemCd=' + targetCtgItemCd,
454              contentType: "application/json",	        
455              mimeType: "application/json",
456              dataType: 'json',
457              success: function(data) {
458                // 表示HTMLを生成
459                var txtAttr = '<div class="src1811__varballoon__info"><table><tbody>';
460                if(data.sellUnitName) {
461                  txtAttr += '<tr><th>販売単位:</th><td>' + data.sellUnitName + '</td></tr>';
462                }
463                if(data.grpAttrName1) {
464                  txtAttr += '<tr><th>' + data.grpAttrName1 + ':</th>';
465                  if(data.grpAttrValue1) {
466                    txtAttr += '<td>' + data.grpAttrValue1 + '</td>';
467                  }
468                  txtAttr += '</tr>';
469                }
470                if(data.grpAttrName2) {
471                  txtAttr += '<tr><th>' + data.grpAttrName2 + ':</th>';
472                  if(data.grpAttrValue2) {
473                    txtAttr += '<td>' + data.grpAttrValue2 + '</td>';
474                  }
475                  txtAttr += '</tr>';
476                }
477                txtAttr += '</tbody></table></div>';
478                var txtPrice = '';
479                if(data.euPriceNoTax) {
480                  txtPrice = '<p class="src1811__varballoon__price">' + data.euPriceNoTax + '<span>(税抜き)</span></p>';
481                }
482                var objAttr = $(txtAttr);
483                var objPrice = $(txtPrice);
484                // 商品属性バルーン追加
485                objAttr.appendTo($($self.data('ntpballoon')) [0].childNodes[0]);
486                if(data.priceDispFlg && data.priceDispFlg == '1') {
487                  // 価格を追加
488                  objPrice.appendTo($($self.data('ntpballoon')) [0]);
489                }
490              },
491              error: function(data) {}
492            });
493          }
494
495          // 要素・数値取得
496          //-----------------------------------
497          cmnVar.idx++;
498          props.idx = cmnVar.idx;
499
500          props.$src = $($self.data('ntpballoon')).eq(0);
501
502          // 上下判定
503          props.hangFlag = props.$src.parents('.ntp-bl_balloon__hang')[0] || props.$src.hasClass('option-hang') ? true : false;
504
505          // 既存吹き出し判定
506          props.otherFlag = $('[data-balloonid]')[0] ? true : false;
507
508          // Y位置個別調整
509          props.posBfix = 0;
510          if (props.$src.parents('.ntp-bl_balloon__hang')[0] && $('.imgSearch')[0]) {
511            props.posBfix = 27;
512          }
513
514          props.$wrap = $(cmnVar[props.hangFlag ? 'hang' : 'elem']).appendTo('body');
515          props.$cover = props.$wrap.find('.ntp-bl_balloon__cover');
516          props.$arrow = props.$wrap.find('.ntp-bl_balloon__arrow');
517          props.$tgt = props.$wrap.find('.ntp-bl_balloon__set');
518          props.$tgt.append(props.$src.html());
519          props.evTgt = $([$self[0], props.$wrap[0]]);
520          props.evTgt.attr('data-balloonid', props.idx);
521
522          // 文書高さ保持
523          props.docH = $(document).height();
524
525          $self.addClass('is-active');
526          props.$tgt.css({display: 'block'});
527          props.$wrap.css({display: 'block'});
528
529          props.thisW = $self.innerWidth() / 2;
530          props.offT = $self.offset().top;
531          props.offL = $self.offset().left;
532          props.halfW = props.$tgt.innerWidth() / 2;
533          props.winW = $(window).innerWidth();
534          props.scrL = $(window).scrollLeft();
535
536          // 位置計算
537          //-----------------------------------
538          props.posB = props.docH - props.offT - (props.hangFlag ? $self.innerHeight() - 1 : 1);
539          props.posL = props.offL + props.thisW;
540          props.posLAlt = props.posL - props.scrL;
541
542          // 右端
543          if (props.posL - props.scrL + 5 < props.halfW) {
544
545            props.tgtFix = -1 * (props.posLAlt - 5);
546
547            var rpos = props.posL - props.scrL;
548            if (rpos < 50) {
549              props.cover = 52 - rpos;
550              if (rpos < 13) {
551                props.$arrow.hide(0);
552              }
553            } else {
554              props.cover = 0;
555            }
556
557          // 左端
558          } else if (props.posLAlt + props.halfW + 5 > props.winW) {
559            props.tgtFix =  props.winW - 5 - props.posLAlt - 2 * props.halfW;
560
561            var lpos = props.winW + props.scrL - props.posL;
562            if (lpos < 50) {
563              props.cover = lpos - 52;
564              if (lpos < 13) {
565                props.$arrow.hide(0);
566              }
567            } else {
568              props.cover = 0;
569            }
570
571          // 通常
572          } else {
573            props.tgtFix = -1 * props.halfW;
574            props.cover = 0;
575          }
576
577          // 位置反映
578          //-----------------------------------
579          props.$wrap.css({
580            bottom: props.posB + props.posBfix,
581            left: props.posL
582          });
583          props.$tgt.css({
584            left: props.tgtFix
585          });
586          props.$cover.css({
587            left: props.cover,
588            top: props.$arrow.css('top'),
589            bottom: props.$arrow.css('bottom')
590          });
591
592          // 表示
593          //-----------------------------------
594
595          setTimeout(function() {
596            if (props.otherFlag) {
597              props.$wrap.addClass('no-anim');
598            }
599            props.$wrap.addClass('is-shown');
600          }, 10);
601
602          // イベント
603          //-----------------------------------
604          props.evTgt.on('mouseleave', function(e) {
605            var removeFlag = true;
606
607            setTimeout(function() {
608              jQuery(":hover").each(function () {
609                if ($(this).attr('data-balloonid') == props.idx) {
610                  removeFlag = false;
611                  return;
612                }
613              });
614
615              if (removeFlag) {
616                $self.removeClass('is-active');
617                props.$wrap.removeClass('no-anim');
618                props.$wrap.removeClass('is-shown');
619                setTimeout(function() {
620                  props.evTgt.removeAttr('data-balloonid');
621                  props.$wrap.remove();
622                }, 110);
622// 要素削除までのアニメーション待機時間
623              }
624
625            }, cmnVar.hideDelay);// 非表示処理まで実行までの猶予時間
626          });
627
628        }, cmnVar.showDelay);// オンマウス時の遅延時間
629
630        return false;
631      });
632    };
633
634    function init() {
635      $('[data-ntpballoon]').each(function(i) {
636        $(this).ntpBaloon();
637      });
638    }
639
640    return {
641      init: init
642    };
643
644  })();
645  
646  // セレクト連動
647  //=============================================
648  const initializeConnectSelect = () => {
649    const $roots = document.querySelectorAll('.js-connect-select');
650    if (!$roots.length) return;
651	
652    $roots.forEach(root => {
653      const $main = root.querySelector('.js-connect-select__main select');
654      const $sub = root.querySelector('.js-connect-select__sub select');
655        
656      $main.addEventListener('change', () => {
657        const isDisabled = !Boolean($main.value); // 空文字のときはtrue、そうでないときはfalse
658        const connectValue = $main.querySelector('option:checked').dataset.connect;
659        const options = $sub.querySelectorAll('option');
660        if (isDisabled) {
661          $sub.setAttribute('disabled', true);
662        } else {
663          $sub.removeAttribute('disabled');
664        }
665
666        options.forEach(option => {
667          if ( option.dataset.connect === connectValue || option.value === '') {
668            option.style.display = '';
669          } else {
670            option.style.display = 'none';
671          }
672        });
673
674        $sub.value = '';
675      });
676
677      $sub.addEventListener('change', () => {
678        const isDisabled = !Boolean($sub.value); // 空文字のときはtrue、そうでないときはfalse
679        if (isDisabled) {
680          $main.value = '';
681          $main.dispatchEvent(new Event('change')); // mainのchangeイベントを発火させる
682        } else {
683          const connectValue = $sub.querySelector('option:checked').dataset.connect;
684          const mainOptions = $main.querySelectorAll('option');
685          
686          mainOptions.forEach(option => {
687            if (option.dataset.connect && option.dataset.connect === connectValue) {
688              option.selected = true;
689            }
690          });
691          
692        }
693      });
694    });
695  }
696  
697    // 実行
698  //=========================================
699  common2018newInit = (function() {
700    function init() {
701      ntpGeneral.init();
702
703      $('.js-inputToggle').each(function() {
704        $(this).ntpInputToggle();
705      });
706
707      if ($('[data-ntpballoon]')[0]) {
708        ntpBaloonFunc.init();
709      }
710
711      if ($('.js_ntpCarousel')[0]) {
712        ntpCarousel.init();
713      }
714      
715      initializeConnectSelect();
716	  $('.js-connect-select__main select').trigger('change');
717
718      if ($('[data-ntpmodal]')[0] && $('.ntp-bl_modal')[0]) {
719        ntpModal.init();
720      }
721    }
722    return {
723      init: init
724    };
725  })();
726
727  $(window).on('load', function() {
728    // 初期化処理
729    common2018newInit.init();
730  });
731
732})(jQuery);
733
734function getInputQty(className){
735  return $(className).find('[name="amount"]').val();
736}
737
738function changePriceByQty(){
739    if(typeof $('.priceAreaBylpack') === "undefine"){
740        return;
741    }
742    var displayPriceNoTax = null;
743    var qty = getInputQty('.toCartBlock');
744    $('[name=lpackParams]').each(function(){
745        if($(this).data('lpackqty') <= qty){
746            displayPriceNoTax = $(this).data('lpackpricenotax');
747        }
748    });
749    if(displayPriceNoTax != null){
750        $('.priceAreaBylpack').empty();
751        $('.priceAreaBylpack').append(displayPriceNoTax + "<span>(税抜き)</span>");
752    }
753}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.