If element changed class from one to another in jQuery

Usually my slideshow automatically advances to the next image, but I want to determine if it goes backward using a user-initiated action (keyboard arrows or controls). My solution for this would be to do this (my imaginary code):

if(jQuery("#slideshow article").hasChangedClassFrom("previous").hasChangedClassTo("current")) {
    backwards = true;
}
if(backwards) { // code for backwards
    jQuery("#slideshow article.previous").css("z-index", "1");
    jQuery("#slideshow article.next").css("z-index", "2");
}
else { // code for forwards (normal state)
    jQuery("#slideshow article.previous").css("z-index", "2");
    jQuery("#slideshow article.next").css("z-index", "1");
}

      

The classes are already implemented, so the current slide always has the class "current" and so on. I know this is not valid code at all, but by reading this I think it would be quite clear what I want to achieve. I'm not very good with JavaScript / jQuery, but I've tried looking for solutions like this with no luck.

Live site // Live JS code

+3


source to share


6 answers


Instead of guessing the previous class, use the current and previous index.

http://jsfiddle.net/whyba4L9/5/



UPDATE 2:

var stopp, antall = jQuery("#slideshow article").length;
var index = 0

function slideTo(idx) {
    jQuery("#slideshow article, #slideshow nav a").removeAttr("class").filter(':nth-of-type(' + (idx+1) + ')').addClass("current");
    if(jQuery("#slideshow article:nth-of-type(2)").hasClass("current")) {
        jQuery("#slideshow article:first-of-type").addClass("forrige");
        jQuery("#slideshow article:last-of-type").addClass("neste");
    }
    else if(jQuery("#slideshow article:first-of-type").hasClass("current")) {
        jQuery("#slideshow article:last-of-type").addClass("forrige");
        jQuery("#slideshow article:nth-of-type(2)").addClass("neste");
    }
    else if(jQuery("#slideshow article:last-of-type").hasClass("current")) {
        jQuery("#slideshow article:nth-of-type(2)").addClass("forrige");
        jQuery("#slideshow article:first-of-type").addClass("neste");
    }

    if(index ==antall-1 && idx ==0 )
    {
        //lasto to first
    }
    else if(index>idx || (index == 0 && idx == antall-1))
    {
        alert('BACKWARDS')
    }
    index = idx;

};
function startCycle() {
    stopp = setInterval(function() {
        jQuery("#slideshow article").stop(true, true);
        var idx = index + 1 > antall - 1 ? 0 : index + 1;
        slideTo(idx,false);
    }, 5500);
}; 
if (antall > 1) {
    jQuery("#slideshow").append("<nav>").css("height", jQuery("#slideshow img").height());
    jQuery("#slideshow article").each(function() {
        jQuery("#slideshow nav").append("<a>&bull;</a>");
    }).filter(":first-of-type").addClass("current first");
    jQuery("#slideshow article:nth-of-type(2)").addClass("neste");
    jQuery("#slideshow article:last-of-type").addClass("forrige");
    startCycle();
    jQuery("#slideshow nav a").click(function() {
        clearInterval(stopp);
        startCycle();
        var idx = jQuery("#slideshow nav a").index(this);
        if (index === idx) return;
        slideTo(idx);
    }).filter(":first-of-type").addClass("current");
    jQuery(document).keyup(function(e) {
        if (e.keyCode == 37) {
            var idx = index - 1 < 0 ? antall - 1 : index - 1;
            slideTo(idx);
            clearInterval(stopp);
            startCycle();
        } 
        else if (e.keyCode == 39) {
            var idx = index + 1 > antall - 1 ? 0 : index + 1;
            slideTo(idx);
            clearInterval(stopp);
            startCycle();
        }
    });
}

      

+1


source


Based on code from the referenced link http://dans.no/cycle.js

Declare variable clickindex = 0;

Place the following inside a jQuery click function ("# slideshow nav a"). Click on



clickindex = jQuery("#slideshow nav a").index(this);
if(clickindex<index){
    console.log("execute some logic");
}

      

Jsfiddle link for my javascript code of my solution http://jsfiddle.net/y601tkfL/

+2


source


Try to call this function when the user changes the image with the parameter this

. I hope I understood correctly what you are asking about. If you don’t let me know, and I will redo it. Also, if the slideshow is over, write html and javascript.

