Adding a SetInterval function in jquery - javascript

So I have this code from here: j360
This code is perfect for what I want: an html wich has a draggable 360º product image view, but it lacks one thing: a button for auto rotation.
I already have the button into the html, but I can't, for more that I try, to make a function or anything to make the images go by itself, and not only when I drag it over the screen.
Here is the code I have in the moment.
(function($){
$.fn.j360 = function(options) {
var defaults = {
clicked: false,
currImg: 1
}
var options = jQuery.extend(defaults, options);
return this.each(function() {
var $obj = jQuery(this);
var aImages = {};
$obj.css({
'margin-left' : 'auto',
'margin-right' : 'auto',
'text-align' : 'center',
'overflow' : 'hide'
});
$overlay = $obj.clone(true);
$overlay.html('<img src="images/loader.gif" class="loader" style="margin-top:' + ($obj.height()/2 - 15) + 'px" />');
$overlay.attr('id', 'view_overlay');
$overlay.css({
'position' : 'absolute',
'z-index': '5',
'top' : $obj.offset().top,
'left' : $obj.offset().left,
'background' : '#fff'
});
$obj.after($overlay);
$obj.after('<div id="colors_ctrls"></div>');
jQuery('#colors_ctrls').css({
'width' : $obj.width(),
'position' : 'absolute',
'z-index': '5',
'top' : $obj.offset().top + $obj.height - 50,
'left' : $obj.offset().left
});
var imageTotal = 0;
jQuery('img', $obj).each(function() {
aImages[++imageTotal] = jQuery(this).attr('src');
preload(jQuery(this).attr('src'));
})
var imageCount = 0;
jQuery('.preload_img').load(function() {
if (++imageCount == imageTotal) {
$overlay.animate({
'filter' : 'alpha(Opacity=0)',
'opacity' : 0
}, 100);
$obj.html('<img src="' + aImages[1] + '" />');
$overlay.bind('mousedown touchstart', function(e) {
if (e.type == "touchstart") {
options.currPos = window.event.touches[0].pageX;
} else {
options.currPos = e.pageX;
}
options.clicked = true;
return false;
});
jQuery(document).bind('mouseup touchend', function() {
options.clicked = false;
});
jQuery(document).bind('mousemove touchmove', function(e) {
if (options.clicked) {
var pageX;
if (e.type == "touchmove") {
pageX = window.event.targetTouches[0].pageX;
} else {
pageX = e.pageX;
}
var width_step = 50;
if (Math.abs(options.currPos - pageX) >= width_step) {
if (options.currPos - pageX >= width_step) {
options.currImg++;
if (options.currImg > imageTotal) {
options.currImg = 1;
}
} else {
options.currImg--;
if (options.currImg < 1) {
options.currImg = imageTotal;
}
}
options.currPos = pageX;
$obj.html('<img src="' + aImages[options.currImg] + '" />');
}
}
});
}
});
if (jQuery.browser.msie || jQuery.browser.mozilla || jQuery.browser.opera || jQuery.browser.safari ) {
jQuery(window).resize(function() {
onresizeFunc($obj, $overlay);
});
} else {
var supportsOrientationChange = "onorientationchange" in window,
orientationEvent = supportsOrientationChange ? "orientationchange" : "resize";
window.addEventListener(orientationEvent, function() {
onresizeFunc($obj, $overlay);
}, false);
}
onresizeFunc($obj, $overlay)
});
}
})
(jQuery)
function onresizeFunc($obj, $overlay){
$obj.css({
'margin-top' : $(document).height()/2
});
$overlay.css({
'margin-top' : 200,
'top' : $obj.offset().top,
'left' : $obj.offset().left
});
jQuery('#colors_ctrls').css({
'top' : $obj.offset().top + $obj.height - 50,
'left' : $obj.offset().left
})
}
function preload(image) {
if (typeof document.body == "undefined") return;
try {
var div = document.createElement("div");
var s = div.style;
s.position = "absolute";
s.top = s.left = 0;
s.visibility = "hidden";
document.body.appendChild(div);
div.innerHTML = "<img class=\"preload_img\" src=\"" + image + "\" />";
}
catch(e) {
// Error. Do nothing.
}
};
I need a method to increment over time a function, to make the ilusion of auto-rotate.

This plugin doesn’t seem to have this option (a kind of autoplay) so you have to code it or search an other plugin.
Since it is a list of image, you can maybe don’t use the plugin and display images one after another with jQuery and .delay()

Related

Change a JS function based on resolution

