i am trying to make a flipbook with turn.js which is awesome.
the only problem i have is that i am trying to make it so in mobies it is single page display and in desktops double page display.
it does have the option to choose when creating the flipbook in javascript
display: 'single' or display: 'double'
i managed to achive changing that when you resize the window but with the onresize jwuery event but that makes it so it triggers only when you resize the window but if you dont it is always double page...so when the browser renders the page for mobile it is as defaul double page and not single
let me post my code here
// Create the flipbook
flipbook.turn({
// Magazine width
width: 922,
// Magazine height
height: 600,
// Duration in millisecond
duration: 1000,
// Enables gradients
gradients: true,
// Auto center this flipbook
autoCenter: true,
// Elevation from the edge of the flipbook when turning a page
elevation: 50,
// The number of pages
pages: 12,
// Events
when: {
turning: function(event, page, view) {
var book = $(this),
currentPage = book.turn('page'),
pages = book.turn('pages');
// Update the current URI
Hash.go('page/' + page).update();
// Show and hide navigation buttons
disableControls(page);
},
turned: function(event, page, view) {
disableControls(page);
$(this).turn('center');
$('#slider').slider('value', getViewNumber($(this), page));
if (page==1) {
$(this).turn('peel', 'br');
}
},
missing: function (event, pages) {
// Add pages that aren't in the magazine
for (var i = 0; i < pages.length; i++)
addPage(pages[i], $(this));
}
}
});
//change from single to double page
$(window).resize(function(){
var win = $(this); //this = window
if (win.width() >= 820) { flipbook.turn('display','double');}
else {
flipbook.turn('display','single');
}
});
i hope someone can help me fix this
To make the flipbook responsive for mobile, you can add the following code, which checks if the user agent of the navigator is mobile or not.
function checkMobile() {
return /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
}
And then use this in the resize of the window function.
if (!checkMobile()) { // not mobile
$('.flipbook').turn('display', 'double');
}
else {
$('.flipbook').turn('display', 'single');
}
You can use the above snippet after you have initialized the flipbook, to dynamically set the display (double, single) of the flipbook.
so hello everyone again, i managed to figure this out..
i changed the last code part from this
$(window).resize(function(){
var win = $(this); //this = window
if (win.width() >= 820) { flipbook.turn('display','double');}
else {
flipbook.turn('display','single');
}
});
to that
$(window).width(function(){
var win = $(this); //this = window
if (win.width() >= 820) { flipbook.turn('display','double');}
else {
flipbook.turn('display','single');
}
});
$(window).resize(function(){
var win = $(this); //this = window
if (win.width() >= 820) { flipbook.turn('display','double');}
else {
flipbook.turn('display','single');
}
});
it works fine both when you refresh the page and when you resize the window. I don't know if this the right way to do it but it seems to work perfectly fine
For mobile screens you have to change the screen width
here is tested and working code
if(window.innerWidth<768 && window.innerWidth >= 320) {
$('#flipbook').turn({
width:430,
height:650,
elevation:50,
inclination:50,
display: 'single',
autocenter:true,
acceleration: true,
gradients:true,
zoom:2,// you can change it as you desire
duration:50,
});
}
Here is what works for me on the mobile screen:
$('#flipbook').turn({
display: 'single',
acceleration: true,
gradients: true,
elevation:50,
when: {
turned: function(e, page) {
console.log('Current view: ', $(this).turn('view'));
}
}
});
Related
I have an image embedded in a container with a background image to give the effect of scrolling within the page. Initially, I had the scrolling effect take place on page load, with this simple bit of script which worked perfectly.
$(window).on("load", function () {
$(".embedded_scroller_image").animate({ scrollTop: $('.embedded_scroller_image')[0].scrollHeight}, 2500, "easeInOutCubic");
}); // end on load
However, the element is too far down the page now and I want that animation to fire when the element enters 80% of the viewport. That part is also working fine with this code here (I'm using a scroll limiter to improve browser performance)
// limit scroll call for performance
var scrollHandling = {
allow: true,
reallow: function() {
scrollHandling.allow = true;
},
delay: 500 //(milliseconds) adjust to the highest acceptable value
};
$(window).on('scroll', function() {
var flag = true;
if(scrollHandling.allow) { // call scroll limit
var inViewport = $(window).height()*0.8; // get 80% of viewport
$('.embedded_scroller_image').each(function() { // check each embedded scroller
var distance = $(this).offset().top - inViewport; // check when it reaches offset
if ($(window).scrollTop() >= distance && flag === true ) {
$(this).animate({ scrollTop: $(this)[0].scrollHeight}, 2500, "easeInOutCubic"); //animate embedded scroller
flag = false;
}
});
} // end scroll limit
}); // end window scroll function
The problem is this: I want the autoscroll to happen once and then stop. Right now, it works on entering viewport, but if I then try to manually scroll the image, it keeps pushing back down or stutters. You can't get the element to scroll normally. I attempted to use the flag in the code to stop the animation, but couldn't get that to successfully work.
How can I have this animation fire when the element is 80% in the viewport, but then completely stop after one time?
Here is a codepen I mocked up as well http://codepen.io/jphogan/pen/PPQwZL?editors=001 If you scroll down, you will see the image element autoscroll when it enters the viewport, but if you try to then scroll that image up in its container, it won't work.
Thanks!
I have tweaked your script a bit:
// limit scroll call for performance
var scrollHandling = {
allow: true,
reallow: function() { scrollHandling.allow = true; },
delay: 500 //(milliseconds) adjust to the highest acceptable value
};
$(window).on('scroll', function() {
if(scrollHandling.allow) { // call scroll limit
var inViewport = $(window).height()*0.8; // get 80% of viewport
$('.embedded_scroller_image').each(function() { // check each embedded scroller
var distance = $(this).offset().top - inViewport; // check when it reaches offset
if ($(window).scrollTop() >= distance ) {
$(this).animate({ scrollTop: $(this)[0].scrollHeight}, 2500, "easeInOutCubic"); //animate embedded scroller
scrollHandling.allow = false;
}
});
} // end scroll limit
}); // end window scroll function
I have kicked out your flag and simply made use of scrollHandling.allow declared already.
Try if it works for you :)
Cheers!
I am using MasterSlider.js to make the carousal, I want to give it partialview on desktop and fillwidth view on tablet and mobile. I am trying to change it through detecting the window width but there is something wrong in my code.
<script type="text/javascript">
var slider = new MasterSlider();
slider.setup('masterslider' , {
width:700,
height:466,
space:5,
loop:true,
view:'fadeFlow',
layout:'partialview',
grabCursor:false,
centerControls:false,
autohide:false,
view:"fadeBasic",
});
slider.control('arrows' , {autohide:false});
if ($(window).width() < 1024) {
slider.setup('masterslider' , {
layout:'fillwidth',
grabCursor:false,
centerControls:false,
});
}
</script>
One more thing I am using fadeBasic option to make the previous and next image fade out by default it is applying opactiy 0.4, is there any way I make it 0.8. Opacity is applying on run time.
Just for reference I am using this slider:
http://www.mercurycustom.com/wp-content/uploads/2014/05/partialview/partialview3.html
Here is a running demo: http://codepen.io/anon/pen/dopNrM
Try this instead:
var slider = new MasterSlider();
slider.control('arrows');
if ($(window).width() < 1024) {
slider.setup('masterslider', {
layout: 'fillwidth',
grabCursor: false,
centerControls: false,
});
} else {
slider.setup('masterslider', {
width: 760,
height: 400,
space: 10,
loop: true,
view: 'fadeFlow',
layout: 'partialview',
});
}
Is there some JavaScript code I can execute to scroll to the top of the messages box on Facebook? So when you click 'see all' and go the main message page, if you scroll up it loads more messages. I want to force the it to keep scrolling up to keep loading messages. I've tried
document.body.scrollTop = document.documentElement.scrollTop = 0;
But that of course only scrolls to the top of the actual page. Any ideas on how to scroll the messages box up?
Select a conversation and try this script (load it through the console):
var autoLoad = {
messagesContainer: document.querySelector('#contentArea [role=main] .uiScrollableAreaContent'),
start: function (speed) {
var messagesContainer = this.messagesContainer,
loadMore = document.querySelector('[role=log] .pam.uiBoxLightblue.uiMorePagerPrimary');
speed = parseInt(speed, 10) || 1000;
clearInterval(this.interval);
this.interval = setInterval(function () {
messagesContainer.style.top = '0px';
loadMore.click();
}, speed);
},
stop: function () {
clearInterval(this.interval);
this.messagesContainer.style.top = '';
}
};
To start it, type:
// Takes a 'speed' parameter, defaults to 1000 milliseconds
autoLoad.start(1200);
And to stop it (necessary for the scrollbar to re-appear):
autoLoad.stop();
Explanation:
After exploring Facebook's DOM, I found some selectors that specifically target the elements that are needed for this to work:
The messages container, which holds the messages
The 'load more' link, that triggers facebook's script in charge of loading more messages.
The messages container scrollable area doesn't use native scrolling, instead, it uses bottom and top to set it's current scroll position.
So, if you want to scroll to the top, you set the container to top: '0', and since this way, the messages auto-load AJAX only triggers once, you need to trigger it manually after every scroll to top. I managed to do this simply by executing click in the link that triggers the AJAX.
I tried to get the most specific classes/selectors that I could find, and the ones that sounded more general, since I don't know if Facebook generates ids/classes dynamically in some way.
I tested this under Firefox and Chrome, explore the code a bit and change it to fit your needs. I hope this works for you as is, otherwise, you can use the DOM explorer to find the appropriate selectors.
I had to tweak the script to use "scrollTop" instead of "style.top".
var autoLoad = {
messagesContainer: document.querySelector('#globalContainer [role=main] .uiScrollableAreaContent'),
start: function (speed) {
var messagesContainer = this.messagesContainer,
loadMore = document.querySelector('#js_d');
speed = parseInt(speed, 10) || 1000;
clearInterval(this.interval);
this.interval = setInterval(function () {
messagesContainer.scrollTop = 0;
loadMore.scrollTop = 0;
/* loadMore.click(); */
}, speed);
},
stop: function () {
clearInterval(this.interval);
this.messagesContainer.style.top = '';
}
};
Nov 2021 #user4698813 code update:
var autoLoad = {
messagesContainer: document.querySelector('[role=main]'),
start: function (speed) {
var messagesContainer = this.messagesContainer,
loadMore = document.querySelector('[data-release-focus-from]');
speed = parseInt(speed, 10) || 1000;
clearInterval(this.interval);
this.interval = setInterval(function () {
messagesContainer.scrollTop = 0;
loadMore.scrollTop = 0;
/* loadMore.click(); */
}, speed);
},
stop: function () {
clearInterval(this.interval);
this.messagesContainer.style.top = '';
}
};
I have an animation where three images rotate up and down. JSfiddle: http://jsfiddle.net/rLgkyzgc/1/
$(window).load(function() {
// Load images in BG that have been hidden by CSS
$('.banners').show();
// Create an empty array
var banners = [];
// Fill array with banner ids
$('.banners').each(function () {
var banner = $(this).attr('id');
banners.push(banner);
});
function switchBanners(){
var $firstBanner = $('#' + banners[0]);
var $secondBanner = $('#' + banners[1]);
var firstBannerHeight = $firstBanner.height();
var secondBannerHeight = $secondBanner.height();
$firstBanner.animate({ bottom: -firstBannerHeight }, 1200);
$secondBanner.animate({ bottom: 0 }, 1200, function(){
b = banners.shift(); banners.push(b);
setTimeout(function(){
switchBanners();
}, 4000);
});
};
// Delay initial banner switch
setTimeout(function(){
switchBanners();
}, 4000);
});
This is great for the desktop view, but on mobile, I want to stop the animation and just show one static image.
So my questions. How can I :
Only start the animation on page load if the window width is > 940px
Stop (reset) the animation if the page is resized to be < 940px wide
THEN restart the animation if the page resized to be > 940px wide
You should use window.matchMedia (see the documentation) to detect the viewport size on document.ready and when the window is resized, so something like this:
function resetAnimation() {
$firstBanner.stop(true, true);
$secondBanner.stop(true, true);
if(window.matchMedia("(min-width: 940px)").matches) {
//Start the animations here
}
}
$(document).ready(function() {
resetAnimation();
}
$(window).resize(function() {
resetAnimation();
}
Note that you don't really need to stopthe animations on document.ready, but this way you have a single function to reset the animations and then restart them only if necessary, which is something you typically want to do every time you resize the browser window, regardless of the viewport size.
I'll reference these in order:
1. Only start the animation on page load if the window width is > 940px
In your window load function, grab your browser width with $(window).width(). Then check that against your 940 (leave off the "px"), and perform necessary actions.
So:
if ($(window).width() > 940){ *actions* }
2. Stop (reset) the animation if the page is resized to be < 940px wide
To do this, you'll need to use the window resize function ($(window).resize()) and check your 940 against the browser width.
So:
$(window).resize(function(){
if ($(window).width() <= 940){
*stop (reset) animation*
}
});
3. THEN restart the animation if the page resized to be > 940px wide
This logic is essentially the same as #2, just reversed:
$(window).resize(function(){
if ($(window).width() > 940){
*restart animation*
}
});
View my jsFiddle
Resize HTML preview to small width and see that slideshow is resized properly
Change jQuery from 1.9.1 to 1.10.1 (in left pane) and click RUN
Resize HTML preview to a small or large width
Open console, and see error: Object [object Object] has no method 'bjqs'
I cannot figure out what about the bjqs plugin is causing this problem with 1.10.1.
Is there something about the plugin preventing it from working the 2nd time it's called in the resize function?
JavaScript is included here, but jsFiddle linked above is going to be a better place to view it.
Plugin I am using is: http://www.basic-slider.com/
$(function () {
$(window).resize(function () {
if (this.resizeTO) clearTimeout(this.resizeTO);
this.resizeTO = setTimeout(function () {
slideShow(); // re-init on resize stop
}, 500);
});
function slideShow() {
$('.bjqs-controls, .bjqs-markers').remove();
console.log($(window).width());
var ss_width;
var ss_height;
if ($(window).width() >= 600) {
// Desktop
ss_width = 300;
ss_height = 200;
} else if ($(window).width() < 600) {
// Tablet
ss_width = 150;
ss_height = 150;
}
// Load content slideshow
$('#banner-slide').bjqs({
nexttext: 'Next',
prevtext: 'Prev',
showmarkers: true,
centermarkers: true, // horizontally center markers
responsive: false, // enable responsive behaviour
width: ss_width,
height: ss_height
});
}
// Init slide show on load
slideShow();
});
The root cause of the error within said plugin is /^\d\.\d+/i.exec(jQuery.fn.jquery))<1.6 it compares the string "1.10" to "1.6" using alphanumeric sorting, therefore "1.6" > "1.10", so it includes it's own version and doesn't properly prevent conflicts. I'd suggest reporting this as a bug to the plugin author, it should be trivial to fix.