PageSourceSearch

https://tvseoul.kr/js/mynews.js

js tvseoul.kr collected 2026-10-02 19:40:03 UTC 11,600 bytes, 492 lines download raw bytes

1// <script type="text/javascript" src="/js/prototype.js"> 프레임워크 적용
2
3function resizeFrame(frameName)
4{
5	var targetFrame = $(frameName);
6	var targetBody	= eval(frameName+".document.body");
7	targetFrame.style.height = targetBody.scrollHeight + (targetBody.offsetHeight - targetBody.clientHeight);
8}
9
10function comboClear(idName)
11{
12	var obj = document.getElementById(idName);
13	for (var i = obj.length - 1; i >= 0; i--)
14	{
15		obj.options[i] = null;
16	}
17}
18
19function comboInsert(idName, key, val)
20{
21	var obj = document.getElementById(idName);
22	obj.options[obj.length] = new Option(key, val);
23}
24
25function comboUpdate(idName, key, val)
26{
27	var obj = document.getElementById(idName);
28	for (var i = 0; i < obj.length; i++)
29	{
30		if (obj.options[i].value == val)
31		{
32			obj.options[i].text = key;
33		}
34	}
35}
36
37function comboDelete(idName, val)
38{
39	var obj = document.getElementById(idName);
40	for (var i = 0; i < obj.length; i++)
41	{
42		if (obj.options[i].value == val)
43		{
44			obj.options[i] = null;
45		}
46	}
47}
48
49function resizeCenter(w, h)
50{
51	window.resizeTo(w, h + 20);
52	var c_x = (screen.availWidth	- w) / 2;
53	var c_y = (screen.availHeight - h) / 2;
54	window.moveTo(c_x, c_y);
55}
56
57function resizeWindow(w, h)
58{
59	window.resizeTo(w, h + 20);
60}
61
62function resizeFull()
63{
64	self.moveTo(0, 0);
65	self.resizeTo(screen.availWidth, screen.availHeight);
66}
67
68function exchangeOption(opt1, opt2)
69{
70	var tmp1, tmp2;
71
72	tmp1 = opt1.value;
73	tmp2 = opt1.text;
74
75	opt1.value = opt2.value;
76	opt1.text = opt2.text;
77
78	opt2.value = tmp1;
79	opt2.text = tmp2;
80}
81
82// 메세지 경고창
83function show_info(msg)
84{
85	alert(msg);
86}
87
88// id Tag 영역 숨기고 보이게
89function showManagePane(idName)
90{
91	var obj =  document.getElementById(idName).style;
92	if (obj.display == "inline" || obj.display == "")
93	{
94		obj.display = "none";
95	}
96	else
97	{
98		obj.display = "inline";
99	}
100}
101
102// 팝업창 간소화 : openWin(url, name, width, height, scroll)
103function openWin(url, name, width, height, scroll)
104{
105  window.open(url, name, 'scrollbars='+scroll+', width='+width+', height='+height+'');
106}
107
108function moveCenter()
109{
110  var w = document.body.offsetWidth;
111  var h = document.body.offsetHeight;
112  var c_x = (screen.availWidth  - w)  / 2;
113  var c_y = (screen.availHeight - h) / 2;
114  window.moveTo(c_x, c_y);
115}
116
117// 레이어 닫기
118function closeLyr(id)
119{
120  $(id).style.display = "none";
121}
122
123// 레이어 오픈
124function openLyr(id)
125{
126  $(id).style.display = "inline";
127}
128
129// 입력글자수 제한(textarea)
130// frm: 폼네임, name:textarea name, limit_str : 제한 글자수
131function checkLength(frm, name, limit_str)
132{
133  var target = eval("$(frm)."+name+".value.length");
134
135  idCurLen.innerHTML = target;
136  if (target > limit_str)
137  {
138		var keycode = window.event.keyCode;
139		if (keycode == 8 || keycode == 46) return;
140		alert(limit_str+"자 이내로 작성해주세요~");
141		return;
142  }
143}
144
145// 경고창 출력후 해당 폼으로 포커싱
146// 사용예: return err(member.user_id, "회원 아이디 중복 검사를 먼저 하십시오.");
147function err(frm, text)
148{
149  if (text != "")
150  {
151    window.alert(text);
152  }
153  if (frm != "")
154  {
155    frm.focus();
156  }
157  return false;
158}
159
160
161// 임시(포토리뷰등에서 쓰이는 드림위버 온로드 이벤트
162function MM_swapImgRestore() { //v3.0
163  var i,x,a=document.MM_sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
164}
165
166function MM_preloadImages() { //v3.0
167  var d=document; if(d.images){ if(!d.MM_p) d.MM_p=new Array();
168    var i,j=d.MM_p.length,a=MM_preloadImages.arguments; for(i=0; i<a.length; i++)
169    if (a[i].indexOf("#")!=0){ d.MM_p[j]=new Image; d.MM_p[j++].src=a[i];}}
170}
171
172function MM_findObj(n, d) { //v4.01
173  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
174    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
175  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
176  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=MM_findObj(n,d.layers[i].document);
177  if(!x && d.getElementById) x=d.getElementById(n); return x;
178}
179
180function MM_swapImage() { //v3.0
181  var i,j=0,x,a=MM_swapImage.arguments; document.MM_sr=new Array; for(i=0;i<(a.length-2);i+=3)
182   if ((x=MM_findObj(a[i]))!=null){document.MM_sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}
183}
184
185function setPng24(obj) {
186    obj.width=obj.height=1;
187    obj.className=obj.className.replace(/\bpng24\b/i,'');
188    obj.style.filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+ obj.src +"',sizingMethod='image');"
189    return '';
190}
191
192function doPopup(url, nWidth, nHeight, scrollbarsYesNo) {
193	window.open(url, '_blank', 'width='+nWidth+',height='+nHeight+',scrollbars='+scrollbarsYesNo);
194}
195
196
197//검색결과 텍스트 표기
198function changeTextColor(targetText, targetEle) {
199    if (!targetText.trim()) return;
200
201    const elements = document.querySelectorAll(targetEle);
202    // 1. 'gi' 플래그 사용: g(전체 반복), i(대소문자 무시)
203    const regex = new RegExp(escapeRegExp(targetText), 'gi');
204
205    elements.forEach(element => {
206        highlightTextNodes(element, regex);
207    });
208}
209
210function highlightTextNodes(node, regex) {
211    if (node.nodeType === 3) {
212        const parent = node.parentNode;
213        if (parent.classList && parent.classList.contains('src_mark')) return;
214
215        const content = node.nodeValue;
216        
217        // regex.test()를 쓰면 lastIndex 문제가 생길 수 있어 match로 확인
218        if (content.match(regex)) {
219            const tempSpan = document.createElement('span');
220            
221            // 2. replace의 두 번째 인자로 함수를 전달하여 매칭된 원본 텍스트($& 또는 match)를 그대로 유지
222            tempSpan.innerHTML = content.replace(regex, (match) => {
223                return `<em class="src_mark">${match}</em>`;
224            });
225            
226            while (tempSpan.firstChild) {
227                parent.insertBefore(tempSpan.firstChild, node);
228            }
229            parent.removeChild(node);
230        }
231    } 
232    else if (node.nodeType === 1 && node.childNodes) {
233        if (node.tagName !== 'SCRIPT' && node.tagName !== 'STYLE') {
234            Array.from(node.childNodes).forEach(child => highlightTextNodes(child, regex));
235        }
236    }
237}
238
239function escapeRegExp(str) {
240    return str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
241}
242
243function initScrollHighlight() {
244
245    const containers = document.querySelectorAll(
246        '.smartOutput, .mo_smart'
247    );
248
249    if (!containers.length) return;
250
251    const observer = new IntersectionObserver(function(entries) {
252
253        entries.forEach(function(entry) {
254
255            if (!entry.isIntersecting) return;
256
257            const group = entry.target._highlightGroup;
258
259            if (group) {
260                runHighlightGroup(group);
261            }
262
263            observer.unobserve(entry.target);
264        });
265
266    }, {
267        threshold: 0,
268        rootMargin: '0px 0px -25% 0px'
269    });
270
271
272    containers.forEach(function(container) {
273
274        const spans = Array.from(
275            container.querySelectorAll(
276                'span[style*="background-color"]'
277            )
278        );
279
280        if (!spans.length) return;
281
282        /*
283         * 같은 색상의 하이라이트 span을 그룹화
284         */
285        let groups = [];
286        let currentGroup = [];
287
288        spans.forEach(function(span, index) {
289
290            const color = span.style.backgroundColor;
291
292            if (!color) return;
293
294
295            if (!currentGroup.length) {
296
297                currentGroup.push(span);
298
299            } else {
300
301                const prev = currentGroup[currentGroup.length - 1];
302
303                if (
304                    getHighlightColor(prev) === getHighlightColor(span) &&
305                    isHighlightConnected(prev, span)
306                ) {
307
308                    currentGroup.push(span);
309
310                } else {
311
312                    groups.push(currentGroup);
313                    currentGroup = [span];
314
315                }
316
317            }
318
319        });
320
321        if (currentGroup.length) {
322            groups.push(currentGroup);
323        }
324
325        /*
326         * 그룹 초기화
327         */
328        groups.forEach(function(group) {
329
330            prepareHighlightGroup(group);
331
332            const first = group[0];
333
334            first._highlightGroup = group;
335
336            observer.observe(first);
337
338        });
339
340    });
341
342    /*
343     * 인라인 background 색상 가져오기
344     */
345    function getHighlightColor(span) {
346
347        return span.style.backgroundColor;
348
349    }
350
351    /*
352     * 두 span 사이에 실제 일반 텍스트가 있는지 확인
353     *
354     * <span>...</span>
355     * <a><span>...</span></a>
356     * <span>...</span>
357     *
358     * 같은 구조는 연결된 것으로 처리
359     */
360    function isHighlightConnected(prev, next) {
361
362        const range = document.createRange();
363
364        try {
365
366            range.setStartAfter(prev);
367            range.setEndBefore(next);
368
369            const contents = range.cloneContents();
370
371            /*
372             * 사이에 있는 하이라이트가 아닌 실제 텍스트 확인
373             */
374            const text = contents.textContent
375                .replace(/\s+/g, '');
376
377            // 텍스트가 없다면 연결된 것으로 판단
378            return text.length === 0;
379
380        } catch (e) {
381
382            return false;
383
384        }
385
386    }
387
388    /*
389     * 그룹 초기 상태 설정
390     */
391    function prepareHighlightGroup(group) {
392
393        let totalWidth = 0;
394
395        /*
396         * 각 span의 실제 화면상의 길이 계산
397         */
398        group.forEach(function(span) {
399
400            if (span.dataset.highlightInit === 'true') return;
401
402            const color = span.style.backgroundColor;
403
404            span.dataset.highlightInit = 'true';
405
406            let width = 0;
407
408            Array.from(span.getClientRects()).forEach(function(rect) {
409                width += rect.width;
410            });
411
412            span._highlightWidth = width;
413
414            totalWidth += width;
415
416
417            span.style.setProperty(
418                'background-color',
419                'transparent',
420                'important'
421            );
422
423            span.style.backgroundImage =
424                'linear-gradient(to right, ' +
425                color + ', ' +
426                color + ')';
427
428            span.style.backgroundRepeat = 'no-repeat';
429
430            span.style.backgroundPosition = 'left center';
431
432            span.style.backgroundSize = '0% 100%';
433
434        });
435
436        /*
437         * 전체 그룹 너비 저장
438         */
439        group._totalHighlightWidth = totalWidth;
440
441    }
442
443    /*
444     * 실제 애니메이션 실행
445     */
446    function runHighlightGroup(group) {
447
448        const totalDuration = 1500; // 전체 1.5초
449
450        const totalWidth =
451            group._totalHighlightWidth || 1;
452
453        let accumulatedDelay = 0;
454
455
456        group.forEach(function(span) {
457
458            const width =
459                span._highlightWidth || 0;
460
461            /*
462             * 전체 길이에 비례해서 해당 span의
463             * 애니메이션 시간을 계산
464             */
465            const duration =
466                totalDuration * (width / totalWidth);
467
468
469            span.style.transition =
470                'background-size ' +
471                duration +
472                'ms linear ' +
473                accumulatedDelay +
474                'ms';
475
476            /*
477             * 애니메이션 시작
478             */
479            requestAnimationFrame(function() {
480
481                span.style.backgroundSize =
482                    '100% 100%';
483
484            });
485
486
487            accumulatedDelay += duration;
488
489        });
490
491    }
492}

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.