1

I'm using Drupal 7.0 and Views 3 module. And my pager setting: Views Load More.

And i listing my thumbnail images via this extensions. Like this: enter image description here

My thumbnail get number, mouseout shadow and hover jQuery effect. I added this codes in main.js and view_load_more.js

Hover code:

    var hoverImg = '<div class="hoverimg"></div>';

$(".thumb").each(function(){
    $(this).children("div").each(function(){
        $(this).find("a").append(hoverImg);
    });
});

$(".thumb div").hover(function() {
    $(this).find(".hoverimg").animate({ opacity: 'toggle' });
});

$(".thumb").hover(function() {
    $(this).find("div").each(function(){
        $(this).find(".shadow").fadeOut(500);
    });
});

Number code:

var c = '';
var d = '';
$('.view-content div.views-row').each(function(){
    c = 0;
    d = 0;
    var i = 1;
    d = $(this).find('.thumbimg').length;
    $(this).find('.thumbimg').each(function(){
        sayi=i++;
        $(this).append('<div class="img_no">0'+sayi+'</div>');
    });
});

View Load More js:

/**
 * @file views_load_more.js
 *
 * Handles the AJAX pager for the view_load_more plugin.
 */
(function ($) {

  /**
   * Provide a series of commands that the server can request the client perform.
   */
  Drupal.ajax.prototype.commands.viewsLoadMoreAppend = function (ajax, response, status) {

    // Get information from the response. If it is not there, default to
    // our presets.
    var wrapper = response.selector ? $(response.selector) : $(ajax.wrapper);
    var method = response.method || ajax.method;
    var effect = ajax.getEffect(response);

    // We don't know what response.data contains: it might be a string of text
    // without HTML, so don't rely on jQuery correctly iterpreting
    // $(response.data) as new HTML rather than a CSS selector. Also, if
    // response.data contains top-level text nodes, they get lost with either
    // $(response.data) or $('<div></div>').replaceWith(response.data).
    var new_content_wrapped = $('<div></div>').html(response.data);
    var new_content = new_content_wrapped.contents();

    // For legacy reasons, the effects processing code assumes that new_content
    // consists of a single top-level element. Also, it has not been
    // sufficiently tested whether attachBehaviors() can be successfully called
    // with a context object that includes top-level text nodes. However, to
    // give developers full control of the HTML appearing in the page, and to
    // enable Ajax content to be inserted in places where DIV elements are not
    // allowed (e.g., within TABLE, TR, and SPAN parents), we check if the new
    // content satisfies the requirement of a single top-level element, and
    // only use the container DIV created above when it doesn't. For more
    // information, please see http://drupal.org/node/736066.
    if (new_content.length != 1 || new_content.get(0).nodeType != 1) {
      new_content = new_content_wrapped;
    }
    // If removing content from the wrapper, detach behaviors first.
    var settings = response.settings || ajax.settings || Drupal.settings;
    Drupal.detachBehaviors(wrapper, settings);
    if ($.waypoints != undefined) {
      $.waypoints('refresh');
    }

    // Set up our default query options. This is for advance users that might
    // change there views layout classes. This allows them to write there own
    // jquery selector to replace the content with.
    var content_query = response.options.content || '.view-content';

    // If we're using any effects. Hide the new content before adding it to the DOM.
    if (effect.showEffect != 'show') {
      new_content.find(content_query).children().hide();
    }

    // Add the new content to the page.
    wrapper.find('.pager a').remove();
    wrapper.find('.pager').parent('.item-list').html(new_content.find('.pager'));
    wrapper.find(content_query)[method](new_content.find(content_query).children());
    if (effect.showEffect != 'show') {
      wrapper.find(content_query).children(':not(:visible)')[effect.showEffect](effect.showSpeed);
    }


    /** thumbnail number **/
var c = '';
var d = '';
$('.view-content div.views-row').each(function(){
    c = 0;
    d = 0;
    var i = 1;
    d = $(this).find('.thumbimg').length;
    $(this).find('.thumbimg').each(function(){
        sayi=i++;
        $(this).append('<div class="img_no">0'+sayi+'</div>');
    });
});
/** thumbnail number end **/

var shadowImg = '<div class="shadow"></div>';

$(".thumb").each(function(){
    $(this).children("div").each(function(){
        $(this).append(shadowImg);
    });
});

var hoverImg = '<div class="hoverimg"></div>';

$(".thumb").each(function(){
    $(this).children("div").each(function(){
        $(this).find("a").append(hoverImg);
    });
});

$(".thumb div").hover(function() {
    $(this).find(".hoverimg").animate({ opacity: 'toggle' });
});

$(".thumb").hover(function() {
    $(this).find("div").each(function(){
        $(this).find(".shadow").fadeOut(500);
    });
});

    // Attach all JavaScript behaviors to the new content
    // Remove the Jquery once Class, TODO: There needs to be a better
    // way of doing this, look at .removeOnce() :-/
    var classes = wrapper.attr('class');
    var onceClass = classes.match(/jquery-once-[0-9]*-[a-z]*/);
    wrapper.removeClass(onceClass[0]);
    var settings = response.settings || ajax.settings || Drupal.settings;
    Drupal.attachBehaviors(wrapper, settings);
  }

  /**
   * Attaches the AJAX behavior to Views Load More waypoint support.
   */
  Drupal.behaviors.ViewsLoadMore = {
    attach: function (context, settings) {
      if (settings && settings.viewsLoadMore && settings.views.ajaxViews) {
        opts = {
          offset: '100%'
        };
        $.each(settings.viewsLoadMore, function(i, setting) {
          var view = '.view-id-' + setting.view_name + '.view-display-id-' + setting.view_display_id + ' .pager-next a';
          $(view).waypoint(function(event, direction) {
            $(view).waypoint('remove');
            $(view).click();
          }, opts);
        });
      }
    },
    detach: function (context, settings, trigger) {
      if (settings && Drupal.settings.viewsLoadMore && settings.views.ajaxViews) {
        $.each(settings.viewsLoadMore, function(i, setting) {
          var view = '.view-id-' + setting.view_name + '.view-display-id-' + setting.view_display_id + ' .pager-next a';
          $(view, context).waypoint('destroy');
        });
      }
    }
     };
})(jQuery);

