사용자:BANIP/낙서장: 두 판 사이의 차이

리버티게임, 모두가 만들어가는 자유로운 게임
잔글 (사이트 정상작동 원인확인)
태그: 되돌려진 기여
편집 요약 없음
 
(사용자 2명의 중간 판 33개는 보이지 않습니다)
1번째 줄: 1번째 줄:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <style>
        .modal-primary-wrapper {
            --var--header-bg-color: hsl(238 20% 30%);
            position: fixed;
            z-index: 9999;
            top: 0;
            left: 0;
            width: 100%;
            height: 100%;
            background-color: rgba(0, 0, 0, 0.5);
        }
       
        /* .modal-primary-wrapper 하위요소 스크롤바 지정 */
        .modal-primary-wrapper *::-webkit-scrollbar {
            width: 4px;
            height: 4px;
            background-color: #fff;
        }
       
        .modal-primary-wrapper *::-webkit-scrollbar-thumb {
            background-color: var(--var--header-bg-color);
            border-radius: 4px;
        }
       
        .modal-primary-wrapper .modal {
            position: absolute;
            overflow: hidden;
            transform: translate(-50%, -50%);
            top: 50%;
            left: 50%;
            max-height: 80%;
            min-width: 250px;
            max-width: 800px;
            background-color: white;
            box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
            display: grid;
            grid-template-rows: 40px 1fr 40px;
        }
       
        .modal-primary-wrapper .header {
            height: 40px;
            background-color: var(--var--header-bg-color);
            border-bottom: 1px solid #ddd;
            color:#fff;
        }
       
        .modal-primary-wrapper .title {
            float: left;
            padding: 10px;
            font-size: 20px;
            font-weight: bold;
        }
       
        .modal-primary-wrapper .content {
            overflow: auto;
            padding:8px;
            background: #edf6fc;
        }
       
        .modal-primary-wrapper .footer {
            border-top: 1px solid #ddd;
            display: flex;
            position: relative;
            align-items: center;
            justify-content: space-around;
        }
       
        .modal-primary-wrapper .footer > .btn {
            width: 100%;
            height: 100%;
            display: flex;
            justify-content: center;
            align-items: center;
            cursor: pointer;
            transition: background 0.2s;
            background: #fff;
        }
       
        .modal-primary-wrapper .footer > .btn:hover {
            background: #eee;
        }
       
        .modal-primary-wrapper .footer > .btn:not(:last-child) {
            border-right: 1px solid #ddd;
        }
    </style>
<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
    <script>
        const createModal = function(option){


// 프리로딩 가능한 링크 최고 갯수
            var resolve = function(){}
var previewLimit = 5
            var reject = function(){}
var getParsedDocumentPromise = (function(link){
           
    var mwApi = new mw.Api();
             var content = option.content || "동의하시겠습니까?"
    return function(pagename){
             var header = option.header || "모달창"
        return new Promise(function(resolve, reject){
            var onModalOpen = option.onModalOpen || function(){}
             mwApi .get({
                action: 'parse',
                page: pagename,
                formatversion: 2
             }).then(function(data){
                resolve(data.parse.displaytitle, data.parse.text);
            }, function(e){
                reject(e);
            });
                       
        });
    }
})();


var setLoading = function(boolean){
            var $modal = $(`
    // 이미 로딩 완료된 작업의 경우 로딩창을 표시하지 않기 위해
            <div class="modal-primary-wrapper">
    // 로딩창 표시 작업시 예약 플래그를 설정하고 약간의 텀을 두기
        <div class="modal modal-primary">
    // 로딩창 삭제 작업시 표시작업이 예약되어있으면 같이 삭제
        <div class="header">
}
        <div class="title"></div>
        </div>
        <div class="content"></div>
        <div class="footer">
        <div class="btn-accept btn-close btn">확인</div>
        <div class="btn-deny btn-close btn">취소</div>
        </div>
        </div>
        </div>`);
           
            var behaive = {
                open: function(){
                    onModalOpen($modal);
                    $modal.fadeIn();
                    return new Promise(function(thisResolve,thisReject){
                        resolve = thisResolve;
                        reject = thisReject;
                    })
                },
                close: function(){
                    $modal.fadeOut()
                    reject('취소됨');
                }
            }


// 선행로딩된 페이지들
            $modal.find(".modal > .content").html(content);
var documentPromiseMap = {};
            $modal.find(".modal > .header > .title").html(header);


var namespace = $("#firstHeading > span.mw-page-title-namespace").val() || ""
// 해당 링크의 action, title, oldid 파라미터가 없는 링크만 가져오기


var targetLinks = $("#mw-content-text a").not(".external").filter(function() {
            $modal.find(".btn-accept").on("click",function(){
    return !this.href.match(/action=|title=|oldid=/);
                resolve();
}).toArray().map(function(el) {
            })
    var [_, namespace, docname] = decodeURI(el.href).match(/[a-z]+\:\/\/[a-z\.]+\/[a-z\.]+\/([^\:]+)\:?(.*)/);
            $modal.find(".btn-close, .modal-primary-wrapper").on("click",function(){
    if (docname === "") [namespace, docname] = [docname, namespace];
                behaive.close();
    [namespace, docname];
            })
   
            $(document.body).append($modal);
    return {
        el,
        link: el.href,
        title: el.title,
        namespace, docname
    }
})
// 동일한 네임스페이스만 이동되게 필터링
.filter(({namespace:thisNamespace}) => thisNamespace === namespace )
// 필터된게 previewLimit 갯수 이상이면 동작 x, 프로미스맵에 클릭 시 로딩 필요함을 명시
if(targetLinks.length > previewLimit){
    targetLinks.forEach(({link}) => documentPromiseMap[link] ||= null);
} else {
    // 필터링된게 프로미스맵에 없는 경우 사전 프리로딩 프로미스 추가
    targetLinks.forEach(({link, docname, namespace}) => {
        var pagename = docname === "" ? namespace : `${namespace}:${docname}`;
        documentPromiseMap[link] ||= getParsedDocumentPromise(pagename)
    });
}
 
// 가져온 링크로 전체 작업
targetLinks.forEach(function(this){
    var $link = $(this);
    // a링크 href를 #로 변경, 클릭 시 이벤트 바인딩
    var href = $link.attr("href");
    var documentPromise = documentPromiseMap[href];
    $link
        .attr("href", "#")
        .click(function(){
 
            // 프리로드 불필요한 경우(네임스페이스가 다를때, 편집/리비전확인 링크일때) url 영구이동
            if(documentPromise === undefined){
                return location.href = href;  
            }
            // 프리로드되지 않은 이동 가능한 링크면 로딩창 표시 후 해당 페이지 로딩
            if(documentPromise === null){
                documentPromise = getParsedDocumentPromise(href);
            }


             // 프로미스가 아직 안끝났으면 로딩창 표시
             return behaive.open();
            setLoading(true);
        }
            // 링크 프로미스에 문제가 있을 시 다시 내용 확인, 성공시 문서 프로미스에 저장, 오류시 에러메세지
            documentPromise.then(function(title, text){
                // 프리로드 프로미스가 정상적으로 불러왔을 경우


                // Promise.race1
        createModal({
                    // 문서내용 페이드 아웃,  
            header: '업로드 하시겠습니까?',
                    // 프로미스 내용으로 교체
            content: 'test',
                    // 문서내용 페이드 인
        })
                // Promise.race2
        .then(function(result){
                    // 사전로딩된 내용에서 프리로드 분석 재실행
            console.log(result)
            }).error(function(e){
        }).catch(function(){})
                // 에러 발생 시 실패한 페이지 다시 프로미스에 저장 시도
                documentPromiseMap[href] = null;
                documentPromise = null;


                // 에러메세지 표시
                toast('페이지 로딩에 실패했습니다. 다시 시도해주세요.');


            }).finally(function(){
    </script>
                // 로딩창 삭제
                setLoading(false);
</body>
            });
</html>
        });
    })
})

