본문 바로가기
css

처음부터 웹 앱 만들기 – 8부 6: AJAX 상호 작용성 추가

by code-box 2021. 10. 10.
반응형

이봐! 이 시리즈와 함께 제공되는 소스 코드를 더 이상 다운로드할 수 없다는 사실을 알려드립니다. 우리는 여전히 시리즈에서 얻을 수 있는 귀중한 정보가 있다고 생각하지만, 앞으로 10년 이상 걸릴 것이기 때문에 진보적인 웹 앱을 만들기 위해 현대적인 PHP 프레임워크(라라벨)나 심지어 자바스크립트 프레임워크(리액트 또는 Vue)도 고려해 볼 가치가 있다고 생각합니다.

우리 개발자는 이미 이 아이디어를 실제 응용 프로그램으로 바꾸는 엄청난 양의 작업을 수행했습니다. 이제 그를 위해 더 만들어 보자! 이 앱에서 가장 중요한 부분은 목록을 만들고 관리하는 것입니다. 우리는 처음부터 이것이 AJAX-Y 앱이 되기로 결정했습니다. 우리는 AJAX가 인기 있는 유행어이기 때문에 선택한 것이 아니라, 웹에서 반응성이 좋고 사용하기 쉬운 자연스러운 느낌의 응용 프로그램을 만들기 위한 최선의 길이라는 것을 알기 때문에 선택했습니다.

가장 큰 것: 목록 저장

AJAX를 사용하면 페이지 새로 고침 없이 서버에서 요청을 보내고 응답을 받을 수 있습니다. 앱에서 이 기능은 주로 저장을 위해 사용됩니다. 이러한 각각의 시간 동안 절약해야 할 것이 무엇인가를 생각해 봅시다.

  • 새 목록 항목이 추가되면 목록에 저장되어야 합니다.
  • 목록 항목이 삭제되면 목록에서 삭제되어야 합니다.
  • 항목 색상이 변경되면 새 색상을 저장해야 합니다.
  • 목록 항목이 완료로 표시되면 해당 상태를 저장해야 합니다.
  • 목록이 다시 정렬되면 새 주문을 저장해야 합니다.
  • 목록 항목의 텍스트가 변경되면 새 텍스트를 저장해야 합니다.그것은 많은 저축이 진행되고 있는 것이다. 우리 개발자는 그의 일을 도맡아 하고 있는데, 그 이유는 각각의 작은 이벤트마다 요청을 받고 처리할 수 있는 PHP 파일이 있어야 하기 때문이다. 다행히도 그는 이미 멋진 물체 지향적인 것들을 가지고 있고 확실히 이것을 다루기 위해 그것을 확장시킬 수 있다.AJAX의 절감 효과와 더불어 인터페이스를 시각적으로 구현해 줍니다. 이 작은 끌기 탭은 목록 항목을 위아래로 끌 수 있다고 말합니다. 우리는 그 일이 일어난 후에 목록을 저장할 것이라고 말하고 있다. 하지만 그게 어떻게 작동할까요? 걱정 마, 우리가 할 거야. 이제 필요한 모든 인터페이스인 자바스크립트에 대해 생각해 보겠습니다.
  • 인터페이스 자바스크립트
  •  
  • 끌기 탭을 클릭하고 끌면 목록 항목을 끌어다 놓고 순서를 변경할 수 있습니다.
  • 색상 탭을 클릭하면 목록 항목 색상이 일부 미리 정의된 선택 항목 간에 전환됩니다.
  • 체크 표시를 클릭하면 목록 항목이 지워지고 아래로 사라집니다.
  • 확인 슬라이드가 나오는 X를 클릭합니다. 다시 클릭하면 목록 항목이 휙 사라집니다.
  • 목록 항목을 두 번 클릭하면 텍스트가 편집을 위한 텍스트 입력으로 바뀝니다.
  • 아래에 큰 상자를 입력하고 추가를 클릭하면 목록 하단에 새 목록 항목이 추가됩니다.
     
    첫 번째 사항: 자바스크립트 파일 호출
    <script type='text/javascript' src='//ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js?ver=1.3.2'></script>
    <script type="text/javascript" src="js/jquery-ui-1.7.2.custom.min.js"></script>
    <script type="text/javascript" src="js/jquery.jeditable.mini.js"></script>
    <script type="text/javascript" src="js/lists.js"></script>
    <script type="text/javascript">
       initialize();
    </script>
  • 우리 사이트에는 자바스크립트가 전혀 필요한 페이지인 메인 리스트 페이지가 하나밖에 없습니다. 스크립트 파일을 인덱스.php 파일로 바로 드롭합니다. 사이트 헤더에 연결된 자바스크립트 파일을 자주 볼 수 있습니다. 지금은 이에 대해 길게 논의할 때가 아니지만, 페이지 끝에 나열하는 것이 일반적으로 성능 향상으로 간주되기 때문에 그럴 필요가 없다고 말해도 충분합니다. 그게 바로 우리가 여기서 할 일이야. index.php 파일에서 목록을 출력한 후 필요한 자바스크립트를 호출합니다.
  • 그리고 다시, 우리는 그 모든 것에 도달할 것입니다. 조금만 더 준비하면 돼!
  • jQuery 로드(더 나은 속도를 위해 Google에서 제공)
  • 사용자 지정 jQuery UI 라이브러리 로드(드래그글 가능)
  • jEdable 플러그인 로드(클릭하여 편집할 수 있음)
  • 사용자 지정 스크립트 로드
  • 초기화 함수 호출(DOM 준비 문과 같은 자체 킥스타터)

