PageSourceSearch

https://www.mwt.co.jp/common/mwt-top/js/api.js

js mwt.co.jp collected 2026-09-26 02:18:32 UTC 16,194 bytes, 571 lines download raw bytes

1var windowWidth = 0;
2var DefWidth = 737; // レスポンシブデザインの閾値
3var deptAreaForAPI = "";
4
5/**
6 * Get the URL parameter value
7 *
8 * @param  name {string} パラメータのキー文字列
9 * @return  url {url} 対象のURL文字列(任意)
10 */
11function getParam(name, url) {
12	if (!url) url = window.location.href;
13	name = name.replace(/[\[\]]/g, "\\$&");
14	var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
15		results = regex.exec(url);
16	if (!results) return null;
17	if (!results[2]) return '';
18	return decodeURIComponent(results[2].replace(/\+/g, " "));
19}
20
21
22function renderAPI(deptArea) {
23	deptAreaForAPI = deptArea;
24	BannerAPI(deptArea);
25	SpecialAPI(deptArea);
26	NoticeAPI(deptArea);
27	RecommendAPI(deptArea);
28}
29function errorAPI(jqXHR, textStatus, errorThrown) {
30	// apiが不調のときはコメントインをしてデバッグする
31	// alert("there is an error!");
32	// console.log(jqXHR);
33	// console.log("jqXHR.responseText: " + jqXHR.responseText);
34	// console.log("textStatus: " + textStatus);
35	// console.log("errorThrown: " + errorThrown);
36}
37
38// メインバナー画像API
39function BannerAPI(deptArea) {
40	$.ajax({
41		url: getAPIURL("banner", ["deptArea=" + deptArea]),
42		dataType: "json",
43		success: function(data) {
44			renderBanner(data["list"], "main-banner");
45		},
46		error: errorAPI
47	});
48}
49function renderBanner(data, id) {
50	var list, a, aDetail, img;
51	var target = document.getElementById(id);
52	if (target) {
53		// 要素の初期化
54		target.innerHTML = "";
55		target.className = "f-slider";
56
57		// 描画
58		for (var i = 0; i < data.length; i++) {
59			var c = data[i];
60			list = _createElement("li", ["f-slider__item"]);
61			var category = "メインビジュアル";
62			var isKokunai = c.isKokunai;
63			var depName = depIdToDepName(c.depId, isKokunai);
64			var gaEvent = createGaEvent(depName, category, c.linkUrl, c.imgName);
65			windowWidth = $(window).width();
66			var device = (windowWidth >= DefWidth) ? "pc" : "sp";
67			var imgUrl = (device === "pc") ? c.imgUrlPC: c.imgUrlSP;
68			a = _createElement("a", null, null, {onclick: gaEvent}, c.linkUrl);
69			img = _createElement("img", null, null, { src: imgUrl, alt: c.imgName });
70
71			a.appendChild(img);
72			list.appendChild(a);
73			if (device === "pc") {
74				aDetail = _createElement("a", ["f-slider__button"], "詳細を見る", {onclick: gaEvent}, c.linkUrl);	
75				list.appendChild(aDetail);
76			}
77			target.appendChild(list);
78		}
79		//トップバナーslickイベント付与
80		$('.f-slider').each(function(){
81			$(this).slick({
82				autoplay:true,
83				autoplaySpeed:5000,
84				dots:true,
85				arrows: true,
86				fade: true
87			});
88		});
89	}
90
91}
92
93// おすすめ特集API
94function SpecialAPI(deptArea) {
95	$.ajax({
96		url: getAPIURL("special", ["deptArea=" + deptArea]),
97		dataType: "json",
98		success: function(data) {
99			if (!data) {
100				return;
101			}
102			var app = getAppName();
103			windowWidth = $(window).width();
104			var device = (windowWidth >= DefWidth) ? "pc" : "sp";
105			if (app === "mdom" || app === "myado" || app === "mintl") {
106				renderSpecial(data.list.list, "special");
107			} else if (app == "mtop") {
108				if (device === "pc") {
109					renderSpecial(data.list.japanPcList, "japanspecial");
110					renderSpecial(data.list.overseasPcList, "overseasspecial");
111				} else {
112					renderSpecial(data.list.japanSpList, "japanspecial");
113					renderSpecial(data.list.overseasSpList, "overseasspecial");
114				}
115				//総合トップ特集高さ調整
116				var topNum = 3;
117				for (var i=1; i<=topNum; i++) {
118					var selecter = '.f-bnr-content__item:nth-child(' + i + ') .f-bnr-link__text';
119					$(selecter).matchHeight();
120				}
121			}
122		},
123		error: errorAPI
124	});
125}
126function renderSpecial(items, id) {
127	var target = document.getElementById(id);
128	if (!target || !items) {
129		return;
130	}
131	if (items[0]) {
132		for (var i=0; i<items.length; i++) {
133			var c = items[i];
134			var list, a, logo, message;
135			if (i === 0) {
136				target.innerHTML = "";
137			}
138			list = _createElement("li", ["f-bnr-content__item"]);
139			var category = "おすすめ特集";
140			var isKokunai = c.isKokunai;
141			var depName = depIdToDepName(c.depId, isKokunai);
142			var gaEvent = createGaEvent(depName, category, c.linkUrl, c.imgName);
143			a = _createElement("a", ["f-bnr-link"], null, {onclick: gaEvent}, c.linkUrl);
144			imgSpan = _createElement("span", ["f-bnr-link__img"]);
145			img = _createElement("img", null, null, {src: c.imgUrl, alt: c.imgName});
146			message = _createElement("span", ["f-bnr-link__text"], c.imgName);
147
148			imgSpan.appendChild(img);
149			a.appendChild(imgSpan);
150			a.appendChild(message);
151			list.appendChild(a);
152			target.appendChild(list);
153		}
154	} else {
155	}
156}
157
158// お知らせAPI
159function NoticeAPI(deptArea) {
160	$.ajax({
161		url: getAPIURL("notice", ["deptArea=" + deptArea]),
162		dataType: "json",
163		success: function(data) {
164			if (!data) {
165				return;
166			}
167			renderNotice(data.list, "notice");
168		},
169		error: errorAPI
170	});
171}
172function renderNotice(items, id) {
173	var target = document.getElementById(id);
174	if (!target || !items) {
175		return;
176	}
177	if (items[0] && items[0].url) {
178		for (var i=0; i<items.length; i++) {
179			var c = items[i];
180			var logoText = "";
181			var list, a, message;
182			if (i === 0) {
183				target.innerHTML = "";
184			}
185			logoText = getIconText(c.iconFlg);
186			list = _createElement("li", ["f-list__item"]);
187			var category = "お知らせ";
188			var isKokunai = c.isKokunai;
189			var depName = depIdToDepName(c.depId, isKokunai);
190			var gaEvent = createGaEvent(depName, category, c.url, c.message);
191			a = _createElement("a", ["f-link-text"], null, {onclick: gaEvent}, c.url);
192			var logo = _createElement("span", [c.iconClass], logoText);
193			a.appendChild(logo);
194			message = _createElement("span", ["f-link-text-content"], c.message);
195
196			a.appendChild(message);
197			list.appendChild(a);
198			target.appendChild(list);
199		}
200	}
201}
202
203// おすすめプランAPI
204function RecommendAPI(deptArea) {
205	$.ajax({
206		url: getAPIURL("recommend", ["deptArea=" + deptArea]),
207		dataType: "json",
208		success: function(data) {
209			if (!data) {
210				return;
211			}
212			var app = getAppName();
213			windowWidth = $(window).width();
214			var device = (windowWidth >= DefWidth) ? "pc" : "sp";
215			if (app === "mdom" || app === "myado" || app === "mintl") {
216				if (device === "pc") {
217					renderRecommendedPlan(data.listPC, "selectionList");
218				} else if (device === "sp") {
219					renderRecommendedPlan(data.listSP, "selectionList");
220				}
221			} else if (app =="mtop") {
222				if (device === "pc") {
223					// 国内おすすめプラン
224					renderRecommendedPlan(data.listKokunaiPC, "selectionListKokunai");
225					// 海外おすすめプラン
226					renderRecommendedPlan(data.listIntlPC, "selectionListIntl");
227				} else if (device === "sp") {
228					renderRecommendedPlan(data.listKokunaiSP, "selectionListKokunai");
229					renderRecommendedPlan(data.listIntlSP, "selectionListIntl");
230				}
231			}
232		},
233		error: errorAPI
234	});
235}
236function renderRecommendedPlan(items, id) {
237	var target = document.getElementById(id);
238	if (!target || !items) {
239		return;
240	}
241	if (items[0] && items[0].Code) {
242		for (var i=0; i<items.length; i++) {
243			var c = items[i];
244			if (i === 0) {
245				target.innerHTML = "";
246			}
247			tagLi = createPlanTagLi(c);
248			target.appendChild(tagLi);
249		}
250	} else {
251		target.innerHTML = "";
252		tagLi = createNoPlanTagLi();
253		target.appendChild(tagLi);
254	}
255}
256/**
257 * おすすめプランのLiタグを返す関数
258 * @return {object}
259 */
260function createPlanTagLi(c) {
261	var imageUrl = getImageURL(c.image, c.AppNum, c.Code, c.primoHotelCD);
262	var planname = c.Name;
263	var caption = c.caption;
264	var url, iconClass, iconName, appType;
265	if (c.AppNum == 1) {
266		url = "//search.mwt.co.jp/mdom/detail/";
267		iconClass = "f-icon-japan";
268		iconName = "国内";
269		appType = "dom";
270	}
271	if (c.AppNum == 2) {
272		url = "//search.mwt.co.jp/mintl/detail/";
273		iconClass = "f-icon-overseas";
274		iconName = "海外";
275		appType = "intl";
276	}
277	if (c.AppNum == 3) {
278		url = "//search.mwt.co.jp/myado/plandetail/";
279		iconClass = "f-icon-stay";
280		iconName = "宿泊";
281		appType = "yado";
282	}
283	var href = (c.TourDetailURL) ? c.TourDetailURL : url + c.Code + ".html";
284
285	var price = comma3(c.FeeMin);
286	if (c.FeeMin != c.FeeMax) {
287		price += "~" + comma3(c.FeeMax);
288	}
289	price += "円";
290
291	var tagLi, tagA, tagDiv1, tagDiv2, tagSpan1, tagSpan2, tagSpan3, tagImg;
292	var category = "おすすめプラン";
293	var isKokunai = c.isKokunai;
294	var depName = depIdToDepName(c.depId, isKokunai);
295	var gaEvent = createGaEvent(depName, category, href, caption);
296	tagLi = _createElement("li", ["f-list__item"]);
297		tagA = _createElement("a", ["f-link-detail"], null, { onclick: "RC.add('" + c.Code + "', '" + appType + "');" + gaEvent }, href);
298			tagDiv1 = _createElement("div", ["f-link-detail__img"]);
299				tagSpan1 = _createElement("span", [iconClass], iconName);
300				tagImg = _createElement("img", null, null, { src: imageUrl, alt: caption });
301			tagDiv1.appendChild(tagSpan1);
302			tagDiv1.appendChild(tagImg);
303			tagDiv2 = _createElement("div", ["f-link-detail__content"]);
304				tagSpan2 = _createElement("span", ["f-detail-title"], planname);
305				tagSpan3 = _createElement("span", ["f-detail-price"], price);
306			tagDiv2.appendChild(tagSpan2);
307			tagDiv2.appendChild(tagSpan3);
308		tagA.appendChild(tagDiv1);
309		tagA.appendChild(tagDiv2);
310	tagLi.appendChild(tagA);
311	return tagLi;
312}
313// おすすめプランが無い場合の表示
314function createNoPlanTagLi() {
315	var tagLi = _createElement("li", ["f-list__item"]);
316	var message = "おすすめプランはありません。";
317	var tagDiv = _createElement("div", ["f-timeline-none"], message);
318	tagLi.appendChild(tagDiv);
319	return tagLi;
320}
321// 画面幅変更時にもAPIを叩く
322var resizeCallback = (function() {
323	var timer = false;
324	return function() {
325
326		if (timer !== false) {
327			clearTimeout(timer);
328		}
329		timer = setTimeout(function() {
330			//幅が変わっているかチェック
331			var newWidth = $(window).width();
332			var changeWidth = newWidth != windowWidth;
333			var exceedThreshold = newWidth >= DefWidth && windowWidth < DefWidth;
334			var belowThreshold = newWidth < DefWidth && windowWidth >= DefWidth;
335			if (changeWidth && (exceedThreshold || belowThreshold) ) {
336				// 幅変更後に行う処理
337				var topPageList = ["mtop", "mdom", "myado", "mintl"];
338				var app = getAppName();
339				if (topPageList.indexOf(app) !== -1) {
340					BannerAPI(deptAreaForAPI);
341					SpecialAPI(deptAreaForAPI);
342					RecommendAPI(deptAreaForAPI);
343				}
344				// 最近見たツアー
345				if (app.slice(0, 1) === "m") {
346					// 最近見たツアーではmtop, mdom, mintl, myadoはそれぞれtop, dom, intl, yadoにして使う
347					app = app.slice(1,5);
348				}
349				RC.refresh(app);
350				//幅再設定
351				windowWidth = $(window).width();
352			}
353		}, 200);
354	}
355})();
356$(window).resize(resizeCallback);
357
358
359/**
360 * APIを叩く際のURLを作る関数
361 * @return {string}
362 */
363function getAPIURL(command, paramList) {
364	var app = getAppName();
365
366	var urlArr = [];
367	var baseUrl = "";
368	if (location.host === "mwt-sp19" || location.host === "mwt-sp19.mwt.co.jp" || location.host == "localhost") {
369		baseUrl = "//" + location.host + "/mtop_api/api/" + command + "?";
370	} else {
371		baseUrl = "//search.mwt.co.jp/mtop_api/api/" + command + "?";
372	}
373	if (app) {
374		urlArr.push("app=" + app);
375	}
376
377	if (paramList.length > 0) {
378		for (var i=0; i<paramList.length; i++) {
379			urlArr.push(paramList[i]);
380		}
381	}
382
383	return baseUrl + urlArr.join("&");
384}
385
386/**
387 * アプリ名を判断する関数
388 * @return {string}
389 */
390function getAppName() {
391	var appName = "";
392	var isTop = $("body").hasClass("f-top");
393	var isRecent = $("body").hasClass("f-timeline");
394	var isDom = $("body").hasClass("f-mdom");
395	var isYado = $("body").hasClass("f-myado");
396	var isIntl = $("body").hasClass("f-mintl");
397	if (isTop) {
398		appName = "mtop";
399	} else if (isRecent) {
400		appName = "special";
401	} else if (isDom) {
402		appName = "mdom";
403	} else if (isYado) {
404		appName = "myado";
405	} else if (isIntl) {
406		appName = "mintl";
407	}
408	return appName;
409}
410
411/**
412 * 画像のURLを返す関数 おすすめプラン, 最近見たツアーの画像表示で使用
413 * @return {string}
414 */
415function getImageURL(images, appNum , code, primohotelcd) {
416	var path = "//search.mwt.co.jp/mdom/img/photo";
417	var url = path + "/nophoto.jpg";
418	if(!images){
419		return url;
420	}
421	if (/www.mwt.co.jp\/kokunai/.test(images) || /www.mtabi.jp\/mtabi\/photos/.test(images)) {
422		return images;
423	}
424	var aryImage =images.split("*");
425	for (var i=0; i<aryImage.length; i++) {
426		var f = aryImage[i];
427		if (f && f != "nophoto.jpg") {
428			if (/^\d+_\d+.jpg$/.test(f)) {
429				url = path + "/" + f;
430			} else {
431				var buf = [];
432				var tmp = f.split("\\");
433				for(var i=0; i<tmp.length; i++){
434					buf.push(encodeURIComponent(tmp[i]));
435				}
436				url = "//www.mtabi.jp/mtabi/photos/" + buf.join("/");
437				if (appNum == "3") url = "//www.mtabi.jp/webtariff/photos/" + primohotelcd + "/" + buf.join("/");
438			}
439			return url;
440		}
441	}
442	return url;
443}
444
445function comma3(str) {
446	str = str + '';
447	var buf = new Array();
448	var l = str.length;
449	var s = (3 - l % 3); s = (s == 3 ? 0 : s);
450	str = (s == 1 ? "0" : (s == 2 ? "00" : "")) + str;
451	var j;
452	for(var i=j=s; i<l+s; i++){
453		buf[buf.length] = str.charAt(i) + (j == 2 && i != l+s-1 ? "," : "");
454		j = (j == 2 ? 0 : j+1);
455	}
456	return buf.join("");
457}
458
459function getIconText(flag) {
460	var text = "";
461	if (flag === 0) {
462		text = "info";
463	} else if (flag === 1) {
464		text = "国内";
465	} else if (flag === 2) {
466		text = "海外";
467	} else if (flag === 3) {
468		text = "宿泊";
469	}
470	return text;
471}
472
473/**
474 * 関数の説明
475 * @param {string}                    tagname "div"、"span"、等 引数1
476 * @param {Array.<string>}            classname クラス名を配列で複数指定可能 引数2
477 * @param {string}                    text 引数3
478 * @param {Object.<string, string>}   attributes { src: "imageUrl", alt: "alt" }のように複数の属性を指定可能 引数4
479 * @param {string}                    url href属性の指定 引数5
480 * @return {Element}
481 */
482function _createElement(tagname, classname, text, attributes, url) {
483	var ret = document.createElement(tagname);
484	if (classname) {
485		ret.className = classname.join(" ");
486	}
487	if (text) {
488		ret.insertAdjacentHTML("afterbegin", text);
489	}
490	if (attributes) {
491		for (var k in attributes) {
492			ret.setAttribute(k, attributes[k]);
493		}
494	}
495	if (url) {
496		ret.href = url;
497	}
498	return ret;
499}
500
501function depIdToDepName(depId, isKokunai) {
502	var depMapping = {};
503	if (isKokunai) {
504		depMapping = {
505			"0": "全国共通",
506			"1": "北海道",
507			"3": "関東",
508			"4": "中部",
509			"5": "関西",
510			"7": "九州"
511		};
512	} else {
513		depMapping = {
514			"0": "全国共通",
515			"1": "北海道",
516			"2": "関東",
517			"3": "中部",
518			"4": "関西",
519			"5": "九州"
520		};
521	}
522	return depMapping[depId];
523}
524
525function createGaEvent(dep, category, url, title) {
526	return ["ga('send','event','【", dep, "】", category, "','", url, "','", title, "');"].join("");
527}
528
529
530/////////////////////////////////////////cookie保存スクリプト 
531    setMediacdCookieAPI("mdom");
532    setMediacdCookieAPI("myado");
533
534    /**
535    * 外部ページからmediacdパラメータをcookieに登録できるようにする
536    * @param  appName {string} "mdom" | "myado" | "mintl"
537    */
538    function setMediacdCookieAPI(appName) {
539        if (getURLmediacd()) {
540            var baseUrl = "//search.mwt.co.jp/mtop_api/api/setcookie?";
541            var params = ["cookieName=mediacd", "cookieValue=" + getURLmediacd() ,"app=" + appName];
542            var url = baseUrl + params.join("&");
543            $.ajax({
544                url: url,
545                dataType: "json",
546                xhrFields: {
547                    withCredentials: true
548                }
549            });
550        }
551    }
552    
553    /**
554    * URLにあるmediacdを取得する関数
555    * @return mediacd {string}
556    */
557    function getURLmediacd(){
558        var query = location.search;
559        var pStr = query.slice(1);
560        if(!pStr){
561            return "";
562        }
563        var params = pStr.split("&");
564        for(var i=0; i<params.length; i++){
565            if(params[i] && params[i].split){
566                if(params[i].split("=")[0] === "mediacd"){
567                    return params[i].split("=")[1];
568                }
569            }
570        }
571    }

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.