I am trying to make two carousel-indicators with Bootstrap 3.2 which has proven difficult with my relatively beginner JavaScript skills. I've tried adding in two carousel-indicators list items, but it only effects on set of indicators. How can I have two carousel-indicators for one carousel? Thanks!
JavaScript from Bootstrap.
+function ($) {
'use strict';
// CAROUSEL CLASS DEFINITION
// =========================
var Carousel = function (element, options) {
this.$element = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this))
this.$indicators = this.$element.find('.carousel-indicators')
this.options = options
this.paused =
this.sliding =
this.interval =
this.$active =
this.$items = null
this.options.pause == 'hover' && this.$element
.on('mouseenter.bs.carousel', $.proxy(this.pause, this))
.on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
}
Carousel.VERSION = '3.2.0'
Carousel.TRANSITION_DURATION = 600
Carousel.DEFAULTS = {
interval: 5000,
pause: 'hover',
wrap: true
}
Carousel.prototype.keydown = function (e) {
switch (e.which) {
case 37: this.prev(); break
case 39: this.next(); break
default: return
}
e.preventDefault()
}
Carousel.prototype.cycle = function (e) {
e || (this.paused = false)
this.interval && clearInterval(this.interval)
this.options.interval
&& !this.paused
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
return this
}
Carousel.prototype.getItemIndex = function (item) {
this.$items = item.parent().children('.item')
return this.$items.index(item || this.$active)
}
Carousel.prototype.getItemForDirection = function (direction, active) {
var delta = direction == 'prev' ? -1 : 1
var activeIndex = this.getItemIndex(active)
var itemIndex = (activeIndex + delta) % this.$items.length
return this.$items.eq(itemIndex)
}
Carousel.prototype.to = function (pos) {
var that = this
var activeIndex = this.getItemIndex(this.$active = this.$element.find('.item.active'))
if (pos > (this.$items.length - 1) || pos < 0) return
if (this.sliding) return this.$element.one('slid.bs.carousel', function () { that.to(pos) }) // yes, "slid"
if (activeIndex == pos) return this.pause().cycle()
return this.slide(pos > activeIndex ? 'next' : 'prev', this.$items.eq(pos))
}
Carousel.prototype.pause = function (e) {
e || (this.paused = true)
if (this.$element.find('.next, .prev').length && $.support.transition) {
this.$element.trigger($.support.transition.end)
this.cycle(true)
}
this.interval = clearInterval(this.interval)
return this
}
Carousel.prototype.next = function () {
if (this.sliding) return
return this.slide('next')
}
Carousel.prototype.prev = function () {
if (this.sliding) return
return this.slide('prev')
}
Carousel.prototype.slide = function (type, next) {
var $active = this.$element.find('.item.active')
var $next = next || this.getItemForDirection(type, $active)
var isCycling = this.interval
var direction = type == 'next' ? 'left' : 'right'
var fallback = type == 'next' ? 'first' : 'last'
var that = this
if (!$next.length) {
if (!this.options.wrap) return
$next = this.$element.find('.item')[fallback]()
}
if ($next.hasClass('active')) return (this.sliding = false)
var relatedTarget = $next[0]
var slideEvent = $.Event('slide.bs.carousel', {
relatedTarget: relatedTarget,
direction: direction
})
this.$element.trigger(slideEvent)
if (slideEvent.isDefaultPrevented()) return
this.sliding = true
isCycling && this.pause()
if (this.$indicators.length) {
this.$indicators.find('.active').removeClass('active')
var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
$nextIndicator && $nextIndicator.addClass('active')
}
var slidEvent = $.Event('slid.bs.carousel', { relatedTarget: relatedTarget, direction: direction }) // yes, "slid"
if ($.support.transition && this.$element.hasClass('slide')){
$next.addClass(type)
$next[0].offsetWidth // force reflow
$active.addClass(direction)
$next.addClass(direction)
$active
.one('bsTransitionEnd', function () {
$next.removeClass([type, direction].join(' ')).addClass('active')
$active.removeClass(['active', direction].join(' '))
that.sliding = false
setTimeout(function () {
that.$element.trigger(slidEvent)
}, 0)
})
.emulateTransitionEnd(Carousel.TRANSITION_DURATION)
} else {
$active.removeClass('active')
$next.addClass('active')
this.sliding = false
this.$element.trigger(slidEvent)
}
isCycling && this.cycle()
return this
}
// CAROUSEL PLUGIN DEFINITION
// ==========================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.carousel')
var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
var action = typeof option == 'string' ? option : options.slide
if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
if (typeof option == 'number') data.to(option)
else if (action) data[action]()
else if (options.interval) data.pause().cycle()
})
}
var old = $.fn.carousel
$.fn.carousel = Plugin
$.fn.carousel.Constructor = Carousel
// CAROUSEL NO CONFLICT
// ====================
$.fn.carousel.noConflict = function () {
$.fn.carousel = old
return this
}
// CAROUSEL DATA-API
// =================
$(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
var href
var $this = $(this)
var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
if (!$target.hasClass('carousel')) return
var options = $.extend({}, $target.data(), $this.data())
var slideIndex = $this.attr('data-slide-to')
if (slideIndex) options.interval = false
Plugin.call($target, options)
if (slideIndex) {
$target.data('bs.carousel').to(slideIndex)
}
e.preventDefault()
})
$(window).on('load', function () {
$('[data-ride="carousel"]').each(function () {
var $carousel = $(this)
Plugin.call($carousel, $carousel.data())
})
})
}(jQuery);
HTML markup
<div id="slider1" class="carousel slide" data-ride="carousel">
<!-- Indicators -->
<ol class="carousel-indicators">
<li data-target="#slider1" data-slide-to="0" class="active"></li>
<li data-target="#slider1" data-slide-to="1"></li>
<li data-target="#slider1" data-slide-to="2"></li>
<li data-target="#slider1" data-slide-to="3"></li>
<li data-target="#slider1" data-slide-to="4"></li>
<li data-target="#slider1" data-slide-to="5"></li>
</ol>
<!-- Wrapper for slides -->
<div class="carousel-inner">
<div class="item active">
<img src="assets/images/slider1image1.png">
<div class="carousel-caption">
<p class="new-products">NEW PRODUCTS</p>
<h2>CYCLONE DRY/WET VACUUM BRAZED CORE DRILL BIT</h2>
</div>
</div>
<div class="item">
<img src="assets/images/slider1image1.png">
<div class="carousel-caption">
<p class="new-products">NEW PRODUCTS</p>
<h2>CYCLONE DRY/WET VACUUM BRAZED CORE DRILL BIT</h2>
</div>
</div>
<div class="item">
<img src="assets/images/slider1image1.png">
<div class="carousel-caption">
<p class="new-products">NEW PRODUCTS</p>
<h2>CYCLONE DRY/WET VACUUM BRAZED CORE DRILL BIT</h2>
</div>
</div>
<div class="item">
<img src="assets/images/slider1image1.png">
<div class="carousel-caption">
<p class="new-products">NEW PRODUCTS</p>
<h2>CYCLONE DRY/WET VACUUM BRAZED CORE DRILL BIT</h2>
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#slider1" role="button" data-slide="prev">
<img src="assets/images/slider1-caret-left.png">
</a>
<a class="right carousel-control" href="#slider1" role="button" data-slide="next">
<img src="assets/images/slider1-caret-right.png">
</a
My solution isn't perfect in my case but maybe it'll helps you :)
I use the function :
$('#carousel-example-generic').on('slide.bs.carousel', function () {
// stuffs
}
This action is call when the next carousel item is gonna be changed.
Then you can add your own code, changing the CSS of the second unchangeable set of indicators.
My example :
$('#carousel-example-generic').on('slide.bs.carousel', function () {
var slide_number = $('.carousel-indicators_custom')
.children('.active')
.children('.losange').attr('data-slide-to');
// here slide number need to be parseInt and you'll certainly need to add +1 value
$('.carousel-indicators_custom-mobile>li').css('color', '#333');
$('.carousel-indicators_custom-mobile').find('li[data-slide-to=' + slide_number +']').css('color', '#be1522');
$('.dynamic_puce__text').html( $('.carousel-indicators_custom-mobile').find('li[data-slide-to=' + slide_number +']').html() );
});
It's a little bit ugly but it's a beginning even I'm sure their are better choices.
Related
I want to check the inputs for each tab.
My code so far: jsfiddle
$(document).ready(function () {
var tabs = $("#mytabs").tabs();
var validator = $("#formItem").validate();
$(".next-button").click(function () {
//var selected = $("#tabs").tabs("option", "selected");
//$("#tabs").tabs("option", "selected", selected + 1);
var valid = true;
var i = 0;
var $inputs = $(this).closest("div").find("input");
$inputs.each(function () {
if (!validator.element(this) && valid) {
valid = false;
}
});
if (valid) {
$("#mytabs").tabs("option", "current", 1);
}
});
//use link to submit form instead of button
$("button[id=finish_button]").click(function () {
$(this).parents("form").submit();
});
});
You need to find closest div but with class i.e tab-content or you can use the respective id as in your current implementation there is a next button for each tab. So use unique id of your div.
You currently have following defined which is incorrect,
var $inputs = $(this).closest("div").find("input");
Fix it to,
$(".next-button").click(function() {
//var selected = $("#tabs").tabs("option", "selected");
//$("#tabs").tabs("option", "selected", selected + 1);
var valid = true;
var i = 0;
var $inputs = $(this).closest("div#tabs-1").find("input");
//var $inputs = $(this).closest("div.tab-content").find("input");
$inputs.each(function() {
if (!validator.element(this) && valid) {
valid = false;
}
});
if (valid) {
$("#mytabs").tabs("option", "current", 1);
}
});
try this code.
here's a codepen
and Here's the code. It is not working here for some reason but you can see it working in codepen
+function ($) {
'use strict';
// VALIDATOR CLASS DEFINITION
// ==========================
var Validator = function (element, options) {
this.$element = $(element)
this.options = options
options.errors = $.extend({}, Validator.DEFAULTS.errors, options.errors)
for (var custom in options.custom) {
if (!options.errors[custom]) throw new Error('Missing default error message for custom validator: ' + custom)
}
$.extend(Validator.VALIDATORS, options.custom)
this.$element.attr('novalidate', true) // disable automatic native validation
this.toggleSubmit()
this.$element.on('input.bs.validator change.bs.validator focusout.bs.validator', $.proxy(this.validateInput, this))
this.$element.on('submit.bs.validator', $.proxy(this.onSubmit, this))
this.$element.find('[data-match]').each(function () {
var $this = $(this)
var target = $this.data('match')
$(target).on('input.bs.validator', function (e) {
$this.val() && $this.trigger('input.bs.validator')
})
})
}
Validator.INPUT_SELECTOR = ':input:not([type="submit"], button):enabled:visible'
Validator.DEFAULTS = {
delay: 500,
html: false,
disable: true,
custom: {},
errors: {
match: 'Does not match',
minlength: 'Not long enough'
},
feedback: {
success: 'glyphicon-ok',
error: 'glyphicon-remove'
}
}
Validator.VALIDATORS = {
'native': function ($el) {
var el = $el[0]
return el.checkValidity ? el.checkValidity() : true
},
'match': function ($el) {
var target = $el.data('match')
return !$el.val() || $el.val() === $(target).val()
},
'minlength': function ($el) {
var minlength = $el.data('minlength')
return !$el.val() || $el.val().length >= minlength
}
}
Validator.prototype.validateInput = function (e) {
var $el = $(e.target)
var prevErrors = $el.data('bs.validator.errors')
var errors
if ($el.is('[type="radio"]')) $el = this.$element.find('input[name="' + $el.attr('name') + '"]')
this.$element.trigger(e = $.Event('validate.bs.validator', {relatedTarget: $el[0]}))
if (e.isDefaultPrevented()) return
var self = this
this.runValidators($el).done(function (errors) {
$el.data('bs.validator.errors', errors)
errors.length ? self.showErrors($el) : self.clearErrors($el)
if (!prevErrors || errors.toString() !== prevErrors.toString()) {
e = errors.length
? $.Event('invalid.bs.validator', {relatedTarget: $el[0], detail: errors})
: $.Event('valid.bs.validator', {relatedTarget: $el[0], detail: prevErrors})
self.$element.trigger(e)
}
self.toggleSubmit()
self.$element.trigger($.Event('validated.bs.validator', {relatedTarget: $el[0]}))
})
}
Validator.prototype.runValidators = function ($el) {
var errors = []
var deferred = $.Deferred()
var options = this.options
$el.data('bs.validator.deferred') && $el.data('bs.validator.deferred').reject()
$el.data('bs.validator.deferred', deferred)
function getErrorMessage(key) {
return $el.data(key + '-error')
|| $el.data('error')
|| key == 'native' && $el[0].validationMessage
|| options.errors[key]
}
$.each(Validator.VALIDATORS, $.proxy(function (key, validator) {
if (($el.data(key) || key == 'native') && !validator.call(this, $el)) {
var error = getErrorMessage(key)
!~errors.indexOf(error) && errors.push(error)
}
}, this))
if (!errors.length && $el.val() && $el.data('remote')) {
this.defer($el, function () {
var data = {}
data[$el.attr('name')] = $el.val()
$.get($el.data('remote'), data)
.fail(function (jqXHR, textStatus, error) { errors.push(getErrorMessage('remote') || error) })
.always(function () { deferred.resolve(errors)})
})
} else deferred.resolve(errors)
return deferred.promise()
}
Validator.prototype.validate = function () {
var delay = this.options.delay
this.options.delay = 0
this.$element.find(Validator.INPUT_SELECTOR).trigger('input.bs.validator')
this.options.delay = delay
return this
}
Validator.prototype.showErrors = function ($el) {
var method = this.options.html ? 'html' : 'text'
this.defer($el, function () {
var $group = $el.closest('.form-group')
var $block = $group.find('.help-block.with-errors')
var $feedback = $group.find('.form-control-feedback')
var errors = $el.data('bs.validator.errors')
if (!errors.length) return
errors = $('<ul/>')
.addClass('list-unstyled')
.append($.map(errors, function (error) { return $('<li/>')[method](error) }))
$block.data('bs.validator.originalContent') === undefined && $block.data('bs.validator.originalContent', $block.html())
$block.empty().append(errors)
$group.addClass('has-error')
$feedback.length
&& $feedback.removeClass(this.options.feedback.success)
&& $feedback.addClass(this.options.feedback.error)
&& $group.removeClass('has-success')
})
}
Validator.prototype.clearErrors = function ($el) {
var $group = $el.closest('.form-group')
var $block = $group.find('.help-block.with-errors')
var $feedback = $group.find('.form-control-feedback')
$block.html($block.data('bs.validator.originalContent'))
$group.removeClass('has-error')
$feedback.length
&& $feedback.removeClass(this.options.feedback.error)
&& $feedback.addClass(this.options.feedback.success)
&& $group.addClass('has-success')
}
Validator.prototype.hasErrors = function () {
function fieldErrors() {
return !!($(this).data('bs.validator.errors') || []).length
}
return !!this.$element.find(Validator.INPUT_SELECTOR).filter(fieldErrors).length
}
Validator.prototype.isIncomplete = function () {
function fieldIncomplete() {
return this.type === 'checkbox' ? !this.checked :
this.type === 'radio' ? !$('[name="' + this.name + '"]:checked').length :
$.trim(this.value) === ''
}
return !!this.$element.find(Validator.INPUT_SELECTOR).filter('[required]').filter(fieldIncomplete).length
}
Validator.prototype.onSubmit = function (e) {
this.validate()
if (this.isIncomplete() || this.hasErrors()) e.preventDefault()
}
Validator.prototype.toggleSubmit = function () {
if(!this.options.disable) return
var $btn = $('button[type="submit"], input[type="submit"]')
.filter('[form="' + this.$element.attr('id') + '"]')
.add(this.$element.find('input[type="submit"], button[type="submit"]'))
$btn.toggleClass('disabled', this.isIncomplete() || this.hasErrors())
}
Validator.prototype.defer = function ($el, callback) {
callback = $.proxy(callback, this)
if (!this.options.delay) return callback()
window.clearTimeout($el.data('bs.validator.timeout'))
$el.data('bs.validator.timeout', window.setTimeout(callback, this.options.delay))
}
Validator.prototype.destroy = function () {
this.$element
.removeAttr('novalidate')
.removeData('bs.validator')
.off('.bs.validator')
this.$element.find(Validator.INPUT_SELECTOR)
.off('.bs.validator')
.removeData(['bs.validator.errors', 'bs.validator.deferred'])
.each(function () {
var $this = $(this)
var timeout = $this.data('bs.validator.timeout')
window.clearTimeout(timeout) && $this.removeData('bs.validator.timeout')
})
this.$element.find('.help-block.with-errors').each(function () {
var $this = $(this)
var originalContent = $this.data('bs.validator.originalContent')
$this
.removeData('bs.validator.originalContent')
.html(originalContent)
})
this.$element.find('input[type="submit"], button[type="submit"]').removeClass('disabled')
this.$element.find('.has-error').removeClass('has-error')
return this
}
// VALIDATOR PLUGIN DEFINITION
// ===========================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var options = $.extend({}, Validator.DEFAULTS, $this.data(), typeof option == 'object' && option)
var data = $this.data('bs.validator')
if (!data && option == 'destroy') return
if (!data) $this.data('bs.validator', (data = new Validator(this, options)))
if (typeof option == 'string') data[option]()
})
}
var old = $.fn.validator
$.fn.validator = Plugin
$.fn.validator.Constructor = Validator
// VALIDATOR NO CONFLICT
// =====================
$.fn.validator.noConflict = function () {
$.fn.validator = old
return this
}
// VALIDATOR DATA-API
// ==================
$(window).on('load', function () {
$('form[data-toggle="validator"]').each(function () {
var $form = $(this)
Plugin.call($form, $form.data())
})
})
}(jQuery);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="contact-form">
<form data-toggle="validator" action="contact_script" method="post" role="form">
<div class="form-group">
<input name="name" type="text" class="form-control input-lg" placeholder="Your Name" required>
</div>
<div class="form-group">
<input name="email" type="email" class="form-control input-lg" placeholder="E-mail" required>
</div>
<div class="form-group">
<input name="phone" type="text" class="form-control input-lg" placeholder="Contact No." required>
</div>
<div class="form-group">
<input name="subject" type="text" class="form-control input-lg" placeholder="Subject" required>
</div>
<div class="form-group">
<textarea name="message" class="form-control input-lg" rows="5" placeholder="Message"></textarea>
</div>
<button type="submit" class="btn wow bounceInRight" data-wow-delay="0.8s">Send</button>
</form>
</div>
I'm using carousel.js, but when I use the controls, it starts to get buggy.
What I've noticed is:
When the autoplay showed all images and wants to show the first one again, it shows the first one for 0.5 seconds and returns to the last image and stays there.
The same goes for using the next button, it starts to bug at the last image (same as autoplay).
The prev button works fine, when I use that it doesn't show any problems at all.
When I remove the buttons, it works fine, no errors at all (Autoplay works fine).
Now the error that shows in console is: Uncaught TypeError: Cannot read property 'slice' of undefined, but I don't think this is the core of the error.
Because what I've noticed in inspect element is that when the error occurs, none of the images in the slides have the class: 'active' anymore, so the code won't work anymore. But I'm not sure what the cause of this is.
This is the code from my controls:
<a class="left carousel-control" href="#carousel-{$id}" data-slide="prev" role="button">
<span class="icon-arrow_left_nav icon-arrow-left2""></span>
</a>
<a class="right carousel-control" href="#carousel-{$id}" data-slide="next" role="button">
<span class="icon-arrow_right_nav icon-arrow-right2"></span>
</a>
And this is the code from the carousel.js file (standard)
/* ========================================================================
* Bootstrap: carousel.js v3.2.0
* http://getbootstrap.com/javascript/#carousel
* ========================================================================
* Copyright 2011-2014 Twitter, Inc.
* Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
* ======================================================================== */
+function ($) {
'use strict';
// CAROUSEL CLASS DEFINITION
// =========================
var Carousel = function (element, options) {
this.$element = $(element).on('keydown.bs.carousel', $.proxy(this.keydown, this))
this.$indicators = this.$element.find('.carousel-indicators')
this.options = options
this.paused =
this.sliding =
this.interval =
this.$active =
this.$items = null
this.options.pause == 'hover' && this.$element
.on('mouseenter.bs.carousel', $.proxy(this.pause, this))
.on('mouseleave.bs.carousel', $.proxy(this.cycle, this))
}
Carousel.VERSION = '3.2.0'
Carousel.DEFAULTS = {
interval: 5000,
pause: 'hover',
wrap: true
}
Carousel.prototype.keydown = function (e) {
switch (e.which) {
case 37:
this.prev();
break
case 39:
this.next();
break
default:
return
}
e.preventDefault()
}
Carousel.prototype.cycle = function (e) {
e || (this.paused = false)
this.interval && clearInterval(this.interval)
this.options.interval
&& !this.paused
&& (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
return this
}
Carousel.prototype.getItemIndex = function (item) {
this.$items = item.parent().children('div.item')
return this.$items.index(item || this.$active)
}
Carousel.prototype.to = function (pos) {
var that = this
var activeIndex = this.getItemIndex(this.$active = this.$element.find('div.item.active'))
if (pos > (this.$items.length - 1) || pos < 0) return
if (this.sliding) return this.$element.one('slid.bs.carousel', function () {
that.to(pos)
}) // yes, "slid"
if (activeIndex == pos) return this.pause().cycle()
return this.slide(pos > activeIndex ? 'next' : 'prev', $(this.$items[pos]))
}
Carousel.prototype.pause = function (e) {
e || (this.paused = true)
if (this.$element.find('.next, .prev').length && $.support.transition) {
this.$element.trigger($.support.transition.end)
this.cycle(true)
}
this.interval = clearInterval(this.interval)
return this
}
Carousel.prototype.next = function () {
if (this.sliding) return
return this.slide('next')
}
Carousel.prototype.prev = function () {
if (this.sliding) return
return this.slide('prev')
}
Carousel.prototype.slide = function (type, next) {
var $active = this.$element.find('div.item.active')
var $next = next || $active[type]()
var isCycling = this.interval
var direction = type == 'next' ? 'left' : 'right'
var fallback = type == 'next' ? 'first' : 'last'
var that = this
if (!$next.length) {
if (!this.options.wrap) return
$next = this.$element.find('div.item')[fallback]()
}
if ($next.hasClass('active')) return (this.sliding = false)
var relatedTarget = $next[0]
var slideEvent = $.Event('slide.bs.carousel', {
relatedTarget: relatedTarget,
direction: direction
})
this.$element.trigger(slideEvent)
if (slideEvent.isDefaultPrevented()) return
this.sliding = true
isCycling && this.pause()
if (this.$indicators.length) {
this.$indicators.find('.active').removeClass('active')
var $nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)])
$nextIndicator && $nextIndicator.addClass('active')
}
var slidEvent = $.Event('slid.bs.carousel', {relatedTarget: relatedTarget, direction: direction}) // yes, "slid"
if ($.support.transition && this.$element.hasClass('slide')) {
$next.addClass(type)
$next[0].offsetWidth // force reflow
$active.addClass(direction)
$next.addClass(direction)
$active
.one('bsTransitionEnd', function () {
$next.removeClass([type, direction].join(' ')).addClass('active')
$active.removeClass(['active', direction].join(' '))
that.sliding = false
setTimeout(function () {
that.$element.trigger(slidEvent)
}, 0)
})
.emulateTransitionEnd($active.css('transition-duration').slice(0, -1) * 1000)
} else {
$active.removeClass('active')
$next.addClass('active')
this.sliding = false
this.$element.trigger(slidEvent)
}
isCycling && this.cycle()
return this
}
// CAROUSEL PLUGIN DEFINITION
// ==========================
function Plugin(option) {
return this.each(function () {
var $this = $(this)
var data = $this.data('bs.carousel')
var options = $.extend({}, Carousel.DEFAULTS, $this.data(), typeof option == 'object' && option)
var action = typeof option == 'string' ? option : options.slide
if (!data) $this.data('bs.carousel', (data = new Carousel(this, options)))
if (typeof option == 'number') data.to(option)
else if (action) data[action]()
else if (options.interval) data.pause().cycle()
})
}
var old = $.fn.carousel
$.fn.carousel = Plugin
$.fn.carousel.Constructor = Carousel
// CAROUSEL NO CONFLICT
// ====================
$.fn.carousel.noConflict = function () {
$.fn.carousel = old
return this
}
// CAROUSEL DATA-API
// =================
$(document).on('click.bs.carousel.data-api', '[data-slide], [data-slide-to]', function (e) {
var href
var $this = $(this)
var $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) // strip for ie7
if (!$target.hasClass('carousel')) return
var options = $.extend({}, $target.data(), $this.data())
var slideIndex = $this.attr('data-slide-to')
if (slideIndex) options.interval = false
Plugin.call($target, options)
if (slideIndex) {
$target.data('bs.carousel').to(slideIndex)
}
e.preventDefault()
})
$(window).on('load', function () {
$('[data-ride="carousel"]').each(function () {
var $carousel = $(this)
Plugin.call($carousel, $carousel.data())
})
})
}(jQuery);
in bootstrap/js/carousel.js, the slide function of Carousel has a line below:
$next[0].offsetWidth // force reflow
With this line, the transition of next slide work currently after the transition of active slide. But, without this line, the transition of next slide do not work. That make me confused.
Just want to know, how the code above make that effect. Thank you!
i paste the slide function below:
Carousel.prototype.slide = function(type, next){
var $active = this.$element.find('.item.active');
var $next = next || this.getItemForDirection(type, $active);
var isCycling = this.interval;
var direction = type == 'prev' ? 'right' : 'left'
var that = this;
if($next.hasClass('active')) return this.sliding = false;
this.sliding = true;
var relatedTarget = $next[0];
isCycling && this.pause();
if(this.$indicators.length){
this.$indicators.find('.active').removeClass('active');
var nextIndicator = $(this.$indicators.children()[this.getItemIndex($next)]);
nextIndicator && nextIndicator.addClass('active');
}
var slideEvent = $.Event('carousel.slide.after', {relatedTarget: relatedTarget, direction: direction});
if($.support.transition && this.$element.hasClass('slide')){
$next.addClass(type);
$next[0].offsetWidth // force reflow
$active.addClass(direction);
$next.addClass(direction);
$active.one($.support.transition.end, function(e){
$next.removeClass([type, direction].join(' ')).addClass('active');
$active.removeClass(['active', direction].join(' '));
that.sliding = false;
setTimeout(function(){
that.$element.trigger(slideEvent);
}, 0)
})
.emulateTransitionEnd(Carousel.TRANSITION_DURATION);
}else{
$active.removeClass('active');
$next.addClass('active');
this.sliding = false;
}
isCycling && this.cycle();
};
I have a jQuery slider on my website.
I managed to make the slider move automatically between only two navigation links, however there are four navigation links.
How can I make it that it moves orderwise from the first navigation link till the fourth link with a defined delay.
Here is the HTML code with the navigation links at the bottom:
<div id="mi-slider" class="mi-slider">
<ul>
<li><img src="images/1.jpg" alt="img01"><h4>Boots</h4></li>
<li><img src="images/2.jpg" alt="img02"><h4>Oxfords</h4></li>
<li><img src="images/3.jpg" alt="img03"><h4>Loafers</h4></li>
<li><img src="images/4.jpg" alt="img04"><h4>Sneakers</h4></li>
</ul>
<ul>
<li><img src="images/5.jpg" alt="img05"><h4>Belts</h4></li>
<li><img src="images/6.jpg" alt="img06"><h4>Hats & Caps</h4></li>
<li><img src="images/7.jpg" alt="img07"><h4>Sunglasses</h4></li>
<li><img src="images/8.jpg" alt="img08"><h4>Scarves</h4></li>
</ul>
<ul>
<li><img src="images/9.jpg" alt="img09"><h4>Casual</h4></li>
<li><img src="images/10.jpg" alt="img10"><h4>Luxury</h4></li>
<li><img src="images/11.jpg" alt="img11"><h4>Sport</h4></li>
</ul>
<ul>
<li><img src="images/12.jpg" alt="img12"><h4>Carry-Ons</h4></li>
<li><img src="images/13.jpg" alt="img13"><h4>Duffel Bags</h4></li>
<li><img src="images/14.jpg" alt="img14"><h4>Laptop Bags</h4></li>
<li><img src="images/15.jpg" alt="img15"><h4>Briefcases</h4></li>
</ul>
<nav>
Shoes
Accessories
Watches
Bags
</nav>
</div>
And the code I used to autoslide between the navigation links, but it is only switching between the first two navigation links:
;
setInterval(function () {
$('nav > a').trigger('click.catslider');
}, 12000);
});
jQuery.noConflict();
jQuery(document).ready(function ($) {;
(function ($, window, undefined) {
'use strict';
$.CatSlider = function (options, element) {
this.$el = $(element);
this._init(options);
};
$.CatSlider.prototype = {
_init: function (options) {
this.$categories = this.$el.children('ul');
this.$navcategories = this.$el.find('nav > a');
var animEndEventNames = {
'WebkitAnimation': 'webkitAnimationEnd',
'OAnimation': 'oAnimationEnd',
'msAnimation': 'MSAnimationEnd',
'animation': 'animationend'
};
this.animEndEventName = animEndEventNames[Modernizr.prefixed('animation')];
this.support = Modernizr.csstransforms && Modernizr.cssanimations;
this.isAnimating = false;
this.current = 0;
var $currcat = this.$categories.eq(0);
if (!this.support) {
this.$categories.hide();
$currcat.show();
} else {
$currcat.addClass('mi-current');
}
this.$navcategories.eq(0).addClass('mi-selected');
this._initEvents();
},
_initEvents: function () {
var self = this;
this.$navcategories.on('click.catslider', function () {
self.showCategory($(this).index());
return false;
});
$(window).on('resize', function () {
self.$categories.removeClass().eq(0).addClass('mi-current');
self.$navcategories.eq(self.current).removeClass('mi-selected').end().eq(0).addClass('mi-selected');
self.current = 0;
});
},
showCategory: function (catidx) {
if (catidx === this.current || this.isAnimating) {
return false;
}
this.isAnimating = true;
this.$navcategories.eq(this.current).removeClass('mi-selected').end().eq(catidx).addClass('mi-selected');
var dir = catidx > this.current ? 'right' : 'left',
toClass = dir === 'right' ? 'mi-moveToLeft' : 'mi-moveToRight',
fromClass = dir === 'right' ? 'mi-moveFromRight' : 'mi-moveFromLeft',
$currcat = this.$categories.eq(this.current),
$newcat = this.$categories.eq(catidx),
$newcatchild = $newcat.children(),
lastEnter = dir === 'right' ? $newcatchild.length - 1 : 0,
self = this;
if (this.support) {
$currcat.removeClass().addClass(toClass);
setTimeout(function () {
$newcat.removeClass().addClass(fromClass);
$newcatchild.eq(lastEnter).on(self.animEndEventName, function () {
$(this).off(self.animEndEventName);
$newcat.addClass('mi-current');
self.current = catidx;
var $this = $(this);
self.forceRedraw($this.get(0));
self.isAnimating = false;
});
}, $newcatchild.length * 90);
} else {
$currcat.hide();
$newcat.show();
this.current = catidx;
this.isAnimating = false;
}
},
forceRedraw: function (element) {
if (!element) {
return;
}
var n = document.createTextNode(' '),
position = element.style.position;
element.appendChild(n);
element.style.position = 'relative';
setTimeout(function () {
element.style.position = position;
n.parentNode.removeChild(n);
}, 25);
}
}
$.fn.catslider = function (options) {
var instance = $.data(this, 'catslider');
if (typeof options === 'string') {
var args = Array.prototype.slice.call(arguments, 1);
this.each(function () {
instance[options].apply(instance, args);
});
} else {
this.each(function () {
instance ? instance._init() : instance = $.data(this, 'catslider', new $.CatSlider(options, this));
});
}
return instance;
};
})(jQuery, window);
$(function () {
$('#mi-slider').catslider();
})
I have added the code for catslider
I have an error on my console => Uncaught TypeError: Cannot read property 'maxHeight' of null.
Well I think it's a problem with the version of jQuery but I don't know how to resolve this, if you can help me. jQuery version : 1.4.2
Here the code :
$.fn.slider = function(options, callback) {
if ($.isFunction(options)) {
callback = options;
options = null;
}
options = $.extend($.fn.slider.defaults,options);
return this.each(function() {
var prt = $(this), itms = prt.find(options.itms), w = prt.width(), max = itms.length, mH = prt.data("options").maxHeight, p = 0, autoStart = prt.data("options").autoStart || options.autoStart, s = (prt.data("options").speed || options.speed) * 1000, t=s/360;
if(max<2) return;
if(prt.find('>.inner').length==1) {
prt.find('>.inner').css({'width':w+'px'});
itms.css({'width':w+'px'});
return;
}
prt.wrapInner('<div class="inner" />');
prt.css({'min-height':mH+'px'});
prt.find('>.inner').css({'height':mH+'px','width':w+'px'});
prt.append('<span class="corners"><span class="c1" /><span class="c2" /><span class="c3" /><span class="c4" /></span><span class="borders"><span class="b1" /><span class="b2" /><span class="b3" /><span class="b4" /></span>');
itms.css({'line-height':mH-2+'px','width':w+'px','min-height':mH+'px'});
/*#
if(ie_rv < 8) {
itms.each(function(){
var ieImg = $(this).find('img:first-child');
var h=(mH-ieImg.height())/2;
ieImg.css({'margin-top':h+'px'});
});
}
#*/
var c = prt.find(' > .current');
var cId = (c.length>0) ? c.index() : 0;
var iterators = '';
itms.each(function(){
var i = $(this).index();
iterators += '<button type="button" title="Slide '+(i+1)+'">•</button>';
});
$('<div class="sliderNav"><button type="button" class="prev">«</button><span class="iterators">'+iterators+'</span><button type="button" class="next">»</button><button class="playPause">►</button><span class="clock" /></div>').appendTo(prt);
var iteratorBtns = prt.find('.iterators button');
var playPause = prt.find('.playPause');
var clock = prt.find('.clock');
iteratorBtns.eq(cId).addClass('on');
prt.find('.next').bind('click',function(){
hold();
shiftItem('fwd','static');
});
prt.find('.prev').bind('click',function(){
hold();
shiftItem('back','static');
});
iteratorBtns.bind('click',function(){
hold();
shiftItem('unknown','static',$(this).index());
});
playPause.bind('click',function(){
toggle();
});
prt.bind('mouseenter',function(){
hold();
});
prt.bind('mouseleave',function(){
if(autoStart==true)
toggle();
});
// first in
itms.eq(cId).fadeTo(0,0).animate({'left':p,'opacity': 1},0,function(){
$(this).css({'filter': 'none'})
});
prt.data('status','idle');
prt.data('playPause','pause');
if(autoStart==true)
toggle();
function shiftItem(direction,type,n){
holdItem();
var w = prt.width();
if(prt.data('status')=='moving') return;
prt.data('status','moving');
if(direction=='unknown') {
if(n==cId) {
prt.data('status','idle');
if(type!='static') play();
return;
}
direction = (n>cId) ? 'fwd' : 'back';
}
else
var n = (direction == 'fwd' ) ? (cId+1 == max) ? 0 : cId+1 : (cId-1 < 0) ? max-1 : cId-1;
var sS = (direction == 'fwd' ) ? w+(2*parseInt(p,10)) : -w-(2*parseInt(p,10));
itms.eq(cId).animate({'opacity': 0},700,function(){});
itms.eq(n).fadeTo(0,0.5).animate({'opacity': 1},700,function(){
$(this).css({'filter': 'none'});
iteratorBtns.removeClass('on');
iteratorBtns.eq(n).addClass('on');
cId=n;
if(type!='static') {
play();
}
prt.data('status','idle');
});
}
var clockMax = 572, clockWidth = 26, clockSlices = 22, clockSpeed = s / clockSlices, currentPosition = 0;
function setClock() {
resetClock();
clock.data('timer',setTimeout(function(){
shiftClock();
},clockSpeed));
}
function shiftClock(){
currentPosition -= clockWidth;
clock.css({'background-position': currentPosition+'px 0'});
clock.data('timer',setTimeout(function(){
shiftClock();
},clockSpeed));
}
function resetClock() {
clearTimeout(clock.data('timer'));
currentPosition = 0;
clock.css({'background-position':'0 0'});
}
function hold(){
holdItem();
prt.data('playPause','pause')
playPause.html('►').removeClass('paused');
resetClock();
}
function play() {
if(prt.data('playPause')=='play') {
prt.data('timer',setTimeout(function(){
shiftItem('fwd','dynamic');
},s));
setClock();
}
}
function toggle(){
var state = (prt.data('playPause')=='pause') ? 'play' : 'pause';
if(state=='play'){
prt.data('playPause','play')
play();
playPause.html('||').addClass('paused');
}
else {
holdItem();
resetClock();
prt.data('playPause','pause')
playPause.html('►').removeClass('paused');
}
}
function holdItem(){
clearTimeout(prt.data('timer'));
}
$.isFunction( options.setup ) && options.setup.call(this);
});
}
Thanks !
Validate the variable maxHright before accessing it:
if (prt.data("options").maxHeight != null)
{
// access the variable
}