자바스크립트로 마크업 정리

 

사용자 정의 list.js 파일에는 여러 가지 다양한 기능이 생성될 것입니다. 첫 번째는 목록이 출력된 후 인덱스.php 파일에서 직접 호출되는 파일입니다.

function initialize() {

};

먼저 마크업에 직접 포함시키지 않고 자바스크립트로 공통 요소를 삽입하여 마크업을 정리할 것입니다. 우리가 그 목록을 조롱했을 때 그 표식이 어떻게 생겼는지 기억하세요?

<ul id="list">
     <li class="colorRed">
               <span>Walk the dog</span>
        <div class="draggertab tab"></div>
        <div class="colortab tab"></div>
        <div class="deletetab tab"></div>
        <div class="donetab tab"></div>
    </li>

    <!-- more list items -->

</ul>

그것의 대부분은 모든 목록 항목에서 중복된다. 우리가 원하는 것은 다음과 같습니다.

 
<ul id="list">
     <li class="colorRed">
               Walk the dog
                   </li>

    <!-- more list items -->

</ul>

모든 디브와 범위가 제거되었습니다. PHP가 데이터베이스를 읽고 목록을 출력할 때 해당 클래스 이름을 뱉어내기 때문에 목록 항목의 클래스 이름은 괜찮습니다.

어떻게 HTML을 추가할 수 있을까요? jQuery로 쉽습니다. 목록 항목을 대상으로 하고 wrapInner() 함수를 사용하여 각 내장을 포장하고 추가 디브와 add() 함수를 추가합니다.

function initialize() {

    // WRAP LIST TEXT IN A SPAN, AND APPLY FUNCTIONALITY TABS
    $("#list li")
      .wrapInner("<span>")
      .append("<div class='draggertab tab'></div><div class='colortab tab'></div></div><div class='deletetab tab'></div><div class='donetab tab'></div>");

};

스마트한 방법으로 새 기능 탭에 이벤트 바인딩
HTML 요소에 이벤트를 바인딩하는 것은 자바스크립트에서 매우 쉽습니다. 이런 식입니다.

 
$("li").click(function() {
     // do something
});

문제될 건 없지만, 목록 앱은 좀 특이한 상황입니다. 1) 이와 같은 이벤트를 바인딩할 때, 페이지 상의 모든 목록 항목에 대해 고유한 이벤트 핸들러를 생성하고, 각각 브라우저 메모리를 사용하며 2) DOM의 현재 상태에 대해 한 번만 이벤트 핸들러를 생성합니다. 너무 걱정하지 마세요. 새로운 목록 항목을 동적으로 삽입할 것이기 때문에 이런 식으로 이벤트를 구속하는 것은 이상적이지 않다는 것이 포인트입니다.

사용자가 새 목록 항목을 삽입하면 DOM에 바로 연결됩니다. 새로운 목록 항목은 다른 항목처럼 바인딩되지 않습니다. 즉, 모든 화려한 작은 탭이 제대로 작동하지 않습니다. 후후. 그 문제를 해결하기 위해 우리가 무엇을 할 수 있을까요? 페이지를 로드하고 새 목록 항목이 추가될 때 호출되는 모든 이벤트 바인딩 작업을 수행하는 새 함수를 만들 수 있습니다. 그것이 확실히 효과가 있을 것입니다. 하지만 jQuery는 그것보다 더 똑똑합니다. jQuery는 이 문제를 완전히 제거하는 live()라는 함수를 제공합니다.