function whatever(this)
{
  if(this.className == 'previous')
  {
    alert('the user has changed the image');
    this.className = 'current';
  }
  else
  {
    alert('the user hasn\'t changed the image');
  }
}

      

+1


source


The easiest way to do this, based on what I understand, your question to look at is to put a handler on the index buttons and a method to track the current image.

Hear the slide change

var currentSlide = '';

$('.slideIndexButtons').on('click', function(e){
    // Conditional logic that compares $(this).data('whichimage') to currentSlide
    var whichImage = $(this).data('whichimage');

    // ->this means attaching data-whichimage="" to each of the elements, or
    // ->you can just stick with detecting the class and going from there
    // Either process results in isBackwards boolean

    if (currentSlide == 'prev' && whichImage == 'current') {
        isBackwards = true;
    }

    if (isBackwards) {
        // Backwards logic here
    } else {
        // Other logic here
    }

    // Unless the event we're listening for in keeping currentSlide updated is also fired when
    // the slide changes due to user input, we'll need to update currentSlide manually.
    currentSlide = whichImage; 
});

      

Track the current slide

$('#slider').on('event', function(){
    // This is assuming that we're strictly listening to the slider automatic sliding

    // The event you attach this to is either fired before or after the slide changes.
    // Knowing which is key in getting the data you want. You are either getting
    // The data from this slide $(this).data('whichimage') or 
    // $(this).next().data('whichimage')

    // Again, you can go with classes, but it is a lot of logic which you have to 
    // update manually if you ever have to add or alter an image in the slide set.
    // Either way, you end up with the variable targetImage

    currentSlide = targetImage;
});

      

Either way, your slideshow code has an API that will allow you to listen when slide events are fired. Otherwise, you will need to find a way to configure, fire and listen for these events manually, either through callbacks passed in or through (eek!) Modifying the code and possibly inadvertently changing its functionality.

This should give you what you asked for. Let me know how it goes.

+1


source


You can add this line at the very beginning of the slideTo function in your cycle.js file

if((idx < index && !(idx == 0 && index == antall - 1)) ||
   (idx == antall - 1 && index == 0)){
   jQuery.trigger('BACKWARDS')
}

      

and then add an event handler for "BACKWARDS" elsewhere (perhaps at the end of the .js loop?).

jQuery.on('BACKWARDS', function(e){
   //DO THINGS HERE
}

      

+1


source


I wrote an attrchange plugin that I think will solve your problem effectively. attrchange is a simple jQuery plugin for detecting attribute change. The plugin internally uses one of the following compatible browser-based methods to detect an attribute change,

  • Mutation watcher
  • DOMAttrModified
  • onpropertychange

Try the demo below to learn more about how you can use the plugin for your needs.

Click to learn more about attrchange.

Note. The plugin does not use polling, so you can use it without any problem, however, polling is supported as an extension to the plugin. You can read more if you are interested.

$('#test').one('click', function() {
  $('#test').attrchange({
    trackValues: true,
    callback: function(event) {
      $('#result').html('<div><label>Attribute Name: </label>' + event.attributeName + '</div>' + '<div><label>Old Value</label>' + event.oldValue + '</div>' + '<div><label>New Value</label>' + event.newValue + '</div>');
    }
  });

  //this will toggleClass 'blue-background' every 2 secs
  setInterval(function() {
    $('#test').toggleClass('lightblue-background');
  }, 2000);
});
      

html {
  font-family: Segoe UI, Arial, sans-serif;
  font-size: 13px;
}
div#test {
  border: 1px solid #d2d2d2;
  padding: 10px;
  display: inline-block;
}
.lightblue-background {
  background-color: #DBEAF9;
}
div label {
  font-weight: bold;
  margin-right: 5px;
}
      

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://raw.githubusercontent.com/meetselva/attrchange/master/js/attrchange.js"></script>
<div id="test">
  <p style="font-weight: bold;">Click anywhere in this box to Start the DEMO</p>
  <p>The demo is to simply toggle a class 'lightblue-background' to this div every 2 secs.</p>  
  <div id="result" style="font-size: 0.9em;"></div>
      

Run codeHide result


See the pseudo code for your case using a plugin,

jQuery("#slideshow article").attrchange({
   trackValues: true,
   callback: function(event) {
      if ($(this).hasClass('current') && 
         (event.oldValue && event.oldValue.indexOf('previous') >= 0)) {
         //code for backward
      } else {
         //code for forward
      }
   }
});

      

+1


source







All Articles