【问题标题】:jQuery Isotope filteringjQuery 同位素过滤
【发布时间】:2014-09-10 17:03:20
【问题描述】:

我有一个 Joomla 网站,其中包含一个购买的模板,其中包含基于同位素和 touchtouch 的投资组合 我遇到了与另一篇文章中描述的相同的问题 - 唯一的区别是他们使用 fancybox 而我的模板使用 touchtouch :jQuery Isotope filtering with Fancybox

这是问题的描述:

作品集包含一个缩略图库。 您可以单击缩略图,然后使用 touchtouch 插件循环浏览图像 现在的问题是,当画廊被过滤时,touchtouch 插件仍然循环遍历所有图像。即使是那些在应用过滤器时没有出现的人。

我试图改变fancybox-post的解决方案,但我仍然不知道如何解决这个问题。

我想应该修改gallery.php中的以下脚本:

<script type="text/javascript">
  jQuery(document).ready(function() {
  (function($){ 
   $(window).load(function(){

    var $container = $('#isotopeContainer');

    // filter items when filter link is clicked
    $('#filters a').click(function(){
      var selector = $(this).attr('data-filter');
      $container.isotope({ filter: selector });
      return false;
    });

    var $optionSets = $('#filters li'),
        $optionLinks = $optionSets.find('a');

        $optionLinks.click(function(){
            var $this = $(this);
            // don't proceed if already selected
            if ( $this.hasClass('selected') ) {
              return false;
            }
            var $optionSet = $this.parents('#filters');
            $optionSet.find('.selected').removeClass('selected');
            $this.addClass('selected');

            // make option object dynamically, i.e. { filter: '.my-filter-class' }
            var options = {},
                key = $optionSet.attr('data-option-key'),
                value = $this.attr('data-option-value');
            // parse 'false' as false boolean
            value = value === 'false' ? false : value;
            options[ key ] = value;
            if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
              // changes in layout modes need extra logic
              changeLayoutMode( $this, options )
            } else {
              // otherwise, apply new options
              $container.isotope( options );
            }

            return false;
        });
   });
})(jQuery);
}); 
</script>

你有什么想法吗?