$("li").live("click", function() {
     // do something
});

라이브() 함수로 이벤트를 바인딩하는 것은 1) 훨씬 효율적인 이벤트 핸들러를 하나만 만들고 2) 페이지에 추가된 새 항목은 동일한 핸들러에 의해 자동으로 바인딩되기 때문에 우리에겐 환상적입니다. 살인자.

 

작은 기능 탭에는 다음과 같이 사용할 것입니다.

$(".donetab").live("click", function() {
     // do stuff
});

$(".colortab").live("click", function(){
     // do stuff
});

$(".deletetab").live("click", function(){
     // do stuff
});

끌기 탭에는 클릭 이벤트가 없습니다. 실제로 jQuery UI의 끌기 가능 기능을 사용하여 끌기 이벤트가 있습니다. 어디 한번 봅시다.

목록을 끌어서 정렬하기

이러한 유용한 함수 집합을 만드는 jQuery UI 덕분에 메가입니다. 드래그 게이블 모듈은 정렬할 수 있는 것과 같은 목록을 작성하기에 완벽합니다. 우리는 부모[ul]를 대상으로 하고, 그것에 우리가 사용하고자 하는 "핸들"을 말하라. (목록 항목의 어느 부분을 클릭해서 끌어서 이동시킬 수 있는지) 또한 매개 변수 forcePlaceholderSize를 사용하여 목록 항목을 끌어다 놓을 때 일부 시각적 피드백(흰 블록 공간이 나타나 목록 항목이 "착륙할" 위치를 표시함)

 
$("#list").sortable({
      handle   : ".draggertab",
      update   : function(event, ui){

                // Developer, this function fires after a list sort, commence list saving!

      },
      forcePlaceholderSize: true
});

항목을 "완료"로 표시

사용자가 작은 체크 표시 탭을 클릭했을 때, 우리는 이미 두 가지를 하기로 결정했다. 목록 항목에 선을 그은 다음 전체 목록 항목을 페이드 아웃합니다. 그러나 항목이 이미 완료로 표시되어 있고 해당 탭을 클릭한 경우 수행할 작업을 고려해야 합니다. 흠, 이걸 뺐다가 다시 희미하게 만들 거야. 클릭이 발생하면 먼저 어떤 상태에 있는지 확인합니다.

$(".donetab").live("click", function() {

      if(!$(this).siblings('span').children('img.crossout').length) {
                $(this)
                    .parent()
                        .find("span")
                        .append("<img src='/images/crossout.png' class='crossout' />")
                        .find(".crossout")
                        .animate({
                                      width: "100%"
                })
                        .end()
                    .animate({
                                  opacity: "0.5"
                },
                                         "slow",
                                         "swing",
                                         function() {

                                  // DEVELOPER, the user has marked this item as done, commence saving!

                })
      }
      else
      {
                $(this)
                    .siblings('span')
                        .find('img.crossout')
                            .remove()
                            .end()
                        .animate({
                                      opacity : 1
                },
                                                 "slow",
                                                 "swing",
                                                 function() {

                                  // DEVELOPER, the user has UNmarked this item as done, commence saving!

                })

      }
});

컬러 사이클링

 

컬러 리스트의 이 "색깔 있는" 부분부터 시작하는 게 낫겠죠? CSS는 실제 색상을 적용하므로 자바스크립트로 수행할 작업은 클릭 시 해당 목록 항목에 적용된 클래스 이름을 순환하는 것입니다.

$(".colortab").live("click", function(){

      $(this).parent().nextColor();

      $.ajax({

                // DEVELOPER, the user has toggled the color on this list item, commence saving!

      });
});

nextColor() 기능은 내장 기능이 아니며, 사용자 지정으로 작성됩니다. 코드 명확성을 위해 추상화했습니다. 여기서 사용하는 방법은 "체인"의 일부로 작은 jQuery 플러그인을 만드는 것입니다. 문제 없어요.

jQuery.fn.nextColor = function() {

      var curColor = $(this).attr("class");

      if (curColor == "colorBlue") {
                $(this).removeClass("colorBlue").addClass("colorYellow").attr("color","2");
      } else if (curColor == "colorYellow") {
                $(this).removeClass("colorYellow").addClass("colorRed").attr("color","3");
      } else if (curColor == "colorRed") {
                $(this).removeClass("colorRed").addClass("colorGreen").attr("color","4");
      } else {
                $(this).removeClass("colorGreen").addClass("colorBlue").attr("color","1");
      };

};

