jQuery 플러그인 개발하기: 나만의 jQuery 플러그인 만드는 가이드

jQuery 플러그인은 매우 유용하다. 이전 포스트에서 사용한 jQuery UI 도 유용한 플러그인 중 하나로 훌륭한 플러그인은 매번 필요한 기능을 직접 개발하지 않게 해준다.

그래서 궁금해 진 것은 이런 jQuery 플러그인을 만드는 방법이다. 해당 방법을 한번 알아보고 정리해 보자.

기본 구조 정의

jQuery 플러그인은 기본적으로 자바스크림트의 함수의 형태로 jQuery 객체의 메소드로 추가 된다. 쉽게 말하자면 jQuery 선택자의 뒤에 오는 .메소드명(); 으로 사용하도록 만들어진다.

이렇게 나만의 메소드를 추가하는 방법은 $.fn 를 이용해 나만의 메소드를 만들 수 있다.

다음 코드는 myPlugin 이란 js 파일을 만든 후 다음과 같은 코드를 작성했다.

$.fn.myPlugin = function() {
    console.log($(this));
}

그리고 이 파일을 HTML 에서 불러와 사용해 보면 console.log 가 정상적으로 출력 됨을 확인할 수 있다.

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>나만의 플러그인 제작</title>
<script src="js/jquery-3.7.1.min.js"></script>
<script src="js/jqueryPlugin/myPlugin.js"></script>
</head>
<body>
<div id="testDiv"></div>
<script>
$('#testDiv').myPlugin();
</script>
</body>
</html>

이를 통해 jQuery 객체 자체를 변경하고 옵션을 받아서 처리할 수 있게 되는 등의 작업이 가능해 진다.

$.fn.myPlugin = function() 의 괄호 안에 매개변수를 지정해서 전달 할 수도 있다.

이미지 갤러리 플러그인 만들어 보기

기본적인 플러그인 생성 방법을 응용해서 이미지 갤러리 플러그인을 직접 만들어 보았다. 이 코드는 jQuery UI 플러그인 도 포함 하여 제작 되었으므로 추가 되어야 한다.

customGalary.js

$.fn.customGalary = function(method) {
    const methods = {
        init: function() {
            if($(this).length == 0){
                console.error('요소를 찾지 못했습니다.');
            }
            $(this).addClass('customGallery');
            $(this).append('<div class = "tabs"><div class = "tab active">folder1</div></div>');
            $(this).append('<div id = "folder1" class = "gallery active"><ul class="sortable"></ul></div>');
            $(this).append('<div class = "btnArea"><button id = "addImage" type="button" class = "btn">사진 추가</button><button type="button" id="addFolder" class = "btn">폴더 추가</button></div>');
            $(this).append('<input type="file" id="fileInput" style="display: none;" accept="image/*" />');
        
            $(".sortable").sortable({
                placeholder: "ui-state-highlight"
            });
            $(".sortable").disableSelection();
        
            $(this).find('#addFolder').on('click', () => {
                const number = $(this).find('.tab').length + 1;
                const id = 'folder' + number;
                $(this).find('.tabs').append(`<div class = "tab">${id}</div>`);
                $(this).find('.gallery').after(`<div id = "${id}" class = "gallery"><ul class="sortable"></ul></div>`);
        
                $(this).find('.tab').on('click', (e) => {
                    $(this).find('.tab').removeClass('active');
                    $(this).find('.gallery').removeClass('active');
                    $(e.target).addClass('active');        
                    const id = $(e.target).text();
        
                    $(this).find(`#${id}`).addClass('active');    
                });
            });
        
            $(this).find('#addImage').on('click', () => {
                $(this).find('#fileInput').click();
            });
        
            $(this).find('#fileInput').change((event) => {
                const files = event.target.files;
        
                $.each(files, (idx, file) => {
                    const $li = $('<li>');
                    const url = URL.createObjectURL(file);                
                    const $img = $('<img>', {src: url});
                    
                    $li.append($img);
        
                    const id = $(this).find('.tab.active').text();
                    $(this).find(`#${id}`).find('.sortable').append($li);
                });
            });

            return this;
        },
        addImage: function(imageUrl) {
            const id = $(this).find('.tab.active').text();
            
            const $li = $('<li>');         
            const $img = $('<img>', {src: imageUrl});

            $li.append($img);
            $(this).find(`#${id}`).find('.sortable').append($li);

            return this;
        }
    }

    // 메서드 호출 로직
    if (methods[method]) {
        console.log(Array.prototype.slice.call(arguments, 1));
        return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
    } else if (typeof method === 'object' || !method) {
        return methods.init.apply(this, arguments);
    } else {
        $.error('Method ' +  method + ' does not exist on jQuery.customGallery');
    }

    return $(this);
}

customGalary.css