【问题讨论】:

    标签: jquery joomla jquery-isotope


    【解决方案1】:

    我找到了一种方法来制作包含帐户过滤器的工作导航,但现在我遇到的问题是,当投资组合第一次出现时 - 在任何过滤之前 - touchtouch 插件不会触发。

    这里我向你展示所涉及的代码:

    Gallery.php(模板覆盖的一部分):

    <?php if($this->params->get('show_filter')): ?>
    
    <script type="text/javascript">
      jQuery(document).ready(function() {
      (function($){ 
       $(window).load(function(){
    
        var $container = $('#isotopeContainer');
    
        // filter items when filter link is clicked
        $('#filters a').click(function(){
          var selector = $(this).attr('data-filter');
          $container.isotope({ filter: selector });
          if(selector == "*"){
            console.log(selector);
          } else { 
            $(".touchGalleryLink").removeClass("MyCat");
            $(".touchGalleryLink").each(function() {
                var tmpvar = $(this).parent().parent().attr('class').split(" ",2);
                if(tmpvar[1] == selector.substr(1)){
                  $(this).addClass("MyCat");
                }
            });
          }
          jQuery('a.touchGalleryLink.MyCat').touchTouch();
          return false;
        });
    ...
    

    在 script.js 文件中我需要注释掉一行:

    jQuery(document).ready(function() {
      ...
      // Initialize the gallery touch
      //jQuery('a.touchGalleryLink').touchTouch();
      ...
    

    以下是 touch.galery.js 文件的一部分:

    (function($){
    
    /* Private variables */
    
    var overlay = $('<div id="galleryOverlay">'),
    slider = $('<div id="gallerySlider">'),
    prevArrow = $('<a id="prevArrow"></a>'),
    nextArrow = $('<a id="nextArrow"></a>'),
    overlayVisible = false;
    
    /* Creating the plugin */
    
    $.fn.touchTouch = function(){
    
      var placeholders = $([]),
      index = 0,
      items = this;
      // Appending the markup to the page
      overlay.hide().appendTo('body');
      slider.appendTo(overlay);
    
      // Creating a placeholder for each image
      items.each(function(){
        placeholders = placeholders.add($('<div class="placeholder">'));
    });
    
    ...
    

    如果有人能帮助我找到一种方法让它第一次也能正常工作,那就太好了......

    【讨论】:

      【解决方案2】:

      此时我几乎得到了我想要的,但我的代码中有一个错误,我看不出它是从哪里来的。

      我选择的解决方案是引入一个新的 MyCat 类,我的修改试图确保该类仅在图像对应于当前类别并且 jquery 考虑该类时才存在。

      这里是这个错误的描述: 当我首先过滤具有 x 个图像的类别时,会发生这种情况,通过它们导航并在最后一个图像上退出导航。 然后我过滤一个少于 x 个图像的类别,比如说 y。 现在,当我单击图像时,我没有得到图像,或者在某些情况下图像不好),我需要单击上一个图像链接(y-x)次才能获得正确的图像。请注意,此时系统已稳定,因为现在下一个图像链接不可用。

      如果不让我知道,我希望我的描述是可以理解的。 我不知道是否有更优雅的方法来执行此操作,但由于它几乎可以工作,如果您看到可以解释该错误的内容,请告诉我。

      这是我修改的两个重要文件的代码:

      gallery.php:

      ...
      <?php if((!empty($this->lead_items) || (!empty($this->intro_items))) &&  $this->params->get('show_filter')): ?>
            <div class="filters">
      
      
              <ul id="filters" class="unstyled">
                <li><a href="#" data-filter="*" class="selected"><?php echo JText::_('TPL_COM_CONTENT_GALLERY_FILTER_SHOW_ALL'); ?></a></li>
                <?php 
                  foreach ($galleryCategories as $key => $value) : 
                ?>
                <li><a class="" href="#"data-filter=".<?php echo special_chars_replace($value); ?>"><?php echo ucwords(str_replace("_"," ",$value)); ?></a></li>
                <?php endforeach; ?>
              </ul>
      
              <div class="clearfix"></div>
            </div>
      <?php endif; ?>
      ...
      <div class="row-fluid">
        <ul id="isotopeContainer" class="gallery items-row cols-<?php echo (int) $this->columns;?>">
          <?php 
              $valgtr = array();
              $keysgtr = array_keys($this->intro_items);
              shuffle($keysgtr);
              foreach($keysgtr as $keygtr) $valgtr[] = $this->intro_items[$keygtr];
      
              foreach ($valgtr as $key => &$item) : 
          ?>
          <?php
            $key = ($key - $leadingcount) + 1;
            $rowcount = (((int) $key - 1) % (int) $this->columns) + 1;
      
            if ($rowcount == 1) : ?>    
            <?php endif; ?>
      
              <li class="gallery-item <?php echo special_chars_replace(strtolower(str_replace(" ","_",$item->category_title))); ?>">
                  <?php
                  $this->item = &$item;
                  echo $this->loadTemplate('item');
      ... 
      <script type="text/javascript">
        jQuery(document).ready(function() {
        (function($){ 
         $(window).load(function(){
          var $cols = <?php echo $this->columns; ?>;
          var $container = $('#isotopeContainer');
      
          $item = $('.gallery-item')
          $item.outerWidth(Math.floor($container.width() / $cols));
      
          $container.isotope({
            animationEngine: 'best-available',
            animationOptions: {
                queue: false,
                duration: 800
              },
              containerClass : 'isotope',
              containerStyle: {
                position: 'relative',
                overflow: 'hidden'
              },
              hiddenClass : 'isotope-hidden',
              itemClass : 'isotope-item',
              resizable: true,
              resizesContainer : true,
              transformsEnabled: !$.browser.opera // disable transforms in Opera
          });
      
          if($container.width() <= '767'){
            $item.outerWidth($container.width());
            $item.addClass('straightDown');
            $container.isotope({
              layoutMode: 'straightDown'
            });
          } else {
            $item.removeClass('straightDown');
            $container.isotope({
              layoutMode: 'fitRows'
            });
          }
      
          $(window).resize(function(){
            $item.outerWidth(Math.floor($container.width() / $cols));
            if($container.width() <= '767'){
              $item.outerWidth($container.width());
              $item.addClass('straightDown');
              $container.isotope({
                layoutMode: 'straightDown'
              });
            } else {
              $item.outerWidth(Math.floor($container.width() / $cols));
              $item.removeClass('straightDown');
              $container.isotope({
                layoutMode: 'fitRows'
              });
            }
          });
        });
      })(jQuery);
      }); 
      </script>
      
      <?php if($this->params->get('show_filter')): ?>
      
      <script type="text/javascript">
        jQuery(document).ready(function() {
        (function($){ 
         $(window).load(function(){
          var $container = $('#isotopeContainer');
      
          // filter items when filter link is clicked
          $('#filters a').click(function(){
            var selector = $(this).attr('data-filter');
            $container.isotope({ filter: selector });
            if(selector == "*"){
              $(".touchGalleryLink").addClass("MyCat");
            } else { 
              $(".touchGalleryLink").removeClass("MyCat");
              $(".touchGalleryLink").each(function() {
                var tmpvar = $(this).parent().parent().attr('class').split(" ",2);
                if(tmpvar[1] == selector.substr(1)){
                  $(this).addClass("MyCat");
              }
            });
          }
          jQuery('a.touchGalleryLink.MyCat').touchTouch();
          return false;
        });
        $( "#filters a:first" ).trigger( "click" );
      
        var $optionSets = $('#filters li'),
            $optionLinks = $optionSets.find('a');
      
            $optionLinks.click(function(){
                var $this = $(this);
                // don't proceed if already selected
                if ( $this.hasClass('selected') ) {
                  return false;
                }
                var $optionSet = $this.parents('#filters');
                $optionSet.find('.selected').removeClass('selected');
                $this.addClass('selected');
      
                // make option object dynamically, i.e. { filter: '.my-filter-class' }
                var options = {},
                    key = $optionSet.attr('data-option-key'),
                    value = $this.attr('data-option-value');
                // parse 'false' as false boolean
                value = value === 'false' ? false : value;
                options[ key ] = value;
                if ( key === 'layoutMode' && typeof changeLayoutMode === 'function' ) {
                  // changes in layout modes need extra logic
                  changeLayoutMode( $this, options )
                } else {
                  // otherwise, apply new options
                  $container.isotope( options );
                }
      
                return false;
            });
        });
      })(jQuery);
      }); 
      </script>
      
      <?php endif; ?>
      

      touch.gallery.js:

      (function($){
      
        /* Private variables */
        var overlay = $('<div id="galleryOverlay">'),
          slider = $('<div id="gallerySlider">'),
          prevArrow = $('<a id="prevArrow"></a>'),
          nextArrow = $('<a id="nextArrow"></a>'),
          overlayVisible = false;
      
      
      /* Creating the plugin */
      
      $.fn.touchTouch = function(){
      
          var placeholders = $([]),
              index = 0,
              items = this;
              gtritems = items;
              $.each(gtritems, function() {
                if(!$(this).hasClass("MyCat")){
                  $(this).remove();
                }
              });
              console.log(gtritems);
          // Appending the markup to the page
          overlay.hide().appendTo('body');
          slider.appendTo(overlay);
      
          // Creating a placeholder for each image
          gtritems.each(function(){
            placeholders = placeholders.add($('<div class="placeholder">'));
          });
      
          $("#gallerySlider").empty();
          // Hide the gallery if the background is touched / clicked
          slider.append(placeholders).on('click',function(e){
            if(!$(e.target).is('img')){
              hideOverlay();
            }
          });
      
          // Listen for touch events on the body and check if they
          // originated in #gallerySlider img - the images in the slider.
          $('body').on('touchstart', '#gallerySlider img', function(e){
      
            var touch = e.originalEvent,
            startX = touch.changedTouches[0].pageX;
      
            slider.on('touchmove',function(e){
      
            e.preventDefault();
      
              touch = e.originalEvent.touches[0] ||
                e.originalEvent.changedTouches[0];
      
              if(touch.pageX - startX > 10){
                slider.off('touchmove');
                showPrevious();
              }
              else if (touch.pageX - startX < -10){
                slider.off('touchmove');
                showNext();
                }
              });
      
              // Return false to prevent image 
              // highlighting on Android
              return false;
      
          }).on('touchend',function(){
              slider.off('touchmove');
          });
      
          // Listening for clicks on the thumbnails
      
          gtritems.on('click', function(e){
            e.preventDefault();
      
            // Find the position of this image
            // in the collection
      
            index = gtritems.index(this);
            console.log(this);
            showOverlay(index);
            showImage(index);
      
            // Preload the next image
            preload(index+1);
      
            // Preload the previous
            preload(index-1);
      
          });
      
          // If the browser does not have support 
          // for touch, display the arrows
          if ( !("ontouchstart" in window) ){
            overlay.append(prevArrow).append(nextArrow);
      
            prevArrow.click(function(e){
              e.preventDefault();
              showPrevious();
            });
      
            nextArrow.click(function(e){
              e.preventDefault();
              showNext();
            });
          }
      
          // Listen for arrow keys
          $(window).bind('keydown', function(e){
      
            if (e.keyCode == 37){
              showPrevious();
            }
            else if (e.keyCode==39){
              showNext();
            }
      
          });
      
      
          /* Private functions */
      
      
          function showOverlay(index){
      
            // If the overlay is already shown, exit
            if (overlayVisible){
              return false;
            }
      
            // Show the overlay
            overlay.show();
      
            setTimeout(function(){
              // Trigger the opacity CSS transition
              overlay.addClass('visible');
            }, 100);
      
            // Move the slider to the correct image
            offsetSlider(index);
      
            // Raise the visible flag
            overlayVisible = true;
          }
      
          function hideOverlay(){
            // If the overlay is not shown, exit
            if(!overlayVisible){
              return false;
            }
      
            // Hide the overlay
            overlay.hide().removeClass('visible');
            overlayVisible = false;
          }
      
          function offsetSlider(index){
            // This will trigger a smooth css transition
            slider.css('left',(-index*100)+'%');
          }
      
          // Preload an image by its index in the items array
          function preload(index){
            setTimeout(function(){
              showImage(index);
            }, 1000);
          }
      
          // Show image in the slider
          function showImage(index){
      
            // If the index is outside the bonds of the array
            if(index < 0 || index >= gtritems.length){
              return false;
            }
      
            // Call the load function with the href attribute of the item
            loadImage(gtritems.eq(index).attr('href'), function(){
              placeholders.eq(index).html(this);
            });
          }
      
          // Load the image and execute a callback function.
          // Returns a jQuery object
      
          function loadImage(src, callback){
            var img = $('<img>').on('load', function(){
            callback.call(img);
            });
      
            img.attr('src',src);
            }
      
            function showNext(){
      
              // If this is not the last image
              if(index+1 < gtritems.length){
                index++;
                offsetSlider(index);
                preload(index+1);
              }
              else{
                // Trigger the spring animation
      
                slider.addClass('rightSpring');
                setTimeout(function(){
                  slider.removeClass('rightSpring');
                },500);
              }
            }
      
          function showPrevious(){
      
            // If this is not the first image
            if(index>0){
              index--;
              offsetSlider(index);
              preload(index-1);
            }
            else{
              // Trigger the spring animation
      
              slider.addClass('leftSpring');
              setTimeout(function(){
                slider.removeClass('leftSpring');
              },500);
            }
          }
      };
      
      })(jQuery);
      

      【讨论】:

        【解决方案3】:

        我当然不是 jquery 专家 就我此时的理解而言,我认为我的解决方案的错误来自这样一个事实,即我必须将 touchtouch 函数的调用从页面加载时加载 1 次的 script.js 文件移动到过滤器时执行的过滤器单击函数变化。 因为我在控制台中观察了变量 gtritems 并且可以看到每次过滤时我都在添加类似新事件的内容,而所有这些的累积似乎会引发错误。 有没有办法清理旧的事件,以便当我打电话时:

        jQuery('a.touchGalleryLink.MyCat').touchTouch();
        

        是否执行了新的干净代码? 一些帮助将不胜感激!

        【讨论】:

          【解决方案4】:

          我很高兴我做到了 我的第一个想法(参见以前的帖子)对我不起作用,但我现在对它的工作原理有了更好的理解。 所以我找到了另一种方法:现在我在元素上显示类别并

          var overlay = $('<div id="galleryOverlay">'),
              slider = $('<div id="gallerySlider">'),
              prevArrow = $('<a id="prevArrow"></a>'),
              nextArrow = $('<a id="nextArrow"></a>'),
              overlayVisible = false;
          var gtritems = [];      
          
          /* Creating the plugin */
          
          $.fn.touchTouch = function(){
          
              var placeholders = $([]),
                  index = 0,
                  items = this;
          
              // Appending the markup to the page
              overlay.hide().appendTo('body');
              slider.appendTo(overlay);
          
              // Creating a placeholder for each image
              items.each(function(){
                  placeholders = placeholders.add($('<div class="placeholder">'));
              });
          
              $("#gallerySlider").empty();
              // Hide the gallery if the background is touched / clicked
              slider.append(placeholders).on('click',function(e){
                  if(!$(e.target).is('img')){
                      hideOverlay();
                  }
              });
          
              // Listen for touch events on the body and check if they
              // originated in #gallerySlider img - the images in the slider.
              $('body').on('touchstart', '#gallerySlider img', function(e){
          
                  var touch = e.originalEvent,
                      startX = touch.changedTouches[0].pageX;
          
                  slider.on('touchmove',function(e){
          
                      e.preventDefault();
          
                      touch = e.originalEvent.touches[0] ||
                              e.originalEvent.changedTouches[0];
          
                      if(touch.pageX - startX > 10){
                          slider.off('touchmove');
                          showPrevious();
                      }
                      else if (touch.pageX - startX < -10){
                          slider.off('touchmove');
                          showNext();
                      }
                  });
          
                  // Return false to prevent image 
                  // highlighting on Android
                  return false;
          
              }).on('touchend',function(){
                  slider.off('touchmove');
              });
          
              // Listening for clicks on the thumbnails
          
              items.on('click', function(e){
                  e.preventDefault();
          
                  // Find the position of this image
                  // in the collection
          
                  function Gtr(obj, href, ind, itemind) {
                      this.obj=obj;
                      this.href=href;
                      this.ind=ind;
                      this.itemind=itemind;
                      return this;
                  }
                  gtritems = [];
                  var i = 0;
                  var oldindex = items.index(this);
                  $.each(items, function() {
                      if(window.selector == '*'){
                          gtritems.push( new Gtr(this, items.eq(items.index(this)).attr('href'), items.index(this), items.index(this)) );
                          if(oldindex == items.index(this)) {
                              index = oldindex;
                          }
                      } else {
                          if($(this).attr("class").split(" ",4)[3] == window.selector.substr(1)){
                              gtritems.push( new Gtr(this, items.eq(items.index(this)).attr('href'), i, items.index(this)) );
                              if(oldindex == items.index(this)) {
                                  index = i;
                              }
                              i++;
                          }
                      }
                  });
              ...
          

          【讨论】:

            猜你喜欢
            • 2012-02-13
            • 2013-05-30
            • 2012-11-22
            • 1970-01-01
            • 1970-01-01
            • 2013-02-20
            • 1970-01-01
            • 1970-01-01
            • 2014-04-18
            相关资源
            最近更新 更多