기본적으로 목록 항목이 이미 어떤 색인지 확인하고 다음 색상으로 이동합니다. 목록 항목에서도 속성을 변경하는 방법에 주목하십시오. 색상은 XHMTL에서는 유효하지 않지만(HTML5에서는 괜찮습니다). 그것은 가격인상에 있지 않기 때문에 별로 중요하지 않다. 이걸 왜 쓰는 거죠? 우리가 그들 중 약 50%가 이것을 정말로 지능적으로 하기 때문입니다. 개발자가 이 목록 항목에 대한 색상 정보를 데이터베이스에 저장하려고 할 때 저장할 항목이 필요합니다. 이 시리즈의 2부로 돌아가서, 우리는 개발자가 이미 이것을 예상했고 그가 INT(정수)를 만든 listItemColor라는 컬러 필드를 만들었다는 것을 볼 수 있다. 그는 그것이 가볍고 쉽고 추상적이기 때문에 그것을 하는 가장 현명한 방법일 것이라고 생각했다. 1 = 파란색, 2 = 빨간색 등의 키가 무엇인지 나중에 결정할 수 있습니다. 데이터 자체는 빨간색인지 알 필요가 없습니다. DOM에 색을 나타내는 정수가 있으면 데이터베이스로 저장하기 쉽죠.

 

왜 이것이 50%만 똑똑한 것일까요? 음, 우리는 아마도 그 영리함을 학급 이름들 자체까지 확장시켜야 할 것이기 때문입니다. 우리는 색을 사용하고 있다.예를 들어, 색상 1이 더 말이 될 수 있을 때, 라인 아래쪽에 노란색을 라인업에서 제거하고 교체하기로 결정하면 노란색이 됩니다. 또는 사용자가 자신의 색상을 선언하도록 할 수도 있습니다.

목록 항목 삭제 중

우리의 작은 "X" 탭은 사용자가 목록 항목을 삭제할 수 있도록 하는 역할을 합니다. 하지만 우리는 실수로 뚱뚱한 손가락질을 하는 것에 대한 약간의 추가 보험을 갖고 싶다. 따라서 실제로 무언가를 삭제하려면 두 번의 클릭이 필요합니다. 일부 애플리케이션은 형편없는 "ARE YOU SURE" 모달 팝업 대화 상자에 의존합니다. 우리는 그것보다 조금 더 교활할 것입니다. X를 클릭하면 오른쪽에 인식에 대한 질문이 표시됩니다. 다시 클릭하면 삭제가 시작될 수 있습니다.

$(".deletetab").live("click", function(){

      var thiscache = $(this);

      if (thiscache.data("readyToDelete") == "go for it") {
                $.ajax({

                                // DEVELOPER, the user wants to delete this list item, commence deleting!

                                success: function(r){
                                                      thiscache
                                                                                  .parent()
                                                                  .hide("explode", 400, function(){$(this).remove()});

                                                      // Make sure to reorder list items after a delete!

                                }

                });
      }
      else
      {
                thiscache.animate({
                              width: "44px",
                              right: "-64px"
                }, 200)
                .data("readyToDelete", "go for it");
      }
});

우리는 일찍이 똑똑했고 작은 탭 그래픽은 모두 하나의 스프라이트 그래픽의 일부이기 때문에, 메시지를 표시하기 위해 탭의 너비를 늘리기만 하면 됩니다. 첫 번째 클릭 후, 우리는 "해보세요"라는 약간의 데이터(jQuery의 데이터 함수)를 목록 항목에 추가합니다. 두 번째 클릭 시 해당 테스트는 TRUE이며 해당 목록 항목을 삭제할 수 있습니다.

 

jQuery UI를 사용하고 있기 때문에 요소를 숨기기 위한 "탐색" 옵션을 사용하여 조금 더 재미있는 기능을 추가했습니다.

목록 항목을 편집하려면 클릭

목록 항목을 클릭해서 편집할 수 있도록 다른 사람의 어깨에 서서 jQuery 플러그인 jEdable을 사용합니다. 이 플러그인으로 필요한 것은 요소를 대상으로 지정하고 일부 매개 변수와 함께 편집 가능한() 함수를 사용하는 것입니다. 그러나 큰 경고에서는 표준 jQuery 이벤트가 아니기 때문에 이 플러그인과 함께 라이브() 기능을 사용할 수 없습니다.