.customGallery {
    width: 800px;    
    height: 500px;
}
.customGallery .tab {
    display: inline-block;
    cursor: pointer;
    margin-right: 5px;
}
.customGallery .tab.active {
    border-bottom: 30px solid #000000; /* 사다리꼴의 높이와 색상 */
    border-right: 25px solid transparent; /* 오른쪽 경사 */
    height: 0;
    width: 50px; /* 사다리꼴의 너비 */
    color: white;
    font-weight: bold;
}
.customGallery .gallery {
    width: 100%;
    height: 100%;
    border: 1px solid #000000;
    display: none;
}
.customGallery .gallery.active{
    display: block;
}
.customGallery .btnArea {
    text-align: right;
}
.customGallery .btn {
    background-color: #000000;
    color: white;
    font-weight: bold;
    cursor: pointer;
}
.customGallery img {
    width: 100px;
    height: 100px;
}
.customGallery .sortable { list-style-type: none; margin: 0; padding: 0; width: 100%; }
.customGallery .sortable li { margin: 3px 3px 3px 0; padding: 1px; float: left; width: 100px; height: 100px; text-align: center; }

HTML 문서

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>나만의 플러그인 제작</title>
<link rel="stylesheet" href="js/jquery-ui-1.13.2/jquery-ui.min.css">
<link rel="stylesheet" href="js/jqueryPlugin/customGalary.css">
<script src="js/jquery-3.7.1.min.js"></script>
<script src="js/jquery-ui-1.13.2/jquery-ui.min.js"></script>
<script src="js/jqueryPlugin/customGalary.js"></script>
</head>
<body>
<div id = "customGallery"></div>

<script>
$(function() {
    $('#customGallery').customGalary();
    $('#customGallery').customGalary('addImage', '/image/profile-man.webp');
});
</script>    
</body>
</html>

출력 결과:

jQuery 플러그인 개발하기: 나만의 jQuery 플러그인 만드는 가이드

플러그인 구조

init 메소드:

갤러리의 기본 구조를 설정한다. 이 메소드는 갤러리를 초기화할 때 호출되며, 갤러리에 필요한 HTML 요소들을 동적으로 추가하고, jQuery UI의 sortable 기능을 활성화하여 이미지의 순서를 변경할 수 있게 한다.

또한, 사진 추가 및 폴더 추가 버튼에 이벤트 리스너를 등록한다.

addImage 메소드:

이 메소드는 외부에서 이미지 URL을 받아 현재 활성화된 폴더에 이미지를 추가한다. 이는 다른 함수와 조합하여 이미지를 갤러리에 추가할 때 사용될 수 있다.

주요 기능

폴더 추가:

사용자가 ‘폴더 추가’ 버튼을 클릭하면 새로운 탭과 해당 탭에 매칭되는 갤러리 컨테이너가 추가된다.

각 탭 클릭 시, 해당 탭과 연결된 갤러리 컨테이너가 활성화 된다.

사진 추가:

‘사진 추가’ 버튼을 클릭하면 숨겨진 파일 입력 필드가 트리거 되고, 사용자가 선택한 이미지 파일들이 현재 활성화된 갤러리에 추가된다.

코드 해석

메서드 마지막에 return this; 가 있는 이유

return this; 가 메서드 마지막에 존재하는 이유는 메서드 체이닝을 위해서다.

메서드 체이닝

jQuery 는 메서드를 온점(.)으로 연결해서 연속 사용이 가능한 메서드 체이닝을 지원한다.

플러그인도 이를 지원하게 만들기 위해서 현재 실행 중인 jQuery 객체(this) 를 리턴하여 메서드 체이닝을 지원하게 해야한다.

메서드 호출 로직:

// 메서드 호출 로직
if (methods[method]) {
	return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
	return methods.init.apply(this, arguments);
} else {
	$.error('Method ' +  method + ' does not exist on jQuery.customGallery');
}

위의 코드를 보면 methods 라는 객체를 만들어서 init, addImage 키에 함수를 담았다. 그 후 메서드 값에 따라 지금 위의 호출 로직으로 사용하게 된다.

처음 아무것도 부여하지 않고 플러그인 메소드를 실행하게 되면 else if (typeof method === ‘object’ || !method) 조건 문을 타고 init 메서드가 실행 된다.

이 때, 안의 코드를 보면 여기서 블로그에서 다룬 적 없는 메서드 apply 메서드가 보인다.

apply 메서드

이 메서드는 함수를 호출하고 괄호 안에 this와 배열로 제공된 인자를 사용해 함수를 실행할 수 있게 만들어주는 메서드다. 그래서 func.apply(this, [배열]) 의 형태로 사용하게 된다.

Array.prototype.slice.call

해당 코드는 arguments 객체를 배열로 바꿔준다. 위의 코드에 $(‘#customGallery’).customGalary(‘addImage’, ‘/image/profile-man.webp’); 를 실행 할 때 arguments 를 console.log 로 출력해 보면 매개변수가 순서대로 담겨 있음을 알 수 있다.

그리고 그 뒤에 숫자 ‘1’ 로 인해 /image/profile-man.webp 가 불러와 져 배열에 담기게 된다.

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x
목차
위로 스크롤