I have a Slick slider with some images and some html5 videos.
I have managed to make the Prev/Next arrows work: if I click on the arrows the slider goes to the next video (it plays automatically) and the previous one is paused.
Now I've added a button to pause/play the current video, but I can't find a way to make it work properly. The button works only the first time a video is played. If I change slide and go back to the same video I am not able to pause it anymore.
$('.sliderVideo').slick({
slidesToShow: 1,
slidesToScroll: 1,
arrows: true,
fade: true,
dots: true,
autoplay: true,
autoplaySpeed: 1000,
adaptiveHeight: true,
pauseOnHover:false,
cssEase: 'linear'});
$('.sliderVideo').on('beforeChange', function(event, slick, currentSlide, nextSlide){
$("video").each(function(){
$(this).get(0).pause();
});
});
$('.sliderVideo').on('afterChange', function(event, slick, currentSlide) {
var vid = $(slick.$slides[currentSlide]).find('video');
if (vid.length > 0) {
$('.sliderVideo').slick('slickPause');
$(vid).get(0).play();
var MyPlayButton = $(slick.$slides[currentSlide]).find('.play-button');
//var MyPlayButton = $('.play-button');
MyPlayButton.on('click', function () {
if ($(vid).get(0).paused) {
$(vid).get(0).play();
console.log('play');
} else {
$(vid).get(0).pause();
console.log('paused');
}
return false;
});
}
});
$('video').on('ended',function(){
$('.sliderVideo').slick('slickPlay');});
I would really appreciate your help.
I've created a fiddle https://jsfiddle.net/8ds3Lrxm/22/
OK, fixed this way:
var MyPlayButton = null;
$('.sliderVideo').on('beforeChange', function(event, slick, currentSlide, nextSlide){
if (null !== MyPlayButton) {
MyPlayButton.off('click');
}
$("video").each(function(){
$(this).get(0).pause();
});
});
A very simple way (keeping it simple is best)
this way we reset the video whenever we start playing it...
$('#slider_id').on('beforeChange', function(event, slick, currentSlide, nextSlide){
// pause old video (better performance)
var old_vid = $('#slider_id .slide:eq('+currentSlide+')').find('video');
$(old_vid).get(0).pause();
// play current video from start
var cur_vid = $('#slider_id .slide:eq('+nextSlide+')').find('video');
$(cur_vid).get(0).currentTime = 0;
$(cur_vid).get(0).play();
});
$('.video_banner_slider').on('beforeChange', function(event, slick, currentSlide, nextSlide){
console.log(currentSlide);
$("video").each(function(){
$(this).get(0).pause();
});
});
Related
I have the popup working but sometimes a user clicks the back button on their browser to close the popup.
How can I make the browser back button close a 'magnific-popup' that is already open?
Thanks
After some digging found history.js and then the following
var magnificPopup = null;
jQuery(document).ready(function ($) {
var $img = $(".img-link");
if ($img.length) {
$img.magnificPopup({
type: 'image',
preloader: true,
closeOnContentClick: true,
enableEscapeKey: false,
showCloseBtn: true,
removalDelay: 100,
mainClass: 'mfp-fade',
tClose: '',
callbacks: {
open: function () {
History.Adapter.bind(window, 'statechange', closePopup);
History.pushState({ url: document.location.href }, document.title, "?large");
$(window).on('resize', closePopup);
magnificPopup = this;
},
close: function () {
$(window).unbind('statechange', closePopup)
.off('resize', closePopup);
var State = History.getState();
History.replaceState(null, document.title, State.data["url"]);
magnificPopup = null;
}
}
});
}
});
function closePopup () {
if (magnificPopup != null)
magnificPopup.close();
}
I'm using this solution:
callbacks: {
open: function() {
location.href = location.href.split('#')[0] + "#gal";
}
,close: function() {
if (location.hash) history.go(-1);
}
}
And this code:
$(window).on('hashchange',function() {
if(location.href.indexOf("#gal")<0) {
$.magnificPopup.close();
}
});
So, on gallery open I add #gal hash. When user closes I virtually click back button to remove it. If user clicks back button - everything works fine olso.
This solution does not break back button behavior and does no require any additional plugins.
Comments are welcome.
Just to add to your answer, these are the meaningful lines that I got to work for me.
callbacks:
open: ->
History.pushState({ url: document.location.href }, null, "?dialogOpen")
History.Adapter.bind(window, 'statechange', attemptToCloseDialog)
close: ->
$(window).unbind('statechange', attemptToCloseDialog)
History.replaceState(null, null, History.getState().data['url'])
With attempt being:
attemptToCloseDialog = ->
$.magnificPopup.close() if $.magnificPopup.instance
I am using a jQuery datatable with bottom pagination. When the pages are clicked from bottom , I want it to scroll it to top, so users do not have to manually do that for longer pages. I tried using dataTables_scrollBody, but it doesn't work properly
Here is my code:
oTable = $('#tTable').dataTable({
"fnDrawCallback": function(o) {
$('dataTables_scrollBody').scrollTop(0);
}
});
The page scrolls to top only when you click first/last (which I think is default behaviour), but not with every page click.
Update. The original answer was targeting 1.9.x. In dataTables 1.10.x it is much easier :
table.on('page.dt', function() {
$('html, body').animate({
scrollTop: $(".dataTables_wrapper").offset().top
}, 'slow');
});
demo -> http://jsfiddle.net/wq853akd/
Also, if you're using the bootstrap version of datatables, you may notice that when using the fix, the page actually scrolls back down after scrolling to the top. This is because it is focusing on the clicked button as per this datatables.net thread. You can fix this by simply focusing on the table header after the animate call, like so:
table.on('page.dt', function() {
$('html, body').animate({
scrollTop: $(".dataTables_wrapper").offset().top
}, 'slow');
$('thead tr th:first-child').focus().blur();
});
Original Answer
You should target .dataTables_wrapper and attach the event to .paginate_button instead. Here with a nice little animation :
function paginateScroll() {
$('html, body').animate({
scrollTop: $(".dataTables_wrapper").offset().top
}, 100);
console.log('pagination button clicked'); //remove after test
$(".paginate_button").unbind('click', paginateScroll);
$(".paginate_button").bind('click', paginateScroll);
}
paginateScroll();
see fiddle -> http://jsfiddle.net/EjbEJ/
Since Datatables 1.10 there is this page event
https://datatables.net/reference/event/page
So one can use
$('#example_table').on( 'page.dt', function () {
$('html, body').animate({
scrollTop: 0
}, 300);
} );
Demo: https://jsfiddle.net/mcyhqrdx/
This worked out for me.
$(document).ready(function() {
var oldStart = 0;
$('#example').dataTable({
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"fnDrawCallback": function (o) {
if ( o._iDisplayStart != oldStart ) {
var targetOffset = $('#example').offset().top;
$('html,body').animate({scrollTop: targetOffset}, 500);
oldStart = o._iDisplayStart;
}
}
});
} );
I'm also using datatables and Allan's solution (found here) worked perfectly for me.
$(document).ready(function() {
var oldStart = 0;
$('#example').dataTable({
"bJQueryUI": true,
"sPaginationType": "full_numbers",
"fnDrawCallback": function (o) {
if ( o._iDisplayStart != oldStart ) {
var targetOffset = $('#example').offset().top;
$('html,body').animate({scrollTop: targetOffset}, 500);
oldStart = o._iDisplayStart;
}
}
});
} );
Thank's from davidkonrad. But when I used his code, after I clicked on paginate button, scroll of page went to top and then after load data, scroll backed to bottom.
I combined multiple posts in StackOverFlow and Datatables forum.
I defined a global variable :
var isScroll = false
When it's clicked on paginate button isScroll set to true:
$(document).on('click', '.paginate_button:not(.disabled)', function () {
isScroll = true;
});
And finally:
$(document).ready(function () {
$('#myDataTable').DataTable({
...
"fnDrawCallback": function () {
if (isScroll) {
$('html, body').animate({
scrollTop: $(".dataTables_wrapper").offset().top
}, 500);
isScroll = false;
}
},
...
});
});
Thanks from #0110
None of the above answers worked for me. Here's my solution.
$("#divContainingTheDataTable").click(function(event){
if ($(event.target).hasClass("paginate_button")) {
$('html, body').animate({
scrollTop: $("#divContainingTheDataTable").offset().top
}, 200);
}
});
I tried targetting .paginate_button but it never seemed to fire. My approach checks the div containing the datatable, if you click on the pagination buttons, the page scrolls up to the top of the container.
For those using the bootstrap version of Datatables:
You may notice that when using the fix from the accepted answer above, the page actually scrolls back down to the paging controls after scrolling to the top. This is because it is focusing on the clicked paging button as per this datatables.net thread. You can fix this by simply focusing on the table header after the animate call like so:
table.on('page.dt', function() {
$('html, body').animate({
scrollTop: $(".dataTables_wrapper").offset().top
}, 'slow');
$('thead tr th:first-child').focus().blur();
});
Note: the chained blur()'ing is done so that you the user doesn't see any focused styles on th:first-child.
I'm trying to add a class "disabled" to the pager if the slider has only 1 slide showing, and nothing to actually slide.
I'm sliding a div, not a list.
It's just a basic div:
<div class="bxslider2">
<div class="wrap">
...
</div>
</div>
Here is the jquery for the slider:
$('.bxslider2').bxSlider({
mode: 'horizontal',
speed: '180',
pagerType:'full',
pager:'true',
captions: false
});
I would like to not show the pager if there is only 1 slide showing.
Thanks for any help!
Justin
I faced the same trouble and here is my solution: we should count how many child elements we have under .bxslider2 block
$(".bxslider2>.wrap").length
and if there is only one, then set option to 'false', otherwise to 'true'.
$('.bxslider2').bxSlider({
mode: 'horizontal',
speed: '180',
pagerType:'full',
pager: ($(".bxslider2>.wrap").length > 1) ? true: false,
captions: false
});
Hope it will helps.
I use css to achieve this.
.bx-pager-item:first-of-type:last-of-type {
display: none
}
Here is a solution if you have more than one bxslider on the page.
$('.bxslider').each(function() {
var options = {
mode: 'fade',
};
if ($(this).find('li').length === 1) {
options.pager = false;
}
$(this).bxSlider(options);
});
Goes through each slider and finds if it has only one li. If so, add pager: false to the object passed to bxSlider.
a nice way to solve this thing is to reload the object like that
and change the controls per number of the items :
var slideQty = $('.bxslider').bxSlider({
minSlides: 1,
maxSlides: 3,
slideWidth: 110,
slideMargin: 0,
adaptiveHeight: true,
pager: false,
moveSlides: 1,
onSlideAfter: function ($slideElement, oldIndex, newIndex) { NextSlide(oldIndex, newIndex); }
});
var count = slideQty.getSlideCount();
if (count < 7) {
slideQty.reloadSlider({
controls : false,
minSlides: 1,
maxSlides: 3,
slideWidth: 110,
slideMargin: 0,
adaptiveHeight: true,
pager: false,
moveSlides: 1,
onSlideAfter: function ($slideElement, oldIndex, newIndex) { NextSlide(oldIndex, newIndex); }
});
}
return false;
Try this it works for me!!
var slider = $('#slider').bxSlider();
$('.bx-next, .bx-prev, .bx-pager a').click(function(){
// time to wait (in ms)
var wait = 1000;
setTimeout(function(){
slider.startAuto();
}, wait);
});
I have an embedded Google Map using API V3 but I cannot get it default Zoom to anything other than 1.
My JS in the head is:
var map1;
var src1 = 'https://latitude.google.com/latitude/apps/badge/api?user=8963899225283336226&type=kml';
function initialize1() {
map1 = new google.maps.Map(document.getElementById('map-canvas'), {
zoom: 7,
mapTypeId: google.maps.MapTypeId.TERRAIN
});
loadKmlLayer1(src1, map1);
}
google.maps.event.addDomListener(window, 'load', initialize1);
function loadKmlLayer1(src1, map1) {
var kmlLayer1 = new google.maps.KmlLayer(src1, {
suppressInfoWindows: false,
clickable: true,
preserveViewport: false,
map: map1
});
}
The HTML is just the map-canvas div, nothing else. Looking at some of the threads on here it look like its something to do with detecting the viewport and resetting the bounds.
I found a thread that suggested adding something like:
google.maps.event.addListener(kmlLayer1, 'defaultviewport_changed', function() {
var bounds = kmlLayer1.getDefaultViewport();
map.setCenter(bounds.getCenter());
})
but it made no difference. I'm by no means a JS expert and whilst I mostly understand what is going on in most of the code above, I'm not advanced enough to improvise or even understand where it should be placed.
Thanks Molle.
I enhanced to this and it works:
google.maps.event.addListener(kmlLayer, 'status_changed', function () {
console.log('kml loaded:');
google.maps.event.addListenerOnce(map, 'zoom_changed', function () {
console.log('zoom_changed:');
map.setZoom(7);
map.setCenter(new google.maps.LatLng(0, 0));
});
});
The API will set the viewport to contain all KML-features, what will override the zoom-settings.
Reset the zoom once the zoom has changed(as it does when the KML-Layer has been loaded)
google.maps.event.addListenerOnce(map1, 'zoom_changed', function() {
this.setZoom(7);
})
I just want to show basic HTML without the header and footer of my main page when using a modal window.
How can one do that in MVC3/4?
Here is an example of what is happening...
Not sure why it is doing that.
This is a basic jquery modal window call
$(function () {
//$('a.tempDlg').live("click", function (event) { loadDialog(this, event, '#edit-set'); });
//$('a.AddPatDlg').live("click", function(event) {loadDialog(this, event, '#addPat');});
//debugger;
$('a.addEncounter').live("click", function (event) { loadDialog(this, event, '#DisplayUniqueEncounters'); });
$('a.SearchEncounter').live("click", function (event) { loadDialog(this, event, '#searchEncounter'); });
//$("#sID").click(function (event) { loadDialogByClick(this, event, '#searchEncounter'); });
});
function loadDialog(tag, event, target) {
//debugger;
event.preventDefault();
var $loading = $('<img src="<%=Url.Content("~/Images/ajax-loader.gif")%>" alt="loading" class="ui-loading-icon">');
var $url = $(tag).attr('href');
var $title = $(tag).attr('title');
var $dialog = $('<div></div>');
$dialog.empty();
$dialog
.append($loading)
.load($url)
.dialog({
autoOpen: false
, title: $title
, width: 1200
, modal: true
, minHeight: 550
, show: 'fade'
, hide: 'fade'
});
$dialog.dialog('open');
};
I have done this before without including the header and footer, and I forget how it was done? I must be missing a step.
You can also set the Layout = null at the top of the page
That is correct... I want to give nemesv credit for this answer, but he didn't answer the question. So I will just say that he was right. You need to return a partialView(), not just a regular view... Returning a regular view always gets all of the other MVC markup. Thanks...