2023년 9월 7일 (목) 17:43 기준 최신판

<!DOCTYPE html> <html lang="en"> <head>

   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <title>Document</title>

</head> <body>

   <style>
       .modal-primary-wrapper {
           --var--header-bg-color: hsl(238 20% 30%);
           position: fixed;
           z-index: 9999;
           top: 0;
           left: 0;
           width: 100%;
           height: 100%;
           background-color: rgba(0, 0, 0, 0.5);
       }
       
       /* .modal-primary-wrapper 하위요소 스크롤바 지정 */
       .modal-primary-wrapper *::-webkit-scrollbar {
           width: 4px;
           height: 4px;
           background-color: #fff;
       }
       
       .modal-primary-wrapper *::-webkit-scrollbar-thumb {
           background-color: var(--var--header-bg-color);
           border-radius: 4px;
       }
       
       .modal-primary-wrapper .modal {
           position: absolute;
           overflow: hidden;
           transform: translate(-50%, -50%);
           top: 50%;
           left: 50%;
           max-height: 80%;
           min-width: 250px;
           max-width: 800px;
           background-color: white;
           box-shadow: 0 0 10px rgba(0, 0, 0, 0.5);
           display: grid;
           grid-template-rows: 40px 1fr 40px;
       }
       
       .modal-primary-wrapper .header {
           height: 40px;
           background-color: var(--var--header-bg-color);
           border-bottom: 1px solid #ddd;
           color:#fff;
       }
       
       .modal-primary-wrapper .title {
           float: left;
           padding: 10px;
           font-size: 20px;
           font-weight: bold;
       }
       
       .modal-primary-wrapper .content {
           overflow: auto;
           padding:8px;
           background: #edf6fc;
       }
       
       .modal-primary-wrapper .footer {
           border-top: 1px solid #ddd;
           display: flex;
           position: relative;
           align-items: center;
           justify-content: space-around;
       }
       
       .modal-primary-wrapper .footer > .btn {
           width: 100%;
           height: 100%;
           display: flex;
           justify-content: center;
           align-items: center;
           cursor: pointer;
           transition: background 0.2s;
           background: #fff;
       }
       
       .modal-primary-wrapper .footer > .btn:hover {
           background: #eee;
       }
       
       .modal-primary-wrapper .footer > .btn:not(:last-child) {
           border-right: 1px solid #ddd;
       }
   </style>

<script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>

   <script>
       const createModal = function(option){
           var resolve = function(){}
           var reject = function(){}
           
           var content = option.content || "동의하시겠습니까?"
           var header = option.header || "모달창"
           var onModalOpen = option.onModalOpen || function(){}
           var $modal = $(`

`);

           var behaive = {
               open: function(){
                   onModalOpen($modal);
                   $modal.fadeIn();
                   return new Promise(function(thisResolve,thisReject){
                       resolve = thisResolve;
                       reject = thisReject;
                   })
               },
               close: function(){
                   $modal.fadeOut()
                   reject('취소됨');
               }
           }
           $modal.find(".modal > .content").html(content);
           $modal.find(".modal > .header > .title").html(header);


           $modal.find(".btn-accept").on("click",function(){
               resolve();
           })
           $modal.find(".btn-close, .modal-primary-wrapper").on("click",function(){
               behaive.close();
           })
           $(document.body).append($modal);
           return behaive.open();
       }
       createModal({
           header: '업로드 하시겠습니까?',
           content: 'test',
       })
       .then(function(result){
           console.log(result)
       }).catch(function(){})


   </script>

</body> </html>