jQuery wrapAll() 메서드가 필요한 이유 (photoswipe.js 예제)

에디터를 통해 이미지를 업로드 하면 img 태그가 생성되어 서버로 넘겨지는 내용 string 에 포함되어 넘겨집니다.

 

photoswipe 를 이용해 첨부된 이미지를 갤러리처럼 보여주고 싶은데 아래의 처리가 되어야 이용 가능합니다.

1) 이미지 터치(클릭)했을 때 보여줄 원본이미지 링크를 저장할  href 속성을 a 태그에 추가

2) 이미지 터치(클릭)했을 때 보여줄 원본이미지 사이즈를 저장할 data-size 속성을 a 태그에 추가

3) img 태그를 감싸는 figure 태그 추가

 

* photoswipe 플러그인은 기본적으로 href 와 data-size 속성을 img 부모 노드의 앵커(a) 태그에 추가합니다. 저의 경우 a 태그 없이 figure 태그안에 위의 두가지 속성을 추가해서 사용했습니다. 이러기 위해서는  아래의 펑션에서 linkEl 에 figureEl 의 첫번째 자식 태그가 아니라 figure 엘러먼트 자체가 되도록 해 주면 됩니다.

var initPhotoSwipeFromDOM = function(gallerySelector) {
.....
.....
  //linkEl = figureEl.children[0]; // <a> element
    linkEl = figureEl; // link use figure
}

 

생성된 img 태그를 어디서 조작할까 하다 서버측보다는 jQuery를 이용해서 결과 html 을 조작하는편이 낫겠다는 판단이 들었습니다. (PHP 통해서 서버측에서 처리하려면 DOMDocument 클래스를 이용하면 된다)

 

jQuery 메서드인 prepend() 또는 append() 의 경우 셀렉터 앞이나 뒤에 괄호 안에 넣은 태그가 삽입됩니다.

문제는 close 태그가 존재하는 태그를 사용한 경우 자동으로 닫혀버린다는 거죠.

 

<figure itemprop=”associatedMedia” itemscope=”” itemtype=”http://schema.org/ImageObject”></figure>

<img src=”http://hostname/path/file.ext” title=”1548235391-38.png” width=”” style=”height: 2568px;”>

 

 

이렇게 되면 photoswipe 에서 img 에 접근하기 어렵습니다. img 를 figure 태그 자식으로 넣기 위해서는 wrapAll 이라는 jQuery 메서드를 이용하면 된다는 군요.

 

[jQuery 작성]

$(window).load(function () {
    // 이미지 사이즈를 .ready() 안에서 받으려하면 값을 못받고 0으로 들어올 수 있으므로 .load() 안에서 처리
    $(".news_article img").each(function (index, item) {
        // img 가로와 세로 크기 확인 후 img 태그 안에 data-size 속성 추가해 주기 (원본사이즈 얻기 위해 width, height 이 아니라 naturalWidth, naturalHeight 을 사용)
        const imgsize = item.naturalWidth + 'x' + item.naturalHeight;
        const figureElem = '<figure href="' + item.src + '" data-size="' + imgsize + '">';

        $(this).wrapAll('<div>');
        $(this).wrapAll(figureElem);
    });
});


[변환된 결과 html]

<figure href=”http://hostname/path/originfile.ext” data-size=”800×1200″>

<img src=”http://hostname/path/file.ext”>

</figure>

위의 태그조합이 이미지 갯수 만큼 반복되겠죠.

 

 

 

 

[PHP 를 통해 서버측에서 처리할 경우]

$dom = new DOMDocument();
// saveHTML() 할 때 doctype 제거하기, $contents 변수에는 에디터로 넘어온 내용 html 이 text type 으로 저장되어 있습니다.
$dom->loadHTML($contents, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); 

foreach($dom->getElementsByTagName('img') as $img)
{

    $createDiv = $dom->createElement('div');
    $cloneDiv = $createDiv->cloneNode();
    $img->parentNode->replaceChild($cloneDiv, $img);
    $cloneDiv->appendChild($img);

    // 실무에서는 이미지 링크를 통해 가로값과 세로값을 얻어서 넣어줄 것 (여기는 간략히 800x1200 으로 넣음)
    $createFigure = $dom->createElement('figure');
    $createFigure->setAttribute("href", $img->getAttribute("src"));
    $createFigure->setAttribute("data-size", "800x1200");

    $clone = $createFigure->cloneNode();
    $img->parentNode->replaceChild($clone, $img);
    $img->setAttribute("data-size", "800x1200");
    $clone->appendChild($img);

    $img->parentNode->appendChild($dom->createElement('figcaption'));
};
$contents = $dom->saveHTML();

 

 

[참조 jQuery ]

https://stackoverflow.com/questions/48216205/avoid-browser-auto-close-tag-when-inserting-html-tag-with-javascript-before-firs

https://sometimes-n.tistory.com/21

 

[참조 PHP DOMDocument]

https://stackoverflow.com/questions/7433601/php-manipulating-html-from-string

https://stackoverflow.com/questions/18316527/php-dom-wrap-image-in-link-and-add-span-before-image-tag