# contextMenu를 사용한 우클릭 메뉴(서브 메뉴)화면 만들기

 

# 예시 화면 
(예제 소스가 필요하신 분은 아래에 풀 소스코드 남겨두었습니다.)

 

 

 


# 1. 준비물 - 필요한 jquery 파일들을 불러옵니다.

 <!-- jquery 불러오기 -->
    <script src="https://code.jquery.com/jquery-3.5.1.min.js"
        integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
    <!-- 우클릭시 contextmenu 만들기 -->
    <link rel="stylesheet"
        href="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.contextMenu.min.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.contextMenu.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.ui.position.js"></script>

# 2.  HTML BODY에 contextMenu 만들 div 만들기

<!-- 활성화 비활성화 조절 버튼 -->
    <button id="actvie">활성화</button>
    <button id="disable">비활성화</button>
    <!-- id 접근 요소 -->
    <div id="id_context_menu"
        style="position: relative; top:20px; left:100px; width:200px; height:200px; background-color: black;">
        asdsadasdasd
    </div>

    <!-- class 접근 요소 -->
    <div class="class_context_menu"
        style="position: relative; margin-top:10px; top:20px; left:100px; width:200px; height:200px; background-color: red;">
        asdsadasdasd
    </div>

# 3.  contextMenu 생성 및 옵션값 조절 

 

-  contextMenu dom 선택

 // 선택자 어떤 dom의 요소를 선택할 것인가?
 selector: '#id_context_menu',
 // 클래스 접근 방법
 selector: '.class_context_menu', 

- contextMenu 어느 위치에 생성할 것인가?

 // 어느 위치에 우클릭 menu를 생성할 것인가? , 없을 경우 클릭한 위치에서 생성
 appendTo: '.class_context_menu',

 

 

- contextMenu 항상 클릭시 callback을 받을 것인가?

callback: function (key, options) {
	// 메뉴 아이템을 클릭한 경우, callback 이벤트 동작
	console.log(arguments);
	console.log("Clicked on " + key + " on element id " + options.$trigger.attr("id") + " on element name " + options.$trigger.attr("name"));
	console.log("options", options);
	// return false; // 리턴값이 false인 경우, 메뉴가 사라지지 않음 
},

- contextMenu 위치에 마우스가 있는 경우, 특정 key를 누른 경우, context menu가 생성됨,

// 마우스가 생성하는 dom 위치에 있을 때, accesskey 누른 경우 메뉴 화면 생성
accesskey: 'a', 

- contextMenu 생성될 때, 트리거 요소 

  // 메뉴 생성 트리거 요소 [right , left , hover, touchstart, none]
  trigger: 'hover',  

- contextMenu 메뉴가 생성될때 요소

 

 items: {
                    "edit": { 
                            // 아이템 표현되는 이름 
                            name: "Edit", 
                            // fontawsome을 통한 아이콘 표현 
                            icon: "edit", 
                            // 버튼 클릭시 콜백 받는 부분
                            callback: (itemKey, opt, e) => {
                            console.log(arguments);
                            console.log("edit 아이템 클릭");
                        } 
                    },
                    "cut": { name: "Cut", icon: "cut" },
                    copy: { name: "Copy", icon: "copy" },
                    "paste": { name: "Paste", icon: "paste" },
                    "delete": { name: "Delete", icon: "delete" },
                    "sep1": "---------", // 라인 만들기
                    // 아이템 안에 아이템을 만드는 경우
                    "fold1": {
                        "name": "Sub group",
                        "items": {
                            "fold1-key1": { "name": "Foo bar" },
                            "fold2": {
                                "name": "Sub group 2",
                                "items": {
                                    "fold2-key1": { "name": "alpha" },
                                    "fold2-key2": { "name": "bravo" },
                                    "fold2-key3": { "name": "charlie" }
                                }
                            },
                            "fold1-key3": { "name": "delta" }
                        }
                    },
                    "sep2": "---------", // 라인 만들기
                    "quit": {
                        name: "Quit", icon: function () {
                            return 'context-menu-icon context-menu-icon-quit';
                        }
                    }
                },

- contextMenu 메뉴가 생성될때 요소

  - 메뉴가 생성, 활성화, 사라질 때, 이벤트 발생 