Currently I am working on a webapplication for my company, and recently started learning JS/Jquery. I have set up content in a Tabs plugin/libary from the github link below:
https://github.com/samsono/Easy-Responsive-Tabs-to-Accordion
The JS file
// Easy Responsive Tabs Plugin
// Author: Samson.Onna <Email : samson3d#gmail.com>
(function ($) {
$.fn.extend({
easyResponsiveTabs: function (options) {
//Set the default values, use comma to separate the settings, example:
var defaults = {
type: 'default', //default, vertical, accordion;
width: 'auto',
fit: true,
closed: false,
tabidentify: '',
activate: function () {
}
}
//Variables
var options = $.extend(defaults, options);
var opt = options, jtype = opt.type, jfit = opt.fit, jwidth = opt.width, vtabs = 'vertical', accord = 'accordion';
var hash = window.location.hash;
var historyApi = !!(window.history && history.replaceState );
//Events
$(this).bind('tabactivate', function (e, currentTab) {
if (typeof options.activate === 'function') {
options.activate.call(currentTab, e)
}
});
//Main function
this.each(function () {
var $respTabs = $(this);
var $respTabsList = $respTabs.find('ul.resp-tabs-list.' + options.tabidentify);
var respTabsId = $respTabs.attr('id');
$respTabs.find('ul.resp-tabs-list.' + options.tabidentify + ' li').addClass('resp-tab-item').addClass(options.tabidentify);
$respTabs.css({
'display': 'block',
'width': jwidth
});
if (options.type == 'vertical')
$respTabsList.css('margin-top', '0px');
$respTabs.find('.resp-tabs-container.' + options.tabidentify).css('border-color', options.active_content_border_color);
$respTabs.find('.resp-tabs-container.' + options.tabidentify + ' > div').addClass('resp-tab-content').addClass(options.tabidentify);
jtab_options();
//Properties Function
function jtab_options() {
if (jtype == vtabs) {
$respTabs.addClass('resp-vtabs').addClass(options.tabidentify);
}
if (jfit == true) {
$respTabs.css({ width: '100%', margin: '0px' });
}
if (jtype == accord) {
$respTabs.addClass('resp-easy-accordion').addClass(options.tabidentify);
$respTabs.find('.resp-tabs-list').css('display', 'none');
}
}
//Assigning the h2 markup to accordion title
var $tabItemh2;
$respTabs.find('.resp-tab-content.' + options.tabidentify).before("<h2 class='resp-accordion " + options.tabidentify + "' role='tab'><span class='resp-arrow'></span></h2>");
$respTabs.find('.resp-tab-content.' + options.tabidentify).prev("h2").css({
'background-color': options.inactive_bg,
'border-color': options.active_border_color
});
var itemCount = 0;
$respTabs.find('.resp-accordion').each(function () {
$tabItemh2 = $(this);
var $tabItem = $respTabs.find('.resp-tab-item:eq(' + itemCount + ')');
var $accItem = $respTabs.find('.resp-accordion:eq(' + itemCount + ')');
$accItem.append($tabItem.html());
$accItem.data($tabItem.data());
$tabItemh2.attr('aria-controls', options.tabidentify + '_tab_item-' + (itemCount));
itemCount++;
});
//Assigning the 'aria-controls' to Tab items
var count = 0,
$tabContent;
$respTabs.find('.resp-tab-item').each(function () {
$tabItem = $(this);
$tabItem.attr('aria-controls', options.tabidentify + '_tab_item-' + (count));
$tabItem.attr('role', 'tab');
$tabItem.css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
//Assigning the 'aria-labelledby' attr to tab-content
var tabcount = 0;
$respTabs.find('.resp-tab-content.' + options.tabidentify).each(function () {
$tabContent = $(this);
$tabContent.attr('aria-labelledby', options.tabidentify + '_tab_item-' + (tabcount)).css({
'border-color': options.active_border_color
});
tabcount++;
});
count++;
});
// Show correct content area
var tabNum = 0;
if (hash != '') {
var matches = hash.match(new RegExp(respTabsId + "([0-9]+)"));
if (matches !== null && matches.length === 2) {
tabNum = parseInt(matches[1], 10) - 1;
if (tabNum > count) {
tabNum = 0;
}
}
}
//Active correct tab
$($respTabs.find('.resp-tab-item.' + options.tabidentify)[tabNum]).addClass('resp-tab-active').css({
'background-color': options.activetab_bg,
'border-color': options.active_border_color
});
//keep closed if option = 'closed' or option is 'accordion' and the element is in accordion mode
if (options.closed !== true && !(options.closed === 'accordion' && !$respTabsList.is(':visible')) && !(options.closed === 'tabs' && $respTabsList.is(':visible'))) {
$($respTabs.find('.resp-accordion.' + options.tabidentify)[tabNum]).addClass('resp-tab-active').css({
'background-color': options.activetab_bg + ' !important',
'border-color': options.active_border_color,
'background': 'none'
});
$($respTabs.find('.resp-tab-content.' + options.tabidentify)[tabNum]).addClass('resp-tab-content-active').addClass(options.tabidentify).attr('style', 'display:block');
}
//assign proper classes for when tabs mode is activated before making a selection in accordion mode
else {
// $($respTabs.find('.resp-tab-content.' + options.tabidentify)[tabNum]).addClass('resp-accordion-closed'); //removed resp-tab-content-active
}
//Tab Click action function
$respTabs.find("[role=tab]").each(function () {
var $currentTab = $(this);
$currentTab.hover(function () {
var $currentTab = $(this);
var $tabAria = $currentTab.attr('aria-controls');
if ($currentTab.hasClass('resp-accordion') && $currentTab.hasClass('resp-tab-active')) {
$respTabs.find('.resp-tab-content-active.' + options.tabidentify).slideUp('', function () {
$(this).addClass('resp-accordion-closed');
});
$currentTab.removeClass('resp-tab-active').css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
return false;
}
if (!$currentTab.hasClass('resp-tab-active') && $currentTab.hasClass('resp-accordion')) {
$respTabs.find('.resp-tab-active.' + options.tabidentify).removeClass('resp-tab-active').css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
$respTabs.find('.resp-tab-content-active.' + options.tabidentify).slideUp().removeClass('resp-tab-content-active resp-accordion-closed');
$respTabs.find("[aria-controls=" + $tabAria + "]").addClass('resp-tab-active').css({
'background-color': options.activetab_bg,
'border-color': options.active_border_color
});
$respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + '].' + options.tabidentify).slideDown().addClass('resp-tab-content-active');
} else {
console.log('here');
$respTabs.find('.resp-tab-active.' + options.tabidentify).removeClass('resp-tab-active').css({
'background-color': options.inactive_bg,
'border-color': 'none'
});
$respTabs.find('.resp-tab-content-active.' + options.tabidentify).removeAttr('style').removeClass('resp-tab-content-active').removeClass('resp-accordion-closed');
$respTabs.find("[aria-controls=" + $tabAria + "]").addClass('resp-tab-active').css({
'background-color': options.activetab_bg,
'border-color': options.active_border_color
});
$respTabs.find('.resp-tab-content[aria-labelledby = ' + $tabAria + '].' + options.tabidentify).addClass('resp-tab-content-active').attr('style', 'display:block');
}
//Trigger tab activation event
$currentTab.trigger('tabactivate', $currentTab);
//Update Browser History
if (historyApi) {
var currentHash = window.location.hash;
var tabAriaParts = $tabAria.split('tab_item-');
// var newHash = respTabsId + (parseInt($tabAria.substring(9), 10) + 1).toString();
var newHash = respTabsId + (parseInt(tabAriaParts[1], 10) + 1).toString();
if (currentHash != "") {
var re = new RegExp(respTabsId + "[0-9]+");
if (currentHash.match(re) != null) {
newHash = currentHash.replace(re, newHash);
}
else {
newHash = currentHash + "|" + newHash;
}
}
else {
newHash = '#' + newHash;
}
history.replaceState(null, null, newHash);
}
});
});
//Window resize function
$(window).resize(function () {
$respTabs.find('.resp-accordion-closed').removeAttr('style');
});
});
}
});
})(jQuery);
Orginally the tabs are set to a onclick like this on line number 142:
$currentTab.click(function () {
I've changed the tabs to a hover because I like that more for my application, like so:
$currentTab.hover(function () {
It works fine on my desktop but when I resize my browser to a smaller resolution the tabs will change in a accordion. Normally it works totally fine, but because I've changed it to a hover system it's not the best option to have now. Is there any way to detect smaller resolutions in javascript/jquery so when its like under 800px the function changes back to $currentTab.click(function () {? Or any other solution for my problem?
What I want: Change a jquery hover event function based on resolution OR change a JS script based on resolution (So I create 2 js files, one for mobile and one for desktop and then decide which script I would load).
Make a named function and do
if (window.screen.width < whatever ) $currentTab.click(doIt);
else $currentTab.hover(doIt);

Get or set variable from another function

I am using this custom JavaScript range slider, and I want to be able to get and set the sliders value. I already implemented the set function. (If you have a better way of doing it, please let me know.) I'm having trouble implementing the getValue function
I tried doing the following:
function getValue() {
if (value) {
return value;
}
return;
}
And when I call that function, I get the following error:
Uncaught ReferenceError: getValue is not defined
Creating a global variable, is not an option. How can I get the sliders value?
To set or get the sliders value, I want to be able to do the following:
mySlider.Value = 17; // Set Value
var currentValue = mySlider.Value // Get Value
JSFiddle
function rangeSlider(elem, config, update) {
if (typeof update != "undefined" && update) {
var dragger = elem.getElementsByTagName('span')[0];
var range = elem.getElementsByTagName('div')[0];
var isVertical = config.vertical;
var rangeWidth = range[!isVertical ? 'offsetWidth' : 'offsetHeight'];
var rangeOffset = range[!isVertical ? 'offsetLeft' : 'offsetTop'];
var draggerWidth = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
dragger.style[!isVertical ? 'left' : 'top'] = (config.value / 100 * rangeWidth - (draggerWidth / 2)) + 'px';
return;
}
function getValue() {
if (value) {
return value;
}
return;
}
var html = document.documentElement,
range = document.createElement('div'),
dragger = document.createElement('span'),
down = false,
rangeWidth, rangeOffset, draggerWidth, cachePosition;
var defaults = {
value: 0, // set default value on initiation from `0` to `100` (percentage based)
vertical: false, // vertical or horizontal?
rangeClass: "", // add extra custom class for the range slider track
draggerClass: "", // add extra custom class for the range slider dragger
drag: function(v) { /* console.log(v); */ } // function to return the range slider value into something
};
for (var i in defaults) {
if (typeof config[i] == "undefined") config[i] = defaults[i];
}
function addEventTo(el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + ev, fn);
} else {
el['on' + ev] = fn;
}
}
var isVertical = config.vertical;
elem.className = (elem.className + ' range-slider ' + (isVertical ? 'range-slider-vertical' : 'range-slider-horizontal')).replace(/^ +/, "");
range.className = ('range-slider-track ' + config.rangeClass).replace(/ +$/, "");
dragger.className = ('dragger ' + config.draggerClass).replace(/ +$/, "");
addEventTo(range, "mousedown", function(e) {
html.className = (html.className + ' no-select').replace(/^ +/, "");
rangeWidth = range[!isVertical ? 'offsetWidth' : 'offsetHeight'];
rangeOffset = range[!isVertical ? 'offsetLeft' : 'offsetTop'];
draggerWidth = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
down = true;
updateDragger(e);
return false;
});
addEventTo(document, "mousemove", function(e) {
updateDragger(e);
});
addEventTo(document, "mouseup", function(e) {
html.className = html.className.replace(/(^| )no-select( |$)/g, "");
down = false;
});
addEventTo(window, "resize", function(e) {
var woh = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
dragger.style[!isVertical ? 'left' : 'top'] = (((cachePosition / 100) * range[!isVertical ? 'offsetWidth' : 'offsetHeight']) - (woh / 2)) + 'px';
down = false;
});
function updateDragger(e) {
e = e || window.event;
var pos = !isVertical ? e.pageX : e.pageY;
if (!pos) {
pos = !isVertical ? e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft : e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
if (down && pos >= rangeOffset && pos <= (rangeOffset + rangeWidth)) {
dragger.style[!isVertical ? 'left' : 'top'] = (pos - rangeOffset - (draggerWidth / 2)) + 'px';
cachePosition = Math.round(((pos - rangeOffset) / rangeWidth) * 100);
config.drag(cachePosition);
}
}
function initDragger() {
var woh = dragger[!isVertical ? 'offsetWidth' : 'offsetHeight'];
cachePosition = ((config.value / 100) * range[!isVertical ? 'offsetWidth' : 'offsetHeight']);
dragger.style[!isVertical ? 'left' : 'top'] = (cachePosition - (woh / 2)) + 'px';
config.drag(config.value);
}
range.appendChild(dragger);
elem.appendChild(range);
initDragger();
}
var slid1 = document.getElementById('range-slider-1');
var btn = document.getElementById('btn');
var anotherBtn = document.getElementById('anotherBtn');
var resultP = document.getElementById('results');
rangeSlider(slid1, {
value: 10,
});
btn.onclick = function() {
rangeSlider(slid1, {
value: 50
}, 1);
}
anotherBtn.onclick = function() {
document.getElementById('results').innerHTML = "Your Current Value is: " + getValue();
}
.range-slider-track {
height: 20px;
}
.range-slider-track:before {
content: "";
display: block;
width: 100%;
height: 2px;
background-color: black;
}
.range-slider-track .dragger {
display: block;
width: 10px;
height: inherit;
position: relative;
background-color: red;
}
<div id="range-slider-1"></div>
<button id="btn">Set Value</button>
<button id="anotherBtn">Get Value</button>
<p id="results"></p>
The function "rangeSlider()" should be handled as an object, not as a function...
You have to create an object:
var mySlider = new rangeSlider(slid1, { value: 10,});
And you can obtain its value as:
mySlider.getValue()
Take a look at: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new
Paste this javascript into the original fiddle and sett it working:
function rangeSlider(elem, config, update) {
var this_ = this;
this.setValue = function(value) {
var dragger = this.config.elem.getElementsByTagName('span')[0];
var range = this.config.elem.getElementsByTagName('div')[0];
var rangeWidth = range[!this.config.vertical ? 'offsetWidth' : 'offsetHeight'];
var draggerWidth = dragger[!this.config.vertical ? 'offsetWidth' : 'offsetHeight'];
dragger.style[!this.config.vertical ? 'left' : 'top'] = (value / 100 * rangeWidth - (draggerWidth / 2)) + 'px';
this.config.value = value;
};
this.getValue = function() {
return this.config.value;
};
var html = document.documentElement,
range = document.createElement('div'),
dragger = document.createElement('span'),
down = false,
rangeWidth, rangeOffset, draggerWidth, cachePosition;
this.config = {
value: (config.value || 0), // set default value on initiation from `0` to `100` (percentage based)
vertical: (config.vertical || false), // vertical or horizontal?
rangeClass: "", // add extra custom class for the range slider track
draggerClass: "", // add extra custom class for the range slider dragger
drag: function(v) { /* console.log(v); */ }, // function to return the range slider value into something
elem: elem
};
addEventTo = function(el, ev, fn) {
if (el.addEventListener) {
el.addEventListener(ev, fn, false);
} else if (el.attachEvent) {
el.attachEvent('on' + ev, fn);
} else {
el['on' + ev] = fn;
}
}
elem.className = (elem.className + ' range-slider ' + (this.config.vertical ? 'range-slider-vertical' : 'range-slider-horizontal')).replace(/^ +/, "");
range.className = ('range-slider-track ' + config.rangeClass).replace(/ +$/, "");
dragger.className = ('dragger ' + config.draggerClass).replace(/ +$/, "");
addEventTo(range, "mousedown", function(e) {
html.className = (html.className + ' no-select').replace(/^ +/, "");
rangeWidth = range[!this_.config.vertical ? 'offsetWidth' : 'offsetHeight'];
rangeOffset = range[!this_.config.vertical ? 'offsetLeft' : 'offsetTop'];
draggerWidth = dragger[!this_.config.vertical ? 'offsetWidth' : 'offsetHeight'];
down = true;
updateDragger(e);
return false;
});
addEventTo(document, "mousemove", function(e) {
updateDragger(e);
});
addEventTo(document, "mouseup", function(e) {
html.className = html.className.replace(/(^| )no-select( |$)/g, "");
down = false;
});
addEventTo(window, "resize", function(e) {
var woh = dragger[!this.config.vertical ? 'offsetWidth' : 'offsetHeight'];
dragger.style[!this.config.vertical ? 'left' : 'top'] = (((cachePosition / 100) * range[!this.config.vertical ? 'offsetWidth' : 'offsetHeight']) - (woh / 2)) + 'px';
down = false;
});
function updateDragger(e) {
e = e || window.event;
var pos = !this_.config.vertical ? e.pageX : e.pageY;
if (!pos) {
pos = !this_.config.vertical ? e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft : e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
}
if (down && pos >= rangeOffset && pos <= (rangeOffset + rangeWidth)) {
dragger.style[!this_.config.vertical ? 'left' : 'top'] = (pos - rangeOffset - (draggerWidth / 2)) + 'px';
cachePosition = Math.round(((pos - rangeOffset) / rangeWidth) * 100);
this_.config.value = cachePosition;
this_.config.drag(cachePosition);
}
};
this.initDragger = function() {
var woh = dragger[!this.config.vertical ? 'offsetWidth' : 'offsetHeight'];
cachePosition = ((config.value / 100) * range[!this.config.vertical ? 'offsetWidth' : 'offsetHeight']);
dragger.style[!this.config.vertical ? 'left' : 'top'] = (cachePosition - (woh / 2)) + 'px';
this.config.drag(this.config.value);
};
range.appendChild(dragger);
elem.appendChild(range);
this.initDragger();
}
var slid1 = document.getElementById('range-slider-1');
var btn = document.getElementById('btn');
var anotherBtn = document.getElementById('anotherBtn');
var resultP = document.getElementById('results');
var rs = new rangeSlider(slid1, {
value: 10,
});
var slid2 = document.getElementById('range-slider-2');
var rs2 = new rangeSlider(slid2, {
value: 20,
});
btn.onclick = function() {
rs.setValue(50);
}
anotherBtn.onclick = function() {
document.getElementById('results').innerHTML = "Range 1: " + rs.getValue() + '<br/>Range2: ' + rs2.getValue();
}
And this html also:
<div id="range-slider-1"></div>
<button id="btn">Set Value</button>
<button id="anotherBtn">Get Value</button>
<div id="range-slider-2"></div>
<p id="results"></p>
Like some of the other posters said, you need to fix your function a bit.
I don't have time to clean up the new code, but I'm sure you'll get the idea.
Here are a few things to keep in mind:
You want to create a new object by calling new rangeSlider.
You can assign the new object to a variable so you can use that variable to set or get values.
Notice the var this_ = this statement so we'll have access to the object instance even certain events, because the this in those events may be the actual elements in the DOM.
This new approach supports the multiple sliders in the document, as with your original code, but it is a lot more simpler and cleaner to get and set values.
I'm sure we can clean this code a lot more, so enjoy.

jQuery: how to implement controller for slider (carousel)?

I have build a slider using jQuery which works fine. It was a quick development so that didn't get time to add controller. Right now it is getting hard to fix controller for the carousel.
Does any one have solution or alternative to fix this?
Demo http://jsfiddle.net/sweetmaanu/Pn2UB/16/
$.fx.speeds._default = 1000;
function slider(container) {
var currPg = null,
firstPg = null;
container.find('> .pg').each(function (idx, pg) {
pg = $(pg);
var o = {
testimonial: pg.find('> .testimonial'),
thumb: pg.find('> .testimonial-thumb'),
pg: pg
};
o.pg.css({
position: 'absolute',
width: '100%',
height: '100%',
});
if (idx > 0) {
o.pg.css({
opacity: 0,
'z-index': -1
});
o.testimonial.css({
'margin-left': '100%'
});
o.thumb.css({
'bottom': '-100%'
});
} else {
firstPg = o;
}
o.prev = currPg;
if (currPg) {
currPg.next = o;
}
currPg = o;
});
firstPg.prev = currPg;
currPg.next = firstPg;
currPg = firstPg;
this.advance = function advance(duration) {
console.log("advance!", this);
var dur = duration || $.fx.speeds._default;
var dur2 = Math.ceil(dur / 2);
var dh = container.height();
var dw = container.width();
var nextPg = currPg.next;
nextPg.pg.css({
opacity: 1,
'z-index': null
});
var _pg = currPg;
currPg.testimonial.stop().animate({
'margin-left': -dw
}, dur, function () {
_pg.pg.css({
opacity: 0,
'z-index': -1
});
_pg = null;
});
nextPg.testimonial.stop()
.css({
'margin-left': dw
})
.animate({
'margin-left': 0
}, dur);
currPg.thumb.stop().animate({
'bottom': -dh
}, dur2, function () {
nextPg.thumb.stop()
.css({
'bottom': -dh
})
.animate({
'bottom': 0
}, dur2);
nextPg = null;
});
currPg = nextPg;
}
}
var s = new slider($('#banner'));
function scheduleNext() {
setTimeout(function () {
s.advance();
scheduleNext();
}, 5000);
}
scheduleNext();
You just want to add a variable direction and change that on click of both prev and next
var direction = 'left';
$('#next').click(function(event) {
direction = 'right';
s.advance(1000,direction);
});
$('#prev').click(function(event) {
direction = 'left';
s.advance(1000,direction);
});
then add a line where it checks the direction variable
if(direction == 'left')
var dw = container.width();
else if(direction =='right')
var dw = - container.width();
else{
console.log('Wrong direction')
return;
}
Carosal fixed
Don't forget to add argument on advanced function
For next slider you need:
$('#next').click(function(){
s.advance();
});
But anyway you have to construct universal animations methods with parameters.
Check this examples:
http://jsfiddle.net/lalatino/pjTU2/
and
http://sorgalla.com/projects/jcarousel/examples/static_controls.html

JavaScript Preventing User Text Selection

Something in this Curtains.js plug-in is preventing user text selection on my page. When I comment it out, I'm able to select text, when I put it back in, I'm not. Can someone identify it and tell me how to fix it? I'm at my wit's end.
<script>
/*
* Curtain.js - Create an unique page transitioning system
* ---
* Version: 2
* Copyright 2011, Victor Coulon (http://victorcoulon.fr)
* Released under the MIT Licence
*/
(function ( $, window, document, undefined ) {
var pluginName = 'curtain',
defaults = {
scrollSpeed: 400,
bodyHeight: 0,
linksArray: [],
mobile: false,
scrollButtons: {},
controls: null,
curtainLinks: '.curtain-links',
enableKeys: true,
easing: 'swing',
disabled: false,
nextSlide: function() {},
prevSlide: function() {}
};
// The actual plugin constructor
function Plugin( element, options ) {
var self = this;
// Public attributes
this.element = element;
this.options = $.extend( {}, defaults, options) ;
this._defaults = defaults;
this._name = pluginName;
this._ignoreHashChange = false;
this.init();
}
Plugin.prototype = {
init: function () {
var self = this;
// Cache element
this.$element = $(this.element);
this.$li = $(this.element).find('>li');
this.$liLength = this.$li.length;
self.$windowHeight = $(window).height();
self.$elDatas = {};
self.$document = $(document);
self.$window = $(window);
self.webkit = (navigator.userAgent.indexOf('Chrome') > -1 || navigator.userAgent.indexOf("Safari") > -1);
$.Android = (navigator.userAgent.match(/Android/i));
$.iPhone = ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)));
$.iPad = ((navigator.userAgent.match(/iPad/i)));
$.iOs4 = (/OS [1-4]_[0-9_]+ like Mac OS X/i.test(navigator.userAgent));
if($.iPhone || $.iPad || $.Android || self.options.disabled){
this.options.mobile = true;
this.$li.css({position:'relative'});
this.$element.find('.fixed').css({position:'absolute'});
}
if(this.options.mobile){
this.scrollEl = this.$element;
} else if($.browser.mozilla || $.browser.msie) {
this.scrollEl = $('html');
} else {
this.scrollEl = $('body');
}
if(self.options.controls){
self.options.scrollButtons['up'] = $(self.options.controls).find('[href="#up"]');
self.options.scrollButtons['down'] = $(self.options.controls).find('[href="#down"]');
if(!$.iOs4 && ($.iPhone || $.iPad)){
self.$element.css({
position:'fixed',
top:0,
left:0,
right:0,
bottom:0,
'-webkit-overflow-scrolling':'touch',
overflow:'auto'
});
$(self.options.controls).css({position:'absolute'});
}
}
// When all image is loaded
var callbackImageLoaded = function(){
self.setDimensions();
self.$li.eq(0).addClass('current');
self.setCache();
if(!self.options.mobile){
if(self.$li.eq(1).length)
self.$li.eq(1).nextAll().addClass('hidden');
}
self.setEvents();
self.setLinks();
self.isHashIsOnList(location.hash.substring(1));
};
if(self.$element.find('img').length)
self.imageLoaded(callbackImageLoaded);
else
callbackImageLoaded();
},
// Events
scrollToPosition: function (direction){
var position = null,
self = this;
if(self.scrollEl.is(':animated')){
return false;
}
if(direction === 'up' || direction == 'down'){
// Keyboard event
var $next = (direction === 'up') ? self.$current.prev() : self.$current.next();
// Step in the current panel ?
if(self.$step){
if(!self.$current.find('.current-step').length){
self.$step.eq(0).addClass('current-step');
}
var $nextStep = (direction === 'up') ? self.$current.find('.current-step').prev('.step') : self.$current.find('.current-step').next('.step');
if($nextStep.length) {
position = (self.options.mobile) ? $nextStep.position().top + self.$elDatas[self.$current.index()]['data-position'] : $nextStep.position().top + self.$elDatas[self.$current.index()]['data-position'];
}
}
position = position || ((self.$elDatas[$next.index()] === undefined) ? null : self.$elDatas[$next.index()]['data-position']);
if(position !== null){
self.scrollEl.animate({
scrollTop: position
}, self.options.scrollSpeed, self.options.easing);
}
} else if(direction === 'top'){
self.scrollEl.animate({
scrollTop:0
}, self.options.scrollSpeed, self.options.easing);
} else if(direction === 'bottom'){
self.scrollEl.animate({
scrollTop:self.options.bodyHeight
}, self.options.scrollSpeed, self.options.easing);
} else {
var index = $("#"+direction).index(),
speed = Math.abs(self.currentIndex-index) * (this.options.scrollSpeed*4) / self.$liLength;
self.scrollEl.animate({
scrollTop:self.$elDatas[index]['data-position'] || null
}, (speed <= self.options.scrollSpeed) ? self.options.scrollSpeed : speed, this.options.easing);
}
},
scrollEvent: function() {
var self = this,
docTop = self.$document.scrollTop();
if(docTop < self.currentP && self.currentIndex > 0){
// Scroll to top
self._ignoreHashChange = true;
if(self.$current.prev().attr('id'))
self.setHash(self.$current.prev().attr('id'));
self.$current
.removeClass('current')
.css( (self.webkit) ? {'-webkit-transform': 'translateY(0px) translateZ(0)'} : {marginTop: 0} )
.nextAll().addClass('hidden').end()
.prev().addClass('current').removeClass('hidden');
self.setCache();
self.options.prevSlide();
} else if(docTop < (self.currentP + self.currentHeight)){
// Animate the current pannel during the scroll
if(self.webkit)
self.$current.css({'-webkit-transform': 'translateY('+(-(docTop-self.currentP))+'px) translateZ(0)' });
else
self.$current.css({marginTop: -(docTop-self.currentP) });
// If there is a fixed element in the current panel
if(self.$fixedLength){
var dataTop = parseInt(self.$fixed.attr('data-top'), 10);
if(docTop + self.$windowHeight >= self.currentP + self.currentHeight){
self.$fixed.css({
position: 'fixed'
});
} else {
self.$fixed.css({
position: 'absolute',
marginTop: Math.abs(docTop-self.currentP)
});
}
}
// If there is a step element in the current panel
if(self.$stepLength){
$.each(self.$step, function(i,el){
if(($(el).position().top+self.currentP) <= docTop+5 && $(el).position().top + self.currentP + $(el).height() >= docTop+5){
if(!$(el).hasClass('current-step')){
self.$step.removeClass('current-step');
$(el).addClass('current-step');
return false;
}
}
});
}
if(self.parallaxBg){
self.$current.css({
'background-position-y': docTop * self.parallaxBg
});
}
if(self.$fade.length){
self.$fade.css({
'opacity': 1-(docTop/ self.$fade.attr('data-fade'))
});
}
if(self.$slowScroll.length){
self.$slowScroll.css({
'margin-top' : (docTop / self.$slowScroll.attr('data-slow-scroll'))
});
}
} else {
// Scroll bottom
self._ignoreHashChange = true;
if(self.$current.next().attr('id'))
self.setHash(self.$current.next().attr('id'));
self.$current.removeClass('current')
.addClass('hidden')
.next('li').addClass('current').next('li').removeClass('hidden');
self.setCache();
self.options.nextSlide();
}
},
scrollMobileEvent: function() {
var self = this,
docTop = self.$element.scrollTop();
if(docTop+10 < self.currentP && self.currentIndex > 0){
// Scroll to top
self._ignoreHashChange = true;
if(self.$current.prev().attr('id'))
self.setHash(self.$current.prev().attr('id'));
self.$current.removeClass('current').prev().addClass('current');
self.setCache();
self.options.prevSlide();
} else if(docTop+10 < (self.currentP + self.currentHeight)){
// If there is a step element in the current panel
if(self.$stepLength){
$.each(self.$step, function(i,el){
if(($(el).position().top+self.currentP) <= docTop && (($(el).position().top+self.currentP) + $(el).outerHeight()) >= docTop){
if(!$(el).hasClass('current-step')){
self.$step.removeClass('current-step');
$(el).addClass('current-step');
}
}
});
}
} else {
// Scroll bottom
self._ignoreHashChange = true;
if(self.$current.next().attr('id'))
self.setHash(self.$current.next().attr('id'));
self.$current.removeClass('current').next().addClass('current');
self.setCache();
self.options.nextSlide();
}
},
// Setters
setDimensions: function(){
var self = this,
levelHeight = 0,
cover = false,
height = null;
self.$windowHeight = self.$window.height();
this.$li.each(function(index) {
var $self = $(this);
cover = $self.hasClass('cover');
if(cover){
$self.css({height: self.$windowHeight, zIndex: 999-index})
.attr('data-height',self.$windowHeight)
.attr('data-position',levelHeight);
self.$elDatas[$self.index()] = {
'data-height': parseInt(self.$windowHeight,10),
'data-position': parseInt(levelHeight, 10)
};
levelHeight += self.$windowHeight;
} else{
height = ($self.outerHeight() <= self.$windowHeight) ? self.$windowHeight : $self.outerHeight();
$self.css({minHeight: height, zIndex: 999-index})
.attr('data-height',height)
.attr('data-position',levelHeight);
self.$elDatas[$self.index()] = {
'data-height': parseInt(height, 10),
'data-position': parseInt(levelHeight, 10)
};
levelHeight += height;
}
if($self.find('.fixed').length){
var top = $self.find('.fixed').css('top');
$self.find('.fixed').attr('data-top', top);
}
});
if(!this.options.mobile)
this.setBodyHeight();
},
setEvents: function() {
var self = this;
$(window).on('resize', function(){
self.setDimensions();
});
if(self.options.mobile) {
self.$element.on('scroll', function(){
self.scrollMobileEvent();
});
} else {
self.$window.on('scroll', function(){
self.scrollEvent();
});
}
if(self.options.enableKeys) {
self.$document.on('keydown', function(e){
if(e.keyCode === 38 || e.keyCode === 37) {
self.scrollToPosition('up');
e.preventDefault();
return false;
}
if(e.keyCode === 40 || e.keyCode === 39){
self.scrollToPosition('down');
e.preventDefault();
return false;
}
// Home button
if(e.keyCode === 36){
self.scrollToPosition('top');
e.preventDefault();
return false;
}
// End button
if(e.keyCode === 35){
self.scrollToPosition('bottom');
e.preventDefault();
return false;
}
});
}
if(self.options.scrollButtons){
if(self.options.scrollButtons.up){
self.options.scrollButtons.up.on('click', function(e){
e.preventDefault();
self.scrollToPosition('up');
});
}
if(self.options.scrollButtons.down){
self.options.scrollButtons.down.on('click', function(e){
e.preventDefault();
self.scrollToPosition('down');
});
}
}
if(self.options.curtainLinks){
$(self.options.curtainLinks).on('click', function(e){
e.preventDefault();
var href = $(this).attr('href');
if(!self.isHashIsOnList(href.substring(1)) && position)
return false;
var position = self.$elDatas[$(href).index()]['data-position'] || null;
if(position){
self.scrollEl.animate({
scrollTop:position
}, self.options.scrollSpeed, self.options.easing);
}
return false;
});
}
self.$window.on("hashchange", function(event){
if(self._ignoreHashChange === false){
self.isHashIsOnList(location.hash.substring(1));
}
self._ignoreHashChange = false;
});
},
setBodyHeight: function(){
var h = 0;
for (var key in this.$elDatas) {
var obj = this.$elDatas[key];
h += obj['data-height'];
}
this.options.bodyHeight = h;
$('body').height(h);
},
setLinks: function(){
var self = this;
this.$li.each(function() {
var id = $(this).attr('id') || 0;
self.options.linksArray.push(id);
});
},
setHash: function(hash){
// "HARD FIX"
el = $('[href=#'+hash+']');
el.parent().siblings('li').removeClass('active');
el.parent().addClass('active');
if(history.pushState) {
history.pushState(null, null, '#'+hash);
}
else {
location.hash = hash;
}
},
setCache: function(){
var self = this;
self.$current = self.$element.find('.current');
self.$fixed = self.$current.find('.fixed');
self.$fixedLength = self.$fixed.length;
self.$step = self.$current.find('.step');
self.$stepLength = self.$step.length;
self.currentIndex = self.$current.index();
self.currentP = self.$elDatas[self.currentIndex]['data-position'];
self.currentHeight = self.$elDatas[self.currentIndex]['data-height'];
self.parallaxBg = self.$current.attr('data-parallax-background');
self.$fade = self.$current.find('[data-fade]');
self.$slowScroll = self.$current.find('[data-slow-scroll]');
},
// Utils
isHashIsOnList: function(hash){
var self = this;
$.each(self.options.linksArray, function(i,val){
if(val === hash){
self.scrollToPosition(hash);
return false;
}
});
},
readyElement: function(el,callback){
var interval = setInterval(function(){
if(el.length){
callback(el.length);
clearInterval(interval);
}
},60);
},
imageLoaded: function(callback){
var self = this,
elems = self.$element.find('img'),
len = elems.length,
blank = "data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==";
elems.bind('load.imgloaded',function(){
if (--len <= 0 && this.src !== blank || $(this).not(':visible')){
elems.unbind('load.imgloaded');
callback.call(elems,this);
}
}).each(function(){
if (this.complete || this.complete === undefined){
var src = this.src;
this.src = blank;
this.src = src;
}
});
}
};
$.fn[pluginName] = function ( options ) {
return this.each(function () {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName, new Plugin( this, options ));
}
});
};
})( jQuery, window, document );
</script>
First you would have to tell us how you are trying to select text (mouse, keyboard, touchscreen, etc.)
I bet my bitcoins on keyboard (but I don't have any).
Must be one of those
self.$document.on('keydown', function(e){
...
e.preventDefault();
which don't even document which keys these numbers stand for.
It's e.preventDefault() which prevents the default browser action from being performed.
If you're in Chrome devtools, you can use
monitorEvents(window, 'key')
to make sense of these.
Of course this bit may help a bit:
keyCode: 38
keyIdentifier: "Up"
So the code could be written readably by use of keyIdentifier instead of keyCode.
I don't know how compatible that would be across browsers.
Be warned that keydown keyCode values are different from keypress values (which actually insert real characters). keydown key codes will vary between keyboard layouts and locales.
See http://unixpapa.com/js/key.html for disgust and enlightenment, but mostly disgust.

Making a slider without recursion

Given the following jsFiddle, how can I implement the same effect as I have made without building on the stack?
http://jsfiddle.net/YWMcy/1/
I tried doing something like this:
jQuery(document).ready(function () {
'use strict';
(function ($) {
function validateOptions(options) {
if (typeof(options.delay) == typeof(0)) {
$.error('Delay value must an integer.');
return false;
} else if (options.delay < 0) {
$.error('Delay value must be greater than zero.');
return false;
}
if (typeof(options.direction) == typeof('')) {
$.error('Direction value must be a string.');
return false;
} else if (!(options.direction in ['left', 'right', 'up', 'down'])) {
$.error('Direction value must be "left", "right", "up", or "down".');
return false;
}
if (typeof(options.easing) == typeof('')) {
$.error('Easing value must be a string.');
return false;
}
if (typeof(options.selector) == typeof('')) {
$.error('Selector value must be a string.');
return false;
}
if (options.transition < 0) {
$.error('Transition value must be greater than zero.');
return false;
}
return true;
}
var methods = {
init: function (options) {
return this.each(function () {
var settings = {
delay: 5000,
direction: 'left',
easing: 'swing',
selector: '*',
transition: 3000
};
if (options) {
$.extend(settings, options);
}
$(this).css({
overflow: 'hidden',
position: 'relative'
});
var styles = {
left: 0,
position: 'absolute',
top: 0
};
switch (settings.direction) {
case 'left':
styles.left = $(this).width() + 'px';
break;
case 'right':
styles.left = -$(this).width() + 'px';
break;
case 'up':
styles.top = $(this).height() + 'px';
break;
case 'down':
styles.top = -$(this).height() + 'px';
break;
default:
jQuery.error('Direction ' + settings.direction + ' is not valid for jQuery.fn.cycle');
break;
}
$(this).children(settings.selector).css(styles).first().css({
left: 0,
top: 0
});
if ($(this).children(settings.selector).length > 1) {
$(this).cycle('slide', settings);
}
});
},
slide: function (options) {
return this.each(function () {
var settings = {
delay: 5000,
direction: 'left',
easing: 'swing',
selector: '*',
transition: 3000
}, animation, property, value;
if (options) {
$.extend(settings, options);
}
switch (settings.direction) {
case 'left':
animation = {left: '-=' + $(this).width()};
property = 'left';
value = $(this).width();
break;
case 'right':
animation = {left: '+=' + $(this).width()};
property = 'left';
value = -$(this).width();
break;
case 'up':
animation = {top: '-=' + $(this).height()};
property = 'top';
value = $(this).height();
break;
case 'down':
animation = {top: '+=' + $(this).height()};
property = 'top';
value = -$(this).height();
break;
default:
jQuery.error('Direction ' + settings.direction + ' is not valid for jQuery.fn.cycle');
break;
}
$(this).children(settings.selector + ':first-child').each(function () {
$(this).delay(settings.delay);
$(this).animate(
animation,
settings.transition,
settings.easing,
function () {
$(this).css(property, value);
}
);
});
$(this).append($(this).children(settings.selector + ':first-child').detach());
$(this).children(settings.selector + ':first-child').each(function () {
$(this).delay(settings.delay);
$(this).animate(
animation,
settings.transition,
settings.easing,
function () {
$(this).parent().cycle('slide', settings);
}
);
});
});
}
};
jQuery.fn.cycle = function (method, options) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
$.error('Method ' + method + ' does not exist on jQuery.fn.cycle');
}
};
}(jQuery));
jQuery('.slider').cycle();
});
But the each() method does not take into account nodes that are added during the loop.
You can launch your _cycle() function through setInterval(), to periodically update the slider:
setInterval(function() {
_cycle2(slider, transition_duration, easing);
}, delay_duration);
Note that I renamed your original _cycle() function to _cycle2(), and removed the delay_duration parameter. You can see a working demo here.
You don't want anything resembling while(true).
Your problem stems from the fact that you're creating a static function and then trying to figure out how to animate the children with the constraint of keeping it all in scope of your static function.
You should instead create an instance of an object per element, let the object maintain the state of the slider and have it update that state via an implementation necessary for the slider to operate.
http://jsfiddle.net/qjVJF/3/
(function ($) {
var $b = $.behaviors || {};
$b.slider = function(element, options) {
this.element = $(element);
this.panels = this.element.find('.slide');
this.options = $.extend({}, $b.slider.defaults, options);
this.currentPanel = 0;
var horizontal = (this.options.direction == 'left' || this.options.direction == 'right');
var anti = (this.options.direction == 'left' || this.options.direction == 'up');
var distance = horizontal ? '600' : '150';
this.action = anti ? '-='+distance : '+='+distance;
this.origin = anti ? distance : 0-distance;
this.edge = horizontal ? 'left' : 'top';
this.animation = horizontal ? { "left": this.action } : { "top" : this.action };
this.panels.css(this.edge, this.origin+'px').show().first().css(this.edge, '0px');
this.delayNext();
return this;
}
$b.slider.defaults = {
delay: 500,
direction: 'left',
easing: 'swing',
transition: 3000
};
$b.slider.prototype = {
delayNext: function() {
setTimeout($.proxy(this.slideNext, this), this.options.delay);
},
slideNext: function() {
var current = this.panels[this.currentPanel % this.panels.length];
var next = $(this.panels[++this.currentPanel % this.panels.length])
.css(this.edge, this.origin+'px');
var plugin = this;
next.add(current).animate(
this.animation,
this.options.transition,
this.options.easing,
function() {
if (this == current) plugin.delayNext();
}
);
}
};
$.fn.cycle = function (options) {
return this.each(function() {
$(this).data('bCycle', new $b.slider(this, options));
});
};
}(jQuery));
jQuery(document).ready(function () {
jQuery('.slider').cycle();
});
Maybe this plugin http://docs.jquery.com/Plugins/livequery can help you?
Live Query utilizes the power of jQuery selectors by binding events or firing callbacks for matched elements auto-magically, even after the page has been loaded and the DOM updated.
For example you could use the following code to bind a click event to all A tags, even any A tags you might add via AJAX.
$('a')
.livequery('click', function(event) {
alert('clicked');
return false;
});

Categories

Resources