I am trying to make a slideshow transition to full screen as shown here: http://alexfuhr.me/polymer-talk/ (the trigger for this is clicking the button at the top right)
The transition to a full screen works fine, but the transition back to the inline view causes the fullscreen slideshow to suddenly fall underneath the scaffolding. I have tried to change z-index to high numbers to rectify this, but nothing seems to work. Does anyone know how to fix this transition? The main code is here: https://github.com/afuhrtrumpet/afuhrtrumpet.github.io/blob/master/polymer-talk/index.html
Instead of mucking around with z-index to overlay elements on top of each other, the following approach might offer a better solution.
The idea is to hide the drawer of the core-drawer-panel (inside the core-scaffold) by setting the narrow attribute to true before the forward animation starts, and then restore the value before the back animation starts.
Also, this issue only happens when the drawer is visible on the screen. So we only need to subscribe to the core-animated-pages-transition-prepare event when the page is not in narrow mode.
Something like the following should work. Personally I prefer this 'cause it also animates the in/out of the drawer panel smoothly, indicating that the fullscreen-list takes up the full screen space.
<script>
var isBackAnimation = false;
var pages = document.querySelector("#mainPages");
var fab = document.querySelector("#fullscreen-button");
var switchPages = function () {
isBackAnimation = pages.selected == 0;
pages.selected = pages.selected == 0 ? 1 : 0;
fab.icon = pages.selected == 1 ? "unfold-less" : "unfold-more";
}
window.addEventListener('polymer-ready', function () {
// locate the core-drawer-panel inside the core-scaffold
var drawerPanel = document.querySelector('core-scaffold::shadow #drawerPanel');
// on loaded, listen to this event only when it's not in narrow mode
if (!drawerPanel.narrow) {
pages.addEventListener('core-animated-pages-transition-prepare', beforeAnimation);
}
drawerPanel.addEventListener('core-responsive-change', function (event) {
// in narrow mode, the animations work fine, so we remove the handlers
if (event.detail.narrow) {
pages.removeEventListener('core-animated-pages-transition-prepare', beforeAnimation);
}
// otherwise we add the handlers
else {
pages.addEventListener('core-animated-pages-transition-prepare', beforeAnimation);
// when the page was initially in narrow mode and then got resized up, we
// need to manually reset the narrow attribute at the end of the animation
if (isBackAnimation) {
pages.addEventListener('core-animated-pages-transition-end', afterAnimation);
}
}
});
function beforeAnimation() {
drawerPanel.narrow = !drawerPanel.narrow;
}
function afterAnimation() {
drawerPanel.narrow = !drawerPanel.narrow;
// this is a once off thing, so unsubscribe it here
pages.removeEventListener('core-animated-pages-transition-end', afterAnimation);
}
});
</script>
Related
I've got functionality that allows to zoom images in and out, and it works properly if there's no scrollable parent element.
But when there is a scrollable parent, it doesn't work properly.
The thing is touch-action: none can't be used directly, because it prevents a page from scrolling, but I want to allow users to scroll the page only if one finger is down, and allow to zoom an image if two fingers are down.
It's strange, but the code below wouldn't work:
let fingerCount; // Assume that it has the right value
element.addEventListener("pointerdown", e => {
if (fingerCount === 2) {
// This line will be ignored
element.style.touchAction = "none";
}
});
Is there a way to combine page scrolling and pinch-zooming?
Oh, I was young and silly)) I had to do this:
// This line has to be outside of `pointerdown`
element.style.touchAction = "pan-y";
I have a responsive design, with selectable sidebar data drawn from a database. At a screen width less than 751 pixels, that sidebar becomes a pull-out tab on the left of the screen. I cannot feasibly reload the data on state change (sidebar to tab or vice versa) as the amount of data is extensive. So, the solution seems to be using the tabbed state (using MB Extruder - a "hidden" tab utility) as the sidebar, also, and just changing the state of the div. However, that cannot be done without javascript as, in the sidebar state, Extruder needs to be open, whereas it needs to be closed when in the tab state.
So, I am doing the following to set the sidebar/tab:
$(document).ready(function()
{
CheckScreen();
},
$(window).resize(function()
{
CheckScreen();
}));
function CheckScreen()
{
var ww=$(window).width();
if(ww < 751)
{
$('#extruderLeft').closeMbExtruder();
$('.extruder.left .flap').css('display', 'block'); // The tab
$('.site_wrapper').css('padding-left', '30px');
}
else
{
$('#extruderLeft').openMbExtruder(true);
$('.extruder.left .flap').css('display', 'none');
$('.site_wrapper').css('padding-left', '0px');
}
}
This changes the state from a sidebar column to a hidden state with a small tab on the left side of the screen when the screen width is less that 751 pixels. This will work fine at any size screen on document.ready. It will adjust fine when dragging the side of a browser from larger to smaller. However, when dragging back out to a larger width, the div will, rather randomly, switch from one state to another.
Perhaps there is a better way to do this altogether. If worse came to worse, I could have two separate entities (sidebar and tabbed state) holding the same data, and just use CSS, but that would be ridiculously redundant.
The problem seemed to be faulty conditions in the if-clauses (see comments under the question).
This should do the trick:
$(window).load(function() {
$(window).resize(function() {
if ($(window).width() < 751) {
if ($('.extruder.left .flap').css('display') != 'block') {
$('#extruderLeft').closeMbExtruder();
$('.extruder.left .flap').css('display','block'); // The tab
$('.site_wrapper').css('padding-left','30px');
}
} else if ($('.extruder.left .flap').css('display') != 'none') {
$('#extruderLeft').openMbExtruder(true);
$('.extruder.left .flap').css('display','none');
$('.site_wrapper').css('padding-left','0');
}
}).resize();
});
Notice the extra if-clauses checking the display-state:
if ($('.extruder.left .flap').css('display') != 'block') {
and
} else if ($('.extruder.left .flap').css('display') != 'none') {
This makes sure the sidebar/tab-switch only occurs on the break point of the specified screen-width, and the if-clauses aren't unnecessarily executed.
I also changed your script a bit to make more efficient use of jQuery. This way you don't have to create a named function AND call it twice. (I always put window.resize inside window.load instead of document.ready because if you need to scale things that only works properly after load anyway, but for your purpose both will work.)
I have the following drop-down :
<select>
<option></option>
<option>Closed</option>
<option>Open</option>
</select>
with the associated style:
select {
font-family: Cursive;
width:200px;
position: relative;
z-index: 100;
padding-right: 25px;
}
My problem is that the drop-down is moving upward on IE 11:
Where as on chrome it is working fine.
Any idea ?
Like mentioned in the comments, select menus are very browser specific and hard to style. Some even send the options into the twilight zone where they are seemingly not even a part of the window and any events will return null. It might not be worth trying to get this to look the same across browsers, also because of the mobile implementations, but I happened to be making something like this for no apparent reason. As it coincides with your question I might as well post it.
It's not the prettiest thing when it comes to HTML and CSS because it requires four additional elements - one wrapper (commonly used for styling select boxes with overflow hidden but I took a slightly different approach because I thought it looked better) and three absolutely placed elements. One is a styled button, another will hide the scrollbar that appears and the third is a minor hack.
Most important thing is that the user will not be able to click the select menu itself. When this happens, most is lost because after that it's limbo. For that the third element will be used. It will be put on top of the select box. Then when it's clicked, instead of directly opening the menu it will be faked by changing the size of the select element. The div covering the right side also serves another purpose. It's initially placed at the bottom and by getting it's offset we'll know the height of the box. This will be used to resize the button and set the correct size for the overlaying div.
Looks to be behaving quite predicatbly on all major Windows desktop browsers. For the mobile implications this script uses a touch support feature test and reverts to normal layout if that is the case. Could probably be tweaked (with a screen size check) to not exclude trackpad users.
Demo
Not too much relevant CSS. But important to style body background the same as the bar on the right. Transparency is used so the actual menu isn't visible before the image for the button loads.
$(function() {
var hub = $('#box'), list = $('select'),
impel = $('#open'), commit = $('#mark'), tract = $('#refer'),
zenith = tract.position().top,
extent = list.children().length, active;
if (touch()) {
impel.add(commit).add(tract).remove();
hub.fadeTo(0,1);
return;
}
impel.add(commit).height(zenith);
tract.addClass('bar');
hub.fadeTo(0,1).on('mouseup click', function(e) {
e.stopPropagation();
});
commit.mouseup(function() {
flip();
show();
active = true;
});
list.add(impel).click(function() {
flip();
active = !active;
if (active) show();
else hide();
});
$(window).click(function() {
if (active) {
flip();
hide();
active = false;
}
});
function show() {list.attr('size', extent)}
function hide() {list.removeAttr('size')}
function flip() {commit.toggle()}
function touch() {
return 'ontouchstart' in window
|| navigator.maxTouchPoints > 0
|| navigator.msMaxTouchPoints > 0;
}
});
I made a jsfiddle so you can reproduce the bug:
FIDDLE
I implemented a carousel to display 3 images. There's a current image (the image being displayed) and the other two remain hidden until I click one of the lateral arrows, causing the next image to slide from the side overlaying the (now previous) current image.
I've been 2 hours trying to figure out why there are certain specific 'transitions' in which the animation doesn't seem to work. For example, when clicking the left arrow to pass from the first image to the second and from the second to the third the animation works fine, but when clicking it again, the transition from 3 to 1 doesn't perform the slide animation. When moving in the opposite direction (using the right arrow) only one transition is animated. I think the problem has to do with that if in the click event handler function, but couldn't spot what's causing it.
Any help would be greatly appreciated.
TIA
The underlying issue here is related to the z-order of the three images. Your slide animations are only showing up where the image being slid in is above the displayed image; the "broken" transitions are actually occurring, they're just obscured by the "higher" visible image.
You can fix this by explicitly setting the z-index of the new and current image. For example, on the right transition:
prevLandscape.zIndex(1);
currLandscape.zIndex(0);
If you do this, you'll also need to increase the z-index of the arrows so they're above the images.
Fiddle
jsfiddle
The issue is with the hide method you just simply hide it add the slide transition for the hide method.
change this line currLandscape.hide(); to currLandscape.hide("slide");
there seemed to be a problem with the order of the images also. please try this code out. The code is reuse of the previous image arrow code. Just try it out.
$('.arrowRight').on('click',function(e) {
var currLandscape = $(this).siblings(".currImg");
var nextLandscape = currLandscape.nextAll(".hiddenImg").first();
var currDesc= $(".currDesc");
var nextDesc= currDesc.nextAll(".hiddenDesc").first();
if (nextLandscape.length == 0) {
nextLandscape = currLandscape.siblings('.hiddenImg').first();
}
if (nextDesc.length == 0) {
nextDesc= currDesc.siblings('.hiddenDesc').first();
}
nextLandscape.show("slide", { direction: "right" }, 400, function() {
currLandscape.hide("slide");
});
currDesc.fadeOut().removeClass('currDesc').addClass('hiddenDesc');
nextDesc.fadeIn().removeClass('hiddenDesc').addClass('currDesc');
currLandscape.removeClass('currImg').addClass('hiddenImg');
nextLandscape.removeClass('hiddenImg').addClass('currImg');
});
i have created a jquery onhover vertical sliding menubar now i need to implement horizontal sliding also i am facing some problem with the styling it is not coming horizontally
i have created a demo in jsfiddle link to demo
on hovering over 'manage' in the vertical slidedown menu there is lookup management menu under which there are 2 submenus(hi and hello) which i want to slide horizontally but unable to do so, it seems there is some problem with the javascript can someone help me out
the javascript is here
var menuShowDelay = 500;
var menuHoverTimer = null;
$(function () {
bindMenuSliding();
});
function bindMenuSliding() {
// Expand menu on mouse over.
$('.ulMiddleMenu li').hover(function () {
// Clear previous mouse hover timer.
if (menuHoverTimer) {
clearTimeout(menuHoverTimer);
menuHoverTimer = null;
}
var targetElement = $(this); // Get the target element.
// Display the menu after a certain time interval.
menuHoverTimer = setTimeout(function () {
targetElement.parent('ul').find('ul').stop(true, true).css('display', 'none');
targetElement.find('ul').slideDown('medium');
}, menuShowDelay);
},
function () {
// Clear previous mouse hover timer.
if (menuHoverTimer) {
clearTimeout(menuHoverTimer);
menuHoverTimer = null;
}
// Hide the menu.
$(this).find('ul').slideUp('fast');
});
}
you can copy paste this in the javascript panel of jsfiddle
Two main problems. One, you were showing all sub-menus on hover, instead of just the child. Two, you had no logic to distinguish between levels of navigation, so there was no way to expect the lower levels to behave differently at all.
// Display the menu after a certain time interval.
menuHoverTimer = setTimeout(function () {
var $parent = targetElement.parent('ul');
$parent.find('ul').stop(true, true).hide();
//test for first level nav
if( $parent.hasClass("ulMiddleMenu") ){
targetElement.children('ul').slideDown('medium');
}else{
targetElement.find('ul').width(0).show().animate({width:'100%'},1000);
}
}, menuShowDelay);
jsFiddle. This still leaves some issues for you to sort out in terms of display. You should consider scrapping your CSS and starting from scratch because it is going to get harder and harder to dig your way out of that mess.