events: {
    show: function (options) {
        // S.fn.init [div#id_context_menu] 메뉴화면 
        console.log(this);

        // 메뉴 생성 시 클래스 추가 
        this.addClass('currently-showing-menu');
        var open = confirm('메뉴 화면을 생성하시겠습니까?' + "\n dom 선택자 : " + options.selector + '?');
        return open === true ? true : false;
    },
    hide: function (options) {
        // 메뉴 화면이 사라질떄
        var hide = confirm('메뉴 화면을 숨기겠습니까?' + "\n dom 선택자 : " + options.selector + '?');
        return hide === true ? true : false;
    },
    activated: function (options) {
        // 메뉴화면이 활성화 되었을 때 
        var activated = confirm('메뉴 활성화 하겠습니까?' + "\n dom 선택자 : " + options.selector + '?');
        return activated === true ? true : false;
    }
}

 

 

# 4.  contextMenu 활성화 비활성화 버튼 요소

$('#actvie').on('click', function (e) {
    console.log(this);
    var $trigger = $('#id_context_menu');
    $trigger.contextMenu(true);
});

$('#disable').on('click', function (e) {
    console.log(this);
    var $trigger = $('#id_context_menu');
    $trigger.contextMenu(false);
});

 

 


# 5.  전체 테스트 코드 

더보기

<!DOCTYPE html>

<html lang="ko">

 

<head>

    <meta charset="UTF-8">

    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Context Menu 만들기</title>

 

    <!-- jquery 불러오기 -->

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

        integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>

    <!-- 우클릭시 contextmenu 만들기 -->

    <link rel="stylesheet"

        href="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.contextMenu.min.css">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.contextMenu.min.js"></script>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-contextmenu/2.7.1/jquery.ui.position.js"></script>

</head>

 