All jQuery effects is working. But when i click Load More button, next thumbnails working normal but jQuery effects seen twice previous thumbnails. Like this: enter image description here

What's problem?

2 Answers 2

5

The Drupal.behaviors.ViewsLoadMore.attach() function is called multiple times (each time Drupal.attachBehaviors() is called, so each time more content is loaded) over the same portion of the DOM tree. So the same element can be processed multiple time by the same code. The easiest solution to prevent this is to use the jQuery once plugin (which is provided by Drupal 7) like this:

$(selector, context).once('behavior-name').doSomething();
$(selector, context).once('behavior-name', function(){ /*do something*/ });
-1

You need to implement those using Drupal.behaviors to stop it being executed twice or more.

Hover:

(function($){
  Drupal.behaviors.myHoverImg = {
    attach: function(context, settings) {
      var hoverImg = '<div class="hoverimg"></div>';

      $(".thumb", context).each(function(){
        $(this).children("div").each(function(){
          $(this).find("a").append(hoverImg);
        });
      });

      $(".thumb div", context).hover(function() {
        $(this).find(".hoverimg").animate({ opacity: 'toggle' });
      });

      $(".thumb", context).hover(function() {
        $(this).find("div").each(function(){
          $(this).find(".shadow").fadeOut(500);
        });
      });
    }
  };
})(jQuery);

Number:

(function($){   
  Drupal.behaviors.thumbNumber = {
    attach: function(context, settings) {
      var c = '';
      var d = '';
      $('.view-content div.views-row', context).each(function(){
        c = 0;
        d = 0;
        var i = 1;
        d = $(this).find('.thumbimg').length;
        $(this).find('.thumbimg').each(function(){
          sayi=i++;
          $(this).append('<div class="img_no">0'+sayi+'</div>');
        });
      });
    }
  };
})(jQuery);
1
  • 1
    Using Drupal.behaviors wont prevent the code from being run multiple times over the same elements... even when using it, you have to actively prevent multiple-processing of the same elements with something like jQuery.once. Commented Apr 21, 2012 at 2:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.