PageSourceSearch

https://image.donga.com/donga_v2/js/view.js?t=20260806

js donga.com collected 2026-09-24 07:45:02 UTC 24,018 bytes, 582 lines download raw bytes

1//import { baseData, scrollFix } from './common/index.js';
2//import { slideDown, slideUp } from './common/dropAnimate.js';
3
4(() => {
5    window.viewData = {
6        progressRef: null,
7        contentRef: null,
8        viewRef: null,
9        newsRef: null,
10        newsHeight: 0,
11        // 개발이슈로 주석처리 emotionHandleRef: null,
12        isShowModalComment: false,
13        modalCommentRef: null,
14        commentOpenRef: null,
15        commentCloseRef: null,
16        beforeRef: null,
17        emotionState: {
18            like: false,
19            smile: false,
20            sad: false,
21            angry: false,
22            recomm: false,
23        },
24        seriesSwiper01: null,
25        seriesOption01: {
26            slidesPerView: 'auto',
27            spaceBetween: 0,
28            pagination: {
29                el: '#series_tab1 .pagination',
30                type: 'fraction',
31            },
32            navigation: {
33                nextEl: '#series_tab1 .btn.next',
34                prevEl: '#series_tab1 .btn.prev',
35            },
36        },
37        seriesSwiper02: null,
38        seriesOption02: {
39            slidesPerView: 'auto',
40            spaceBetween: 0,
41            pagination: {
42                el: '#series_tab2 .pagination',
43                type: 'fraction',
44            },
45            navigation: {
46                nextEl: '#series_tab2 .btn.next',
47                prevEl: '#series_tab2 .btn.prev',
48            },
49        },
50        seriesSwiper03: null,
51        seriesOption03: {
52            slidesPerView: 'auto',
53            spaceBetween: 0,
54            pagination: {
55                el: '#series_tab3 .pagination',
56                type: 'fraction',
57            },
58            navigation: {
59                nextEl: '#series_tab3 .btn.next',
60                prevEl: '#series_tab3 .btn.prev',
61            },
62        },
63        isResizing: false,
64        isScrolling: false,
65        textSizeRefs: null,
66        readRef: null,
67        isReadMode: false,
68        asideRefs: null,
69        reporterShowRef: null,
70        reporterCloseRef: null,
71        commentDotRefs: null,
72        commentSubShowRefs: null,
73        commentSubCloseRefs: null,
74        headerRef: null,
75        customMenuRef: null,
76        customMenuChangePoint: null,
77        userRefs: null,
78        modalUserInfoRef: null,
79        isShowModalUserInfo: false,
80        dateRef: null,
81        detailDateRef: null,
82        isShowModalDate: false,
83
84    };
85
86    window.viewMethod = {
87        handleModalComment(state, $this, isFocus = true) {
88            if (viewData.isShowModalComment !== state) viewData.isShowModalComment = state;
89            else return;
90            if (viewData.isShowModalComment) {
91                viewData.modalCommentRef?.setAttribute('tabindex', 0);
92                viewData.modalCommentRef?.removeAttribute('aria-hidden');
93                viewData.modalCommentRef?.classList.add('is_active');
94                viewData.beforeRef = $this;
95                $this.setAttribute('aria-expanded', true);
96                if (baseData.win.w < 768) scrollFix(true);
97                setTimeout(() => {
98                    viewData.modalCommentRef?.focus();
99                }, 1);
100            } else {
101                viewData.modalCommentRef?.removeAttribute('tabindex');
102                viewData.modalCommentRef?.setAttribute('aria-hidden', true);
103                viewData.modalCommentRef?.classList.remove('is_active');
104                viewData.modalCommentRef?.classList.add('is_hide');
105                if (baseData.win.w < 768) scrollFix(false);
106                if ($this && isFocus) {
107                    $this.setAttribute('aria-expanded', false);
108                    $this.focus();
109                }
110                setTimeout(() => {
111                    viewData.modalCommentRef?.classList.remove('is_hide');
112                }, 350);
113            }
114        },
115        handleModalCommentOpen(e, v) {
116            e.preventDefault();
117            clearSelection(); //툴바 팝업뜨면 삭제 250115 추가
118            viewMethod.handleModalComment(true, v);
119            $('body').css('overflow', 'hidden');
120			if (baseData.win.w < 768) { // 모바일앱 댓글 스크롤 이슈 관련 추가
121				$('body').addClass('minheight');
122				window.scrollBy(0, 1);
123			}
124        },
125        handleModalCommentClose(e) {
126            e.preventDefault();
127            viewMethod.handleModalComment(false, viewData.beforeRef);
128            $('body').css('overflow', 'visible');
129			if (baseData.win.w < 768) { // 모바일앱 댓글 스크롤 이슈 관련 추가
130				$('body').removeClass('minheight');
131				window.scrollBy(0, -1);
132			}
133        },
134        /* 개발이슈로 주석처리
135		handleEmotion(e) {
136            const $this = e.currentTarget;
137            const id = $this.dataset.id;
138            viewData.emotionState[id] = !viewData.emotionState[id];
139            //const countRef = $this.parentNode.querySelector('dd b');
140            viewData.emotionState[id] ? $this.classList.toggle('on') : $this.classList.toggle('on');
141            //countRef?.textContent = viewData.emotionState[id] ? Number(countRef?.textContent) + 1 : Number(countRef?.textContent) - 1;
142        },*/
143        setFixModalBtn() {
144            const st = viewData.modalCommentRef?.scrollTop;
145            const btnGroup = viewData.commentCloseRef?.parentNode;
146            btnGroup.style.transform = `translate3d(0, ${st}px, 0)`;
147			//btnGroup.style.position = 'fixed';
148        },
149        setNewsContentHeight() {
150            if (  !viewData.newsRef ) return ;
151            const newsH = viewData.newsRef?.scrollHeight;
152            const viewH = viewData.viewRef?.scrollHeight;
153            const viewTop = viewData.viewRef?.getBoundingClientRect().top;
154            const ratio = baseData.win.h / 2; // 뉴스가 끝난 부분이 화면에서 어느정도 올라왔을때, 전체 읽음으로 처리할지에 대한 비율
155            viewData.newsHeight = parseInt(newsH + baseData.yOffset + viewTop - ratio);
156            viewData.contentRef?.setAttribute('style', `--viewH : ${viewH + 20}`);
157        },
158        setSwiper(el) {
159            return new Swiper(el, {
160                slidesPerView: 'auto',
161                loop: false,
162                pagination: {
163                    el: el + ' .pagination',
164                    type: 'fraction',
165                },
166                navigation: {
167                    nextEl: el + ' .btn.next',
168                    prevEl: el + ' .btn.prev',
169                },
170            });
171        },
172        calcProgress(st) {
173            return st / viewData.newsHeight >= 1 ? 1 : st / viewData.newsHeight;
174        },
175        setMenuChangePoint() {
176            viewData.customMenuChangePoint = viewData.customMenuRef?.parentNode.getBoundingClientRect().top + baseData.yOffset;
177        },
178        handleModalUserInfo(state) {
179            if (viewData.isShowModalUserInfo !== state) viewData.isShowModalUserInfo = state;
180            else return;
181            if (viewData.isShowModalUserInfo) {
182                viewData.modalUserInfoRef?.setAttribute('tabindex', 0);
183                viewData.modalUserInfoRef?.removeAttribute('aria-hidden');
184                viewData.modalUserInfoRef?.classList.add('is_active');
185                if (baseData.win.w < 768) scrollFix(true);
186                setTimeout(() => {
187                    viewData.modalUserInfoRef?.focus();
188                }, 1);
189                $('body').css('overflow', 'hidden');
190				if (baseData.win.w < 768) { // 모바일앱 댓글 스크롤 이슈 관련 추가
191					$('body').addClass('minheight');
192					window.scrollBy(0, 1);
193				}
194            } else {
195                viewData.modalUserInfoRef?.removeAttribute('tabindex');
196                viewData.modalUserInfoRef?.setAttribute('aria-hidden', true);
197                viewData.modalUserInfoRef?.classList.remove('is_active');
198                viewData.modalUserInfoRef?.classList.add('is_hide');
199                if (baseData.win.w < 768) scrollFix(false);
200                setTimeout(() => {
201                    viewData.modalUserInfoRef?.classList.remove('is_hide');
202                }, 350);
203                $('body').css('overflow', 'visible');
204				if (baseData.win.w < 768) { // 모바일앱 댓글 스크롤 이슈 관련 추가
205					$('body').removeClass('minheight');
206					window.scrollBy(0, -1);
207				}
208            }
209        },
210        handleDate(state = null) {
211            if (state === null) {
212                viewData.isShowModalUserInfo = !JSON.parse(viewData.dateRef?.getAttribute('aria-expanded'));
213            } else {
214                if (viewData.isShowModalUserInfo !== state) viewData.isShowModalUserInfo = state;
215                else return;
216            }
217            if (viewData.isShowModalUserInfo) {
218                slideDown(viewData.detailDateRef);
219                viewData.dateRef?.setAttribute('aria-expanded', true);
220            } else {
221                slideUp(viewData.detailDateRef);
222                viewData.dateRef?.setAttribute('aria-expanded', false);
223            }
224        },
225    };
226    const init = () => {
227        viewData.headerRef = document.getElementById('header');
228        viewData.progressRef = document.getElementById('viewProgress');
229        viewData.contentRef = document.getElementById('contents');
230        viewData.viewRef = document.querySelector('.main_view');
231        viewData.newsRef = document.querySelector('.news_view');
232        //개발이슈로 주석처리 viewData.emotionHandleRef = document.querySelectorAll('.emotion_btn');
233        viewData.modalCommentRef = document.getElementById('modalComment');
234        viewData.commentOpenRef = document.querySelectorAll('[data-target="modalComment"]');
235        viewData.commentCloseRef = viewData.modalCommentRef?.querySelector('.close_modal');
236        viewData.textSizeRefs = document.querySelectorAll('.txt_size_node > button');
237        viewData.reporterShowRef = document.getElementById('reporterShow');
238        viewData.reporterCloseRef = document.getElementById('reporterClose');
239        viewData.readRef = document.querySelector('.btn_read');
240        viewData.asideRefs = document.querySelectorAll('.view_body aside');
241        viewData.commentDotRefs = document.querySelectorAll('.comment_item .btn_group > button');
242        viewData.commentSubCloseRefs = document.querySelectorAll('[data-sub-comment]');
243        viewData.commentSubOpenRefs = document.querySelectorAll('[data-open-comment]');
244
245        viewData.customMenuRef = document.querySelector('.custom_set_wrap');
246        viewData.userRefs = document.querySelectorAll('[data-user]');
247        viewData.modalUserInfoRef = document.getElementById('modalUserInfo');
248
249        viewData.dateRef = document.querySelector('[data-date]');
250        viewData.detailDateRef = viewData.dateRef?.parentNode.querySelector('.date_info');
251
252        viewMethod.setMenuChangePoint();
253        /* 개발이슈로 주석처리
254		viewData.emotionHandleRef?.forEach((v) => {
255            v.addEventListener('click', (e) => {
256                e.preventDefault();
257                viewMethod.handleEmotion(e);
258            });
259        });*/
260        viewMethod.setNewsContentHeight();
261
262        // 코멘트 모달 오픈
263        viewData.commentOpenRef?.forEach((v) => {
264            v.addEventListener('click', (e) => {
265                viewMethod.handleModalCommentOpen(e, v);
266            });
267        });
268        // 코멘트 모달 닫기
269        viewData.commentCloseRef?.addEventListener('click', (e) => {
270            viewMethod.handleModalCommentClose(e);
271        });
272        viewData.modalCommentRef?.addEventListener('scroll', (e) => {
273            e.preventDefault();
274            viewMethod.setFixModalBtn();
275        });
276        /* 기사뷰 하단 연재칼럽 스와이프 수정 width 값에 상관없이 동작
277        if (baseData.win.w < 768) {
278          viewData.seriesSwiper = viewMethod.setSwiper('#series_tab1', viewData.seriesOption);
279        }*/
280        viewData.seriesSwiper01 = viewMethod.setSwiper('#series_tab1', viewData.seriesOption01);
281        viewData.seriesSwiper02 = viewMethod.setSwiper('#series_tab2', viewData.seriesOption02);
282        viewData.seriesSwipe03r = viewMethod.setSwiper('#series_tab3', viewData.seriesOption03);
283
284        viewData.textSizeRefs.forEach((v) => {
285            v.addEventListener('click', () => {
286                viewData.textSizeRefs.forEach((v1) => {
287                    if (v === v1) {
288                        v1.parentNode.classList.add('is_active');
289                    } else {
290                        v1.parentNode.classList.remove('is_active');
291                    }
292                });
293                viewData.viewRef.dataset.fz = v.dataset.value;
294            });
295        });
296        viewData.reporterShowRef?.addEventListener('click', (e) => {
297            e.preventDefault();
298            viewData.reporterShowRef.closest('.reporter_ui.multi').style.display = 'none';
299            viewData.reporterCloseRef.closest('.reporter_item_group').style.display = 'block';
300        });
301
302        viewData.reporterCloseRef?.addEventListener('click', (e) => {
303            e.preventDefault();
304            viewData.reporterShowRef.closest('.reporter_ui.multi').style.display = 'block';
305            viewData.reporterCloseRef.closest('.reporter_item_group').style.display = 'none';
306        });
307
308        viewData.readRef?.addEventListener('click', () => {
309            viewData.isReadMode = viewData.readRef?.classList.contains('is_active');
310            viewData.asideRefs.forEach((v) => {
311                if (viewData.isReadMode) {
312                    v.style.display = 'none';
313                } else {
314                    v.style.removeProperty('display');
315                }
316            });
317            viewData.isReadMode ? viewData.contentRef?.classList.add('mode_read') : viewData.contentRef?.classList.remove('mode_read');
318        });
319        viewData.commentDotRefs.forEach((v) => {
320            v.addEventListener('click', () => {
321                const blurHandle = () => {
322                    v.setAttribute('aria-expanded', false);
323                };
324                viewData.commentDotRefs.forEach((v1) => {
325                    if (v === v1) {
326                        v1.setAttribute('aria-expanded', !JSON.parse(v1.getAttribute('aria-expanded')));
327                        const btn = v1.parentNode.querySelector('ul button');
328                        if (JSON.parse(v1.getAttribute('aria-expanded'))) {
329                            btn.addEventListener('blur', blurHandle);
330                            setTimeout(() => {
331                                btn.focus();
332                            }, 10);
333                        } else {
334                            btn.removeEventListener('blur', blurHandle);
335                        }
336                    } else {
337                        v1.setAttribute('aria-expanded', false);
338                    }
339                });
340            });
341        });
342        viewData.commentSubCloseRefs.forEach((v) => {
343            v.addEventListener('click', () => {
344                slideUp(v.closest('.depth_comment_wrap'));
345            });
346        });
347        viewData.commentSubOpenRefs.forEach((v) => {
348            v.addEventListener('click', () => {
349                const depthComment = v.closest('li').querySelector('.depth_comment_wrap');
350                const display = window.getComputedStyle(depthComment).display;
351                if (depthComment && display === 'none') slideDown(v.closest('li').querySelector('.depth_comment_wrap'));
352            });
353        });
354        viewData.userRefs.forEach((v) => {
355            v.addEventListener('click', () => {
356                viewMethod.handleModalUserInfo(true, v);
357            });
358        });
359        viewData.modalUserInfoRef?.querySelector('[data-back]').addEventListener('click', () => {
360            viewMethod.handleModalUserInfo(false);
361        });
362
363        viewData.dateRef?.addEventListener('click', () => {
364            viewMethod.handleDate();
365        });
366    };
367
368    window.addEventListener("load", function () {
369        init();
370    });
371
372	document.addEventListener("DOMContentLoaded", function(){
373		window.max_scroll = 0 ;
374		window.addEventListener('scroll', (e) => {       
375			//if (viewData.isScrolling) return;
376			if ( viewData.isScrolling ) return;
377			if ( !viewData.progressRef ) return;
378		
379			viewData.isScrolling = true;
380			viewData.progressRef.value = parseInt(Math.abs(viewMethod.calcProgress(baseData.yOffset) * 100));
381
382			if(viewData.progressRef.value > max_scroll){
383				max_scroll = viewData.progressRef.value
384				if(viewData.progressRef.value > 100){
385					max_scroll = 100;
386				}
387			}
388			
389			setTimeout(() => {
390				viewData.isScrolling = false;
391			}, 20);
392
393            
394            let dataDir = document.querySelector('html').getAttribute('data-dir');//241105 추가
395            //241105 조건 추가 
396			if (baseData.yOffset > viewData.customMenuChangePoint && dataDir == 'down'){
397				if (viewData.headerRef) viewData.headerRef?.classList.add('is_tool');
398				if (viewData.customMenuRef) viewData.customMenuRef?.classList.add('is_fix');
399                if($('.recon02').length != 0){
400                    $('.logo_sec').addClass('is_active');//241025 수정
401                }   
402
403                
404
405			} 
406            // else {
407			// 	if (viewData.customMenuRef) viewData.customMenuRef?.classList.remove('is_fix');
408			// 	if (viewData.headerRef) viewData.headerRef?.classList.remove('is_tool');
409            //     if($('.recon02').length != 0){
410            //         $('.logo_sec').removeClass('is_active');//241025 수정
411            //     }
412               
413			// } //250206 삭제
414
415            //모바일 헤더 관련 250206 추가
416            var win = $(window),
417            header = $("#header");
418    
419            win.scroll (function(){
420                if ( $(this).scrollTop() == 0 ) {
421                    $('.view_head_setting .custom_set_wrap').removeClass('is_fix');
422                    header.removeClass('is_tool');
423                    $('.logo_sec').removeClass('is_active');
424                }  
425            });
426		});
427
428        // 인터랙션 바 댓글창 버튼
429        if (baseData.win.w > 767) {
430            $('.interaction_bar').removeClass('is_active');//241025 추가
431        }else{
432            $('.interaction_bar').addClass('is_active');//241025 추가
433        }
434	});
435
436    window.addEventListener('resize', () => {
437        if (viewData.isResizing) return;
438        viewData.isResizing = true;
439        viewMethod.setMenuChangePoint();
440        setTimeout(() => {
441            viewData.isResizing = false;
442            if (baseData.win.w > 767) {
443                if (viewData.seriesSwiper01) {
444                    viewData.seriesSwiper01.destroy();
445                    viewData.seriesSwiper01 = null;
446                }
447                if (viewData.seriesSwiper02) {
448                    viewData.seriesSwiper02.destroy();
449                    viewData.seriesSwiper02 = null;
450                }
451                if (viewData.seriesSwiper03) {
452                    viewData.seriesSwiper03.destroy();
453                    viewData.seriesSwiper03 = null;
454                }
455                
456                $('.interaction_bar').removeClass('is_active');//241025 인터랙션바 비활성화
457            } else {
458                if (viewData.isShowModalUserInfo || viewData.isShowModalComment) scrollFix(false);
459                if (!viewData.seriesSwiper01) {
460                    viewData.seriesSwiper01 = viewMethod.setSwiper('#series_tab1', viewData.seriesOption01);
461                }
462                if (!viewData.seriesSwiper02) {
463                    viewData.seriesSwiper02 = viewMethod.setSwiper('#series_tab2', viewData.seriesOption02);
464                }
465                if (!viewData.seriesSwiper03) {
466                    viewData.seriesSwiper03 = viewMethod.setSwiper('#series_tab3', viewData.seriesOption03);
467                }
468
469                $('.interaction_bar').addClass('is_active');//241025 인터랙션바 활성화
470            }
471        }, 30);
472    });
473})();
474
475$('#photoview .btn_img a').on('click', function () {
476    $("#photoview_layer").css('visibility', 'visible');
477    $('body').css('overflow', 'hidden');
478    //return false;
479});
480
481//251114 추가
482$('#photoview .btn_img button').on('click', function () {
483    $("#photoview_layer").css('visibility', 'visible');
484    $('body').css('overflow', 'hidden');
485});
486
487$('#photoview_layer .btn_close ').on('click', function () {
488    $("#photoview_layer").css('visibility', 'hidden');
489    $('body').css('overflow', 'visible');
490    return false;
491});
492
493/* 회원가입유도 , 구독유도 */
494/*$( window ).scroll( function() {
495    $( '#join_msg' ).addClass( 'layer_in_bottom ' );
496    $( '#subscribe_msg' ).addClass( 'layer_in_bottom ' );
497});*/
498
499/* 연재칼럼 탭 */
500$('.series_news_sec .tab_list_wrap button').click(function () {
501    var tab_id = $(this).attr('data-tab');
502
503    $('.series_news_sec .tab_list_wrap li').removeClass('is_active');
504    $('.view_series .sec_body').removeClass('active');
505
506    $(this).parent().addClass('is_active');
507    $("#" + tab_id).addClass('active');
508});
509
510/* 기사뷰 추천 비추천 */
511$('.comment_foot .btn_recommend').click(function () {
512    $(this).toggleClass('is_active').siblings('.btn_recommend').removeClass('is_active');
513});
514
515// 속보배너 있을 시 wrapper 상단패딩 - .today_contents 없을 경우 //240912 편성표와 함께 삭제
516// let tC = $('.today_contents');
517// if (tC.length == 0) {
518//     let wPTop = parseInt($('#wrapper').css('padding-top'));
519//     let breakingNews = $('.breaking_news');
520//     let breakingNewsH = breakingNews.height();
521//     if (breakingNews.length > 0) {
522//         wPTop = wPTop + breakingNewsH;
523//         $('#wrapper').css('padding-top', wPTop);
524//     }
525// }
526
527// 속보 배너 닫힘 버튼 - .today_contents 없을 경우
528$('.breaking_news').find('.btn_close').on('click', function () {
529    $(this).parents('.breaking_news').addClass('hidden').hide();
530    if (tC.length == 0) {
531        wPTop = $('#header').height();
532        $('#wrapper').css('padding-top', wPTop);
533        $('#header').css('inset', '0 0 auto');
534    }
535})
536
537// 기자정보 팝업
538window.modalAuthorPopupObj = Popup( $( '#modalAuthor' ), {
539	vertical: 'center',  /* top, bottom, center */
540	horizontal: 'center',  /* left, right, center */
541	//effect: 'slide',  /* clip slide blind */
542	//direction: 'left',   /* up, down, left, right */
543	duration: 0.3
544	//scroll: true
545});
546
547$('.author_info .modal_open').on('click', function () {
548	modalAuthorPopupObj.show();
549});
550$('#modalAuthor .close_btn').on('click', function () {
551	modalAuthorPopupObj.hide();
552});
553
554// 단일 이미지 레이어
555$('#zoom_layer .btn_close').on('click', function () {
556	$('#zoom_layer').css('display' , 'none');
557	$('body').removeClass('scroll_hidden');
558});
559
560// 어플설치유도 팝업 추가 240702
561$('#app_msg .close_btn ').on('click', function () {
562    $( '#app_msg' ).css( 'display','none' );
563});
564
565// 구독유도 팝업 추가 241025
566$('#subscribe_msg .close_btn ').on('click', function () {
567    $( '#subscribe_msg' ).css( 'display','none' );
568});
569
570// 모바일 하단 광고배너 추가 250512
571$('.bottom_ad_m .close_btn ').on('click', function () {
572    $( '.bottom_ad_m' ).css( 'display','none' );
573});
574
575// 툴바 팝업떴을때 삭제 추가 250115
576function clearSelection() {
577    if (window.getSelection) {
578        window.getSelection().removeAllRanges();
579    } else if (document.selection) {
580        document.selection.empty();
581    }
582}

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.