<body>

    <!-- 활성화 비활성화 조절 버튼 -->

    <button id="actvie">활성화</button>

    <button id="disable">비활성화</button>

    <!-- id 접근 요소 -->

    <div id="id_context_menu"

        style="position: relative; top:20px; left:100px; width:200px; height:200px; background-color: black;">

        asdsadasdasd

    </div>

 

    <!-- class 접근 요소 -->

    <div class="class_context_menu"

        style="position: relative; margin-top:10px; top:20px; left:100px; width:200px; height:200px; background-color: red;">

        asdsadasdasd

    </div>

    <script>

        $(function () {

            $.contextMenu({

                // 선택자 어떤 dom의 요소를 선택할 것인가?

                selector: '#id_context_menu',

                // 클래스 접근 방법

                // selector: '.class_context_menu', 

                // 어느 위치에 우클릭 menu를 생성할 것인가? , 없을 경우 클릭한 위치에서 생성

                appendTo: '.class_context_menu',

                // 마우스가 생성하는 dom 위치에 있을 때, accesskey 누른 경우 메뉴 화면 생성

                //accesskey: 'a', 

                callback: function (key, options) {

                    // 메뉴 아이템을 클릭한 경우, callback 이벤트 동작

                    console.log(arguments);

                    console.log("Clicked on " + key + " on element id " + options.$trigger.attr("id"+ " on element name " + options.$trigger.attr("name"));

                    console.log("options", options);

                    // return false; // 리턴값이 false인 경우, 메뉴가 사라지지 않음 

                },

                // 메뉴 생성 트리거 요소 [right , left , hover, touchstart, none]

                trigger: 'hover',

                items: {

                    "edit": {

                        // 아이템 표현되는 이름 

                        name: "Edit",

                        // fontawsome을 통한 아이콘 표현 

                        icon: "edit",

                        // 버튼 클릭시 콜백 받는 부분

                        callback: (itemKey, opt, e) => {

                            console.log(arguments);

                            console.log("edit 아이템 클릭");

                        }

                    },

                    "cut": { name: "Cut"icon: "cut" },

                    copy: { name: "Copy"icon: "copy" },

                    "paste": { name: "Paste"icon: "paste" },

                    "delete": { name: "Delete"icon: "delete" },

                    "sep1": "---------",

                    // 아이템 안에 아이템을 만드는 경우

                    "fold1": {

                        "name": "Sub group",

                        "items": {

                            "fold1-key1": { "name": "Foo bar" },

                            "fold2": {

                                "name": "Sub group 2",

                                "items": {

                                    "fold2-key1": { "name": "alpha" },

                                    "fold2-key2": { "name": "bravo" },

                                    "fold2-key3": { "name": "charlie" }

                                }

                            },

                            "fold1-key3": { "name": "delta" }

                        }

                    },

                    "sep2": "---------",

                    "quit": {

                        name: "Quit"icon: function () {

                            return 'context-menu-icon context-menu-icon-quit';

                        }

                    }

                },

                events: {

                    show: function (options) {

                        // S.fn.init [div#id_context_menu] 메뉴화면 

                        console.log(this);

 

                        // 메뉴 생성 시 클래스 추가 

                        this.addClass('currently-showing-menu');

                        var open = confirm('메뉴 화면을 생성하시겠습니까?' + "\n dom 선택자 : " + options.selector + '?');

                        return open === true ? true : false;

                    },

                    hide: function (options) {

                        // 메뉴 화면이 사라질떄

                        var hide = confirm('메뉴 화면을 숨기겠습니까?' + "\n dom 선택자 : " + options.selector + '?');

                        return hide === true ? true : false;

                    },

                    activated: function (options) {

                        // 메뉴화면이 활성화 되었을 때 

                        var activated = confirm('메뉴 활성화 하겠습니까?' + "\n dom 선택자 : " + options.selector + '?');

                        return activated === true ? true : false;

                    }

                }

            });

 

            $('#actvie').on('click'function (e) {

                console.log(this);

                var $trigger = $('#id_context_menu');

                $trigger.contextMenu(true);

            });

 

            $('#disable').on('click'function (e) {

                console.log(this);

                var $trigger = $('#id_context_menu');

                $trigger.contextMenu(false);

            });

 

        });

    </script>

</body>

 

</html>

블로그 이미지

미나미나미

,

# Array.From 사용법 / Array 복사 방법

  -  사용법 : Array.from(arrayLike[, mapFn[, thisArg]])

  -  예시 : Array.from( 복사할 array , 복사하면서 수행할 function)

  -  주의 사항 : Array 복사 얇은(Shallow) 복사로 됨.

 

# 예시 

// Array 얕은 복사 방법
var a = [1, 2, 3];
console.log("a" , a)
// Array A를 복사
var b = Array.from(a);
console.log("b" , b)

// Array A를 복사하면 +1 증가
var c = Array.from(a, function (x) {
console.log("c" , c)
    return x + 1;
});

// Array A를 복사하면 제곱하기
var d = Array.from(a, x => x * x);
console.log("d" , d)

// 부록 : es6 Array 복사
var e = [...a];
console.log("e" , e)

// Array 안에 Object 형식도 복사 가능
var f = Array.from([{ a : 1 , b: 2}]);
console.log("f" , f)

// 부록 : 깊은 복사 방법 
var deep_copy = JSON.parse(JSON.stringify(a));
console.log("deep_copy" , deep_copy)

 

# 결과화면 

블로그 이미지

미나미나미

,

# [JavaScript] ES6 Getter Setter 사용법

 - JavsScript ES6의 Getter와 Setter를 사용한 데이터 초기화 및 출력 


var student = {
  fullInfo : "",
  name : "",
  grade : "",
  number : "",
  // student 정보 출력
  get getStudent(){
    return "name = >" + this.name + "grade = >" + this.grade + "number = >" + this.number;
  },
  // Property 'setPerson' implicitly has type 'any', because its set accessor lacks a parameter type annotation.
  // setter에 매개변수가 하나만 들어갈 수 있다.
  set setStudent(data){
    this.fullInfo = data;
    data = data.split(" ");
    this.name = data[0];
    this.grade = data[1];
    this.number = data[2];
  }
}

// setter를 사용한 초기화
student.setStudent = "김구 3학년 11번";
// ES6 객체 복사
var stu1 = {...student};
console.log(stu1.getStudent);

// setter를 사용한 초기화
student.setStudent = "포그바 1학년 1번";
// ES6 객체 복사
var stu2 = {...student};
console.log(stu2.getStudent);

// 객체 복사시 setter는 사용할 수 없게됨.
var stu3 = {...student};
console.log(stu3);

# 결과화면 

블로그 이미지

미나미나미

,

# [JavaScript] ES6 클래스(Class) extends , super 사용

 

1. Parent가 될 클래스

// extends할 클래스 
class Car {
  constructor(name = "없음", passengers = "0", price = "0") {
    this.name = name;
    this.passengers = passengers;
    this.price = price;
  }
  carPrint() {
    return (
      "name => " +
      this.name +
      "/ passengers => " +
      this.passengers +
      "/ price => " +
      this.price
    );
  }
  // Car 클래스의 static 메소드
  static description() {
    console.log("static carPrint 스태틱 메소드 출력");
  }
}

2.  Child가 될 클래스

// Car를 상속 받음 
// 
class Sonata extends Car{
// "var Sonata = class extends Car"와 "class Sonata extends Car" 동일함
    constructor(name, passengers, price, seatFacility){
        // Car 클래스에 변수값 전달
        super(name, passengers, price);
        // 현재 클래스에 할당 
        this.seatFacility = seatFacility; 
    }

    // 내용 정보찍기 
    sonataPrint(){
        // super 키워드를 통한 부모의 메소드 접근 
        return super.carPrint() + "/ seatFacility => " + this.seatFacility; 
    }

    // Sonata 클래스의 static 메소드
    static description(){
        console.log("이 클래스는 소나타 클래스입니다");
    }
}

 


3.  실행하기

var sonata = new Sonata("소나타" , "4" , "1000" , "열시트");
console.log("sonata.carPrint =>" , sonata.carPrint());
console.log("sonata.sonataPrint =>" , sonata.sonataPrint());

// VM67:47 sonata.carPrint => name => 소나타/ passengers => 4/ price => 1000
// VM67:48 sonata.sonataPrint => name => 소나타/ passengers => 4/ price => 1000/ seatFacility => 열시트

 


4,결과화면

 


 

블로그 이미지

미나미나미

,

# Class 생성 및 인스턴스 생성 

class Car {
    constructor(name, passengers, price) {
        this.name = name;
        this.passengers = passengers;
        this.price = price;
    }

    print() {
        console.log(
            'name => ' + this.name, 
            '/ passengers => ' + this.passengers, 
            '/ price => ' + this.price
        );
    }
}

var sonata = new Car('sonata' , '4' , 10000);
sonata.print();
// name = >sonata / passengers = >4 / price = >10000

# 결과 화면 

 


# Class  인스턴스  생성시 초기화

class Car {
   // 인스턴스 생성시, 초기화 값 지정
    constructor(name='없음', passengers='0', price='0') {
        this.name = name;
        this.passengers = passengers;
        this.price = price;
    }

    print() {
        console.log(
            'name => ' + this.name, 
            '/ passengers => ' + this.passengers, 
            '/ price => ' + this.price
        );
    }
}

var sonata = new Car('sonata' , '4' , 10000);
sonata.print();
//name = >sonata / passengers = >4 / price = >10000

// 인스턴스 생성시, 인자값 초기화 지정값 사용
var notCar = new Car();
notCar.print();

 

# 결과 화면

블로그 이미지

미나미나미

,

call 함수는 결국 this를 조작하는 거 같다. 그러하다...


# 문서 call 함수 정의

- call() 메소드는 주어진 this 값 및 각각 전달된 인수와 함께 함수를 호출합니다

 

# 문서 call 함수 설명

- call()은 이미 할당되어있는 다른 객체의 함수/메소드를 호출하는 해당 객체에 재할당할때 사용됩니다. this는 현재 객체(호출하는 객체)를 참조합니다. 메소드를 한번 작성하면 새 객체를 위한 메소드를 재작성할 필요 없이 call()을 이용해 다른 객체에 상속할 수 있습니다.

 

솔직히 잘모르겠다. 그래서 예시를 만들어보았다.

 

# developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Function/call

 

Function.prototype.call()

call() 메소드는 주어진 this 값 및 각각 전달된 인수와 함께 함수를 호출합니다.

developer.mozilla.org

구문

func.call(thisArg[, arg1[, arg2[, ...]]])

매개변수

thisArg func 호출에 제공되는 this의 값.

this는 메소드에 의해 보이는 실제값이 아닐 수 있음을 주의하세요: 메소드가 비엄격 모드 코드 내 함수인 경우, nullundefined는 전역 객체로 대체되고 원시값은 객체로 변환됩니다.

arg1, arg2, ...

객체를 위한 인수.

반환값(Return Value)

this 와 arguments 를 매개로 호출된 함수의 반환값


#예시

서버 3대 ServerA, ServerB, ServerC의 정보를 담은 객체와 출력하는 함수 만들기

var serverInfoPrint = {
  ip: "없음",
  address: "없음",
  name: "없음",
  print: function (conIp, conName) {
    return (
      "서버 정보 : " +
      this.ip +
      " , " +
      this.address +
      " , " +
      this.name +
      "/ 접속 정보 :" +
      conIp +
      " , " +
      conName
    );
  },
};

var serverA = {
  ip: "10.10.10.10",
  address: "서울 B구역",
  name: "개발 서버",
};

var serverB = {
  ip: "10.124.140.111",
  address: "부산 C구역",
  name: "백업 서버",
};

var serverC = {
  ip: "미할당",
  address: "대구 Q구역",
  name: "가상 서버",
};

// serverInfoPrint의 this를 사용하는 경우, 인자값을 안주는 경우
console.log(serverInfoPrint.print());
// serverInfoPrint의 this를 사용하는 경우, 인자값을 주는 경우
console.log(serverInfoPrint.print("0.0.0.0" , "테스트계정"));

// serverA의 this를 사용하는 경우, 인자값을 안주는 경우
console.log(serverInfoPrint.print.call(serverA));
// serverA의 this를 사용하는 경우, 인자값을 주는 경우
console.log(serverInfoPrint.print.call(serverA, "10.200.10.11", "테스트 계정"));
// serverA의 this를 사용하는 경우, 인자값을 주는 경우
console.log(serverInfoPrint.print.call(serverA, "0.0.0.0", "마스터 계정"));

// serverB의 this를 사용하는 경우, 인자값을 주는 경우
console.log(serverInfoPrint.print.call(serverB, "210.120.33.111", "유저 계정"));
// serverC의 this를 사용하는 경우, 인자값을 주는 경우
console.log(serverInfoPrint.print.call(serverC, "123.0.13.231", "테스트 계정"));

/**
서버 정보 : 없음 , 없음 , 없음/ 접속 정보 :undefined , undefined
서버 정보 : 없음 , 없음 , 없음/ 접속 정보 :0.0.0.0 , 테스트계정
서버 정보 : 10.10.10.10 , 서울 B구역 , 개발 서버/ 접속 정보 :undefined , undefined
서버 정보 : 10.10.10.10 , 서울 B구역 , 개발 서버/ 접속 정보 :10.200.10.11 , 테스트 계정
서버 정보 : 10.10.10.10 , 서울 B구역 , 개발 서버/ 접속 정보 :0.0.0.0 , 마스터 계정
서버 정보 : 10.124.140.111 , 부산 C구역 , 백업 서버/ 접속 정보 :210.120.33.111 , 유저 계정
서버 정보 : 미할당 , 대구 Q구역 , 가상 서버/ 접속 정보 :123.0.13.231 , 테스트 계정
 */

 

 

# 결과화면

 

블로그 이미지

미나미나미

,

[javascript] arguments 인자값의 변화

 

 

 - 함수 인자값을 함수 실행 중 변경시 변경된다.

function argumentTest(a, b) {
  console.log("a+b", a + b);
  b = 10;
  console.log(arguments);
  console.log("a+b", a + b);
}

function argumentTest2(a, b) {
  console.log(arguments);
  b = 10;
}

argumentTest(1, 2);
argumentTest(1, 10);

/**
     a+b 3
    VM854:4 Arguments(2) [1, 10, callee: ƒ, Symbol(Symbol.iterator): ƒ]
    VM854:5 a+b 11
    VM854:2 a+b 11
    VM854:4 Arguments(2) [1, 10, callee: ƒ, Symbol(Symbol.iterator): ƒ]
    VM854:5 a+b 11
 */
 
 
 // ------------------------------------------
 // object는 값에 변화가 없음
 
 var o = { 0: 1, 1: 2 };
console.log(o);
// VM888:2 {0: 1, 1: 2}

var a = o[0],
  b = o[1];

b = 10;
console.log(o);
// VM888:7 {0: 1, 1: 2}

 // ------------------------------------------
블로그 이미지

미나미나미

,

# new Function 함수 

 

 - 런타임상에 문자열을 사용해 함수를 만들 수 있다는 장점.

 - 함수의 인자값을 서버로 부터 받아서 동적으로 함수를 생성할 때, 유용하게 사용 가능.

 - 단, new Function의 생성은 오직 전역 변수에만 접근 가능 

 

 

# newFunction 함수 문법

var function = new Function([arg1, arg2 ... argN] , functionBody);

# new Function 예시 

   

- sum 함수

 var sum = new Function('a' , 'b' , 'return a + b;');     
 var sum = new Function('a , b' , 'return a + b;');
 sum(1,2); //3 

  - alert 띄우기

var alertFunc  = new Function( 'v', 'alert(v)'));

   - 화살표 함수 생성하기 

function arrowFuncMake(str) {
  var splitted = str.split("=>");
  console.log(splitted);
  return new Function(splitted[0], "return (" + splitted[1] + ");");
}

arrowFuncMake('n => n * 10')(10);
// 100
arrowFuncMake('n => n * 10')(20);
// 200
arrowFuncMake('n => n * 10')(30);
// 300
arrowFuncMake('a ,b => a + b')(10,20);
// 30

 

 


# new Fucntion은 전역 변수만 접근 가능

   var value = "1111";     
   function getFunc() {         
   		var value = "test";         
        var func = new Function('alert(value)');         
        return func;
   }
   getFunc()(); 
   // alert시 1111이 띄워짐

 

블로그 이미지

미나미나미

,