라이브를 하기 전에, 아까 잠깐 얘기했던 것을 했어요. 우리는 모든 구속력을 갖는 함수를 호출했다. 이렇게 하면 AJAX 삽입 후뿐만 아니라 DOM ready에서도 호출할 수 있습니다. 이제 그 기술에 기대하겠습니다.

function bindAllTabs(editableTarget) {

      $(editableTarget).editable("/path/for/DEVELOPER/to/save.php", {
                id        : 'listItemID',
                indicator : 'Saving...',
                tooltip   : 'Double-click to edit...',
                event     : 'dblclick',
                submit    : 'Save',
                submitdata: {action : "update"}
      });

}
 

이러한 매개 변수를 사용하여 개발자에게 콜백 파일 경로에 필요한 정보를 제공합니다. 또한 편집할 목록 항목, 도구 추가 정보 및 저장 단추의 텍스트에 표시되는 내용을 두 번 클릭해야 한다고 선언합니다. 사용자 지정이 매우 용이합니다!

앞에서 목록 항목의 텍스트 주위에 삽입한 범위를 기억하십시오. 이제 우리는 그것을 이용하여 돈을 벌고 있다. 이 편집 가능한 기능을 바인딩할 때 해당 범위에 바인딩합니다. DOM이 준비되면 바로 연락드리겠습니다.

bindAllTabs("#list li span");

새로운 목록 항목을 추가할 때 이 기능이 다시 필요합니다.

새 목록 항목 추가

 

목록 앱의 기능의 핵심은 사람들이 새로운 목록 항목을 추가할 수 있도록 하는 것입니다. 여기에 대한 마크업은 이미 마련되어 있습니다. 따라서 이를 지원하는 자바스크립트를 살펴보겠습니다.

$('#add-new').submit(function(){

      var $whitelist = '<b><i><strong><em><a>',
                  forList = $("#current-list").val(),
                  newListItemText = strip_tags(cleanHREF($("#new-list-item-text").val()), $whitelist),
                  URLtext = escape(newListItemText),
                  newListItemRel = $('#list li').size()+1;

      if(newListItemText.length > 0) {
                $.ajax({

                                  // DEVELOPER, save new list item!

                              success: function(theResponse){
                                              $("#list").append("<li color='1' class='colorBlue' rel='"+newListItemRel+"' id='" + theResponse + "'><span id=""+theResponse+"listitem" title='Click to edit...'>" + newListItemText + "</span><div class='draggertab tab'></div><div class='colortab tab'></div><div class='deletetab tab'></div><div class='donetab tab'></div></li>");
                                              bindAllTabs("#list li[rel='"+newListItemRel+"'] span");
                                              $("#new-list-item-text").val("");
                              },
                              error: function(){
                                                // uh oh, didn't work. Error message?
                              }
                });
      } else {
                $("#new-list-item-text").val("");
      }
      return false; // prevent default form submission
});

참고: 여기에서 수행해야 하는 추가 보안에 대해 설명하는 시리즈의 마지막 부분에 대해 계속 시청하십시오. 사용자의 입력을 받아들일 때마다 스크럽해야 합니다. 이것도 예외는 아니다.

우리가 마지막으로 한 일은 제출 후 입력 필드를 비우는 것이었습니다. 이렇게 하면 목록 항목을 순서대로 추가하는 것이 매우 쉽고 자연스럽게 됩니다. 또한 새 목록 항목이 추가된 후 bindAllTabs 함수를 다시 호출했습니다. 그렇기 때문에 처음부터 이 기능을 추상화해서 새로운 목록 항목이 AJAX 스타일로 추가되었을 때 이 기능을 호출할 수 있습니다. 이렇게 하면 페이지를 새로 고치기 전에 새로 추가된 목록 항목에서 클릭해서 편집하는 기능이 작동합니다. 나머지 탭은 라이브() 바인딩으로 인해 자동으로 냉각됩니다.

다음 단계로 이동

 

다음에는 목록 상호 작용의 작동 방식에 대한 공백을 PHP/데이터베이스 측에서 채우기 위해 개발자에게 다시 전달하겠습니다. 그럼, 보안에 대한 얘기를 좀 끝내고 허술한 일은 마무리하도록 하죠.

댓글