我使用JavaScript构建的自定义图库过滤功能导致页面崩溃。我的代码的哪一部分可能引起了?

时间:2018-08-13 19:36:59

标签: javascript wordpress-rest-api

免责声明:我知道我的代码很糟糕。我对JavaScript还不是很有经验。

因此,我使用JavaScript和WP Rest API构建了具有过滤功能的图库。我终于可以正常工作了,但是在图库子类别之间单击几下后,页面开始变慢,最终崩溃。我想我正在做的是效率非常低下的工作,它会杀死页面,但是我不确定主要的罪魁祸首是什么。

除了我编写代码的其他明显问题之外,可能是什么原因导致的,并且有很好的方法来测试这样的性能问题吗?

(以下是此版本的有效版本的链接:http://victorysurfaces.x10host.com/gallery/

编辑:更新了代码,并修复了由灯箱代码添加的额外HTML DOM节点的问题。不幸的是,没有解决页面崩溃问题。

更新:我注意到有时单击一个子类别会发出更多的网络请求,但有时却没有。我觉得这很重要。

更新2:我认为这可能与我添加的事件监听器有关。由于我是动态添加子类别的,因此必须在加载事件监听器后再添加它们,但是上一次运行的事件监听器似乎仍然存在,因此事件监听器的数量在不断增加。我不知道该怎么办。

<div class="gallery">
  <div class="medium-wrapper">

    <div class="gallery__filters text-center">

      <div class="gallery__main-filters">

        <button class="category-filter main-category active" data-category="residential">Residential</button>

        <span>|</span>

        <button class="category-filter main-category" data-category="commercial">Commercial</button>

      </div>

      <div class="gallery__category-filters"></div>

    </div>

    <div class="gallery__images"></div>

  </div>

</div>

<script>

  /* I'm so sorry for this monstrosity. This was way more complicated than I thought and in the end I just wanted it to work */

  jQuery(document).ready(function($) {
    $('.main-category').on('click', function() {
      $('.main-category').removeClass('active');
      $(this).addClass('active');
    });
    initLightbox();
  });

  jQuery( function( $ ) {

    $.getJSON("/wp-json/wp/v2/gallery-categories", function( data ) {

      var currentMainCategory = $('.main-category.active').data('category');
      getSubCategories();

      var currentSubCategory = '';

      document.querySelectorAll('.main-category').forEach( function(trigger) {
          trigger.addEventListener('click', function() {
            resetCategories($(this).data('category')); }, false);
        });

      function getSubCategories() {
        var categoriesArray = [];
        var subCategories = data.map(function(category) {
          if( category.acf.gallery_section.trim().toLowerCase() === currentMainCategory) {

            var setCategory = "<button class='category-filter sub-category' data-category='" + category.acf.category_title + "'>" + category.acf.category_title + "</button>";

            categoriesArray.push(setCategory);
          }
        });
        $('.gallery__category-filters').html(categoriesArray);
        getPhotos();
      }

      function resetCategories(mainCategoryTitle) {
        currentMainCategory = '';
        currentSubCategory = '';
        $('.sub-category').removeClass('active');
        $('.gallery__category-filters').empty();
        currentMainCategory = mainCategoryTitle;
        getSubCategories();
      }

      function setSubCategory() {
        currentSubCategory = document.querySelector('.sub-category.active').dataset.category;
        getPhotos();
      }

      var galleryPhotos;

      function getPhotos(photos) {

        $('.gallery__images').empty();

        var mainCategory = currentMainCategory.trim().toLowerCase();
        if( (currentSubCategory !== undefined) && (currentSubCategory !== '' ) ) {
          var subCategory = currentSubCategory.trim().toLowerCase();
        }

        galleryPhotos = data.map(function(category) {

          if( category.acf.gallery_section.toLowerCase() === mainCategory ) {

            if( subCategory !== '' && subCategory !== undefined) {

              var categoryTitle = category.acf.category_title.toLowerCase().trim();

              if( categoryTitle === subCategory ) {

                var galleryCategory = category.acf.gallery_items;

                var categoryPhotos = galleryCategory.map(function(photo) {

                  var galleryPhoto = "<div class='gallery__item'><a class='lightbox-link' href=''><img class='full-width lightbox-target' src='" + photo.gallery_item_image.sizes.flexible + "' alt='" + photo.gallery_item_image.alt + "'></a></div>";

                  return galleryPhoto;
                });

                $('.gallery__images').append(categoryPhotos);
              }

            } else {

              var galleryCategory = category.acf.gallery_items;

              var categoryPhotos = galleryCategory.map(function(photo) {

                var galleryPhoto = "<div class='gallery__item'><a class='lightbox-link' href=''><img class='full-width lightbox-target' src='" + photo.gallery_item_image.sizes.flexible + "' alt='" + photo.gallery_item_image.alt + "'></a></div>";

                return galleryPhoto;
              });

              $('.gallery__images').append(categoryPhotos);
            }

          }

        });

        $('.sub-category').on('click', function() {
          $('.sub-category').removeClass('active');
          $(this).addClass('active');
          setSubCategory();
        });

        checkOrientation();
        handleLightboxUpdate();

      }

    });

  });

  function checkOrientation() {
    document.querySelectorAll('.lightbox-target').forEach(function(item) {
      var image = new Image();
      image.src = item.src;
      image.onload = function() {
        if(image.naturalHeight >= image.naturalWidth) {
          item.classList.add('portrait');
        }
      }
    });
  }

  function initLightbox() {
    var $overlay = jQuery('<div id="overlay"></div>');
    var $container = jQuery('<div class="lightbox"><a href="javascript:void(0)" class="close">&times;</a></div>');
    var $image;
    var $imageClone;

    jQuery('body').append($overlay);

    $overlay.click(function(){
      $overlay.hide();
    });

    $overlay.append($container);
  }

  function handleLightboxUpdate() {
    document.querySelectorAll('.lightbox-link').forEach( function(trigger) {
      trigger.addEventListener('click', function() {
        event.preventDefault();
        jQuery('.lightbox-image').remove();

        $image = jQuery(this).find('.lightbox-target');

        $imageClone = $image.clone();

        if($imageClone.hasClass('portrait')) {
          $imageClone.addClass('resize-lightbox');
        }

        jQuery('#overlay').show();
        //add image to overlay
        $imageClone.addClass('lightbox-image').appendTo('#overlay .lightbox');
      });
    });
  }

</script>

2 个答案:

答案 0 :(得分:1)

我不太在意代码,但是我可以告诉您这里发生了什么。单击“子类别”会使页面变慢,因为您向页面中添加了越来越多的HTML节点,直到它变得太多为止。具体来说,您每次点击都会以指数形式添加<div id="overlay">...</div>

  

有没有很好的方法来测试这样的性能问题?

我建议打开开发工具,看看那里发生了什么。如果不是添加更多的html,我将研究递归或创建太多对象的潜在问题。

答案 1 :(得分:0)

我知道了!我的setSubCategory()函数正在调用getPhotos(),而后者又正在调用setSubCategory(),依此类推。

原来,这是一个简单的永无止境的循环。脸部手掌。