Necesitamos iterar un conjunto y manejar su visibilidad properti es.
Antes que nada, permítame mostrarle dos bibliotecas que he creado. La primera es Iterable
, que está diseñado para manejar todo tipo de iteraciones:
function Iterable(params) {
var prevHandlers = [];
var nextHandlers = [];
var that = this;
this.current = params.current;
function ensureArray() {
if (!that.elements) {
that.elements = [];
} else if (!Array.isArray(that.elements)) {
that.elements = $.map(that.elements, function(value, index) {
return [value];
});
}
return that.elements;
}
function calculateCount() {
that.count = ensureArray().length;
}
this.setElements = function(elements) {
this.elements = elements;
calculateCount();
};
this.prev = function(amount) {
if (amount === undefined) {
amount = 1;
}
//Modulo twice to make sure current will be positive
that.current = (((that.current - amount) % that.count) + that.count) % that.count;
while (amount--) {
for (var prevHandler in prevHandlers) {
prevHandlers[prevHandler](params);
}
}
};
this.next = function(amount) {
if (amount === undefined) {
amount = 1;
}
that.current = (that.current + amount) % that.count;
while (amount--) {
for (var nextHandler in nextHandlers) {
nextHandlers[nextHandler](params);
}
}
};
this.getCurrent = function() {
return that.elements[that.current];
};
this.setCurrent = function(current) {
for (var index in that.elements) {
if (that.elements[index] === current) {
that.current = index;
return true;
}
}
return false;
};
this.pushElement = function(element) {
that.elements.push(element);
};
this.pushElements = function(elements) {
for (var element in elements) {
that.pushElement(elements[element]);
}
};
this.insertElement = function(element, index) {
that.elements.splice(index, 0, element);
};
this.insertElements = function(elements, indexes, leftToRight) {
var start = 0;
var end = indexes.length - 1;
if (leftToRight === false) {
var aux = start;
start = end;
end = aux;
}
var leap = (start < end) ? 1 : -1;
while (start - leap !== end) {
that.insertElement[elements[indexes[start]]];
start += leap;
}
};
this.popElement = function() {
that.elements.pop();
};
this.popElements = function(amount) {
that.elements.splice(that.elements.length - amount, amount);
};
this.removeElement = function(index) {
that.elements.splice(index, 1);
};
this.removeElements = function(indexes, leftToRight) {
var start = 0;
var end = indexes.length - 1;
if (leftToRight === false) {
var aux = start;
start = end;
end = aux;
}
var leap = (start < end) ? 1 : -1;
while (start - leap !== end) {
that.removeElement(indexes[start]);
start += leap;
}
};
this.register = {
prev: function(param) {
if (Array.isArray(param)) {
for (var func in param) {
prevHandlers.push(param[func]);
}
} else {
prevHandlers.push(param);
}
},
next: function(param) {
if (Array.isArray(param)) {
for (var func in param) {
nextHandlers.push(param[func]);
}
} else {
nextHandlers.push(param);
}
}
};
this.setElements(params.elements);
if ((!!this.current) && (!Array.isArray(params.elements))) {
this.setCurrent(params.elements[params.current]);
}
}
La segunda es Visiblary
, que está diseñado para manejar todo tipo de eventos de visibilidad:
/*
* params:
* - selector: jQuery selector
* - init: function which gets the Visiblary object to initialize it
* - events: object/array
* - root: a selector which contain all the affected tags, default is "body"
* - types: array, which contains the string representation of the events
* - selector: inner selector to identify the target set
* - handler: handler function
*/
function Visiblary(params) {
var instance = this;
if (!params.toggleClass) {
params.toggleClass = "invisible";
}
this.hideAll = function() {
$(params.selector).addClass(params.toggleClass);
return instance;
};
this.hideSubset = function(subsetSelector) {
$(params.selector).filter(subsetSelector).addClass(params.toggleClass);
return instance;
};
this.hideOnly = function(subsetSelector) {
$(params.selector).not(subsetSelector).removeClass(params.toggleClass);
$(params.selector).filter(subsetSelector).addClass(params.toggleClass);
return instance;
};
this.showAll = function() {
$(params.selector).removeClass(params.toggleClass);
return instance;
};
this.showSubset = function(subsetSelector) {
$(params.selector).filter(subsetSelector).removeClass(params.toggleClass);
return instance;
};
this.showOnly = function(subsetSelector) {
$(params.selector).not(subsetSelector).addClass(params.toggleClass);
$(params.selector).filter(subsetSelector).removeClass(params.toggleClass);
return instance;
};
this.invert = function() {
$(params.selector).each(function() {
$(this).hasClass(params.toggleClass) ? $(this).removeClass(params.toggleClass) : $(this).addClass(params.toggleClass);
});
return instance;
};
if (!!params.init) {
params.init(this);
}
if (!!params.events) {
for (var event in params.events) {
$(!!params.events[event].root ? params.events[event].root : "body").on(params.events[event].types.join(" "), params.events[event].selector, params.events[event].handler);
}
}
return instance;
}
y, suponiendo que uno utiliza estas herramientas y los siete elementos que ya se ha creado, este es el script que resuelve el problema:
var myVisiblary = new Visiblary({
selector: "#content-1, #content-2, #content-3, #content-4, #content-5, #content-6, #content-7"
});
myVisiblary.showOnly("#content-1");
var myIterable = new Iterable({
elements: $("#content-1, #content-2, #content-3, #content-4, #content-5, #content-6, #content-7"),
current: 0
});
myIterable.register.next(function() {myVisiblary.showOnly($(myIterable.getCurrent()))});
setInterval(function(){ myIterable.next(); }, 5000);
Gracias taaaaaaaaaaaaaan mucho! ¡Esto es genial! Solo tengo otras 2 preguntas que espero que no sean un gran problema para implementar.1) ¿Es posible agregar algo que hace que la animación se detenga cuando pasas el cursor sobre div? y 2) ¿Cómo puedo hacer para que cualquier div en el que estoy reciba una clase asignada? Tengo ciertos estilos que me gustaría aplicar al div actual. ¡Gracias de nuevo! – user1163942
haciendo que se detenga cuando pase el mouse va a ser un poco más complicado, pero [aquí hay una actualización] (http://jsfiddle.net/eFjnU/2/) para agregar/eliminar una clase cuando se desplaza. –
@ Si8: Creo que es un poco más limpio sin usar los índices. https://jsfiddle.net/egLefjwv/11/ El suyo no estaba manejando el caso donde el '++' llevaría el índice más allá del último índice del elemento. Para solucionarlo, podría tomar el resto de la división por 'vAlertLen', que lo devolverá a' 0' cuando el índice sea igual a la longitud, y luego hará el incremento. '(vCurrentDispItem% vAlertLen + 1)' Te dejaré llevarlo desde allí con las animaciones. ¡Buena suerte! –