Slider - preloader - buttons aren't working after setting style="display: none" - html

Could anyone have a look at this snippet of code?
I recreated another loader and included the last amount possible of code I could to show you the problem.
Basically I have a div container, which is "all-page-container" which has an inline style="display: none" which makes it non visible until the loader is done (but also it makes it wait at least 2 seconds to show the actual page content).
But this also makes the js part of the code as
var s = $('.slider'),
sWrapper = s.find('.slider-wrapper'),
sItem = s.find('.slide'),
btn = s.find('.slider-link'),
sWidth = sItem.width(),
sCount = sItem.length,
slide_date = s.find('.slide-date'),
slide_title = s.find('.slide-title'),
slide_text = s.find('.slide-text'),
slide_more = s.find('.slide-more'),
slide_image = s.find('.slide-image img'),
sTotalWidth = sCount * sWidth;
Not find the actual classes, because of the display:none, does anyone know how could I overcome this issue?
I fixed it with a while loop which checks until a property is set to 0 to load the script, but obviously this isn't going to fix the major problem.
https://jsfiddle.net/boxxo/95ocxrb2/59/
if you remove the inline style="display:none", obviously the buttons are going to work ask expected and also the slider is going to work properly.
(The buttons are actually running, I added logs into the conditions and the "next" and "previous" are definitely executing correctly).
If anyone could help I would be grateful.
Thanks everyone.
(I also checked other questions on the site, but couldn't find the solution to my issue, and also other guys are using display: none to hide the page content until the preloader is done loading).

The problem is that width of the element that is not visible (display: none) is 0 same as height. If initially, the page is not visible (width display: none) your animation will not work.
Just add console.log({sWidth}); to see for yourself.
To solve the issue you can show the div before you start your code. Or use different CSS properties:
visibility: hidden;
visibility: visible;
This property works similarly to display: none but the width and height is not 0, the element still occupies the same space but it's not visible.

Related

How to keep fixed html element visible on bottom of screen when the soft keyboard is open on iOS Safari?

In a web page I have an input field and a div that is fixed to the bottom of the window (with these CSS properties: position:fixed; and bottom:0;
I made a Codepen to show what I'm talking about: https://codepen.io/anon/pen/xpQWbb/
Chrome on Android keeps the div visible even when the soft keyboard is open:
However, Safari on iOS seems to draw the soft keyboard over the fixed element:
(I should mention I'm testing on the iOS simulator on my Macbook, because I don't have a working iPhone)
Is there a way to make iOS Safari keep the element visible even when the soft keyboard is open, like how Chrome does it?
I recently ran in to this problem when creating a chat input that should stay fixed at the bottom of the page. Naturally the iOS keyboard displayed on top of the chat input. Knowing the exact keyboard height seems more or less impossible. I embarked on a quest to find a solid value to base my calculations on so i can manually position the chat input container above the keyboard. I wanted to find the actual "innerHeight" value, in other words the currently visible area of the webpage. Due to how the iOS keyboard works, the only way to get that value with the keyboard open seems to be to scroll to the very bottom of the page, and then take a sample of "window.innerHeight".
So, i set up an event listener on my input field on 'click' (since on 'focus' caused a lot of issues for me). This opens the keyboard, which takes a while, so after i set a timeout for 1000ms to make sure (hopefully) that my keyboard is fully open. After 1000ms i quickly scroll to the bottom of the page with javascript, save the value of "window.innerHeight" in this state, and scroll back to where i was. This gives me the actual height of the visible area on the screen.
It seems like the browser window is placed behind the keyboard until you scroll to the very bottom, in which case the whole window 'scrolls up' and the bottom is placed at the top of the keyboard view.
Once i have this value i use currently scrolled value (window.scrollY) plus the value i saved minus the height of my absolute positioned element to determine where to place it. I opted to also hide the input while scrolling since it's flicking around quite a bit. Another downside to this is that you get a quick flick of the page when it does the measurement at the bottom.
Another thing i couldn't solve was the variable height of the address bar. I just made the input a bit higher than i needed so it would have some "padding" at the bottom.
var correctInnerHeight = window.innerHeight;
var isFocused = false;
var docHeight = $(document).height();
var input = $('.myInput');
input.click(function(e){
isFocused = true;
input.css('position', 'absolute');
// Wait for the keyboard to open
setTimeout(function(){
docHeight = $(document).height();
var lastScrollPos = $(document).scrollTop();
// Scroll to the bottom
window.scroll(0, $(document).height());
// Give it a millisecond to get there
setTimeout(function(){
// Save the innerHeight in this state
correctInnerHeight = window.innerHeight;
console.log(correctInnerHeight);
// Now scroll back to where you were, or wish to be.
window.scroll(0, lastScrollPos);
fixInputPosition();
// Make sure the input is focused
input.focus();
}, 1);
}, 1000);
});
input.on('blur', function(){
input.css('position', 'fixed');
input.css('top', 'auto');
input.css('bottom', '');
isFocused = false;
});
$(window).scroll(function(){
fixInputPosition();
});
function fixInputPosition(){
if(isFocused){
var offsetTop = ($(window).scrollTop() + correctInnerHeight) - input.height();
offsetTop = Math.min(docHeight, offsetTop);
input.css('top', offsetTop);
input.css('bottom', 'auto');
}
};
body, html{
margin: 0;
}
html{
width: 100%;
height: 2000px;
}
.myInput{
position: fixed;
height: 30px;
bottom: 0;
width: 100%;
border: 1px solid black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type='text' class='myInput'>
Check out this thread, it talks about a work around that may be more feasible in terms of code. In brief it talks about using the height of the keyboard to move the content into view. All be it a bit hacky it may be difficult to pin down the exact height of the keyboard across devices.
Unfortunately, due to the nature of the IOs Safari keyboard it's not part of the browser viewport so cannot be referenced as you would do typical elements.
#Bhimbim's answer may a good shot too.
Regards,
-B
i experienced this before. What i did back then was :
Make a listener when keyboard is hit.
When keyboard is hit resize you webview's height with screen height - keyboard height.
To do this trick you need to make sure that you html is responsive.
I can show more code in the IOS side, if you're interested i can edit my answer and show you my IOS code. Thank you.
Hi again, sorry, i was mistaken, i thought you were creating apps with webview inside. If you still wanna do this by listening the keyboard i still have work around for you. It may not the perfect way, but i believe this will work if you want to try. Here my suggestion :
You still can have listener from webpage when the keyboard is up. You can put a listener on your textfield by jquery onkeyup or onfocus.
Then you will know when the input is hit and the keyboard will show.
Then you can create a condition in your java script to manipulate your screen.
Hope this give you an insight friend.
#Beaniie thank you !.
Hi Andreyu !. Yes correct, we can not know the keyboard height, not like my case with WebView, I can know the keyboard height through IOS code. I have another work around, not so smart, but might work. You can get the screen size and compare to array of IOS device screen size. Then you might narrowed down the keyboard height by surveying through IOS devices. Good luck friend.
Try using position:absolute and height:100% for the whole page.
When the system displays the keyboard,it plTaces it on top of the app content.
One way is to manage both the keyboard and objects is to embed them inside a UIScrollView object or one of its subclasses, like UITableView. Note that UITableViewController automatically resizes and repositions its table view when there is inline editing of text fields.
When the keyboard is displayed, all you have to do is reset the content area of the scroll view and scroll the desired text object into position. Thus, in response to a UIKeyboardDidShowNotification, your handler method would do the following:
1.Get the size of the keyboard.
2.Adjust the bottom content inset of your scroll view by the keyboard height.
3.Scroll the target text field into view.
Check the Apple developer's guideline to learn more:https://developer.apple.com/library/content/documentation/StringsTextFonts/Conceptual/TextAndWebiPhoneOS/KeyboardManagement/KeyboardManagement.html

Selenium : isDisplayed returns

I'm quite new to Selenium so that question may be silly, but i cannot resolve it...
I'm trying to make a click() with Selenium (in Java, with Eclipse and Firefox and Chrome drivers) on an element that is definitely displayed and visible on the screen, but that returns false when i apply the isDisplayed() method on it. So i get an exception telling me that the element must be visible in order to perform an action on it.
I checked all parents div (i'm not using any iframe in my page), and some of them returns true as other returns false. Here is a small example of code of what i try to do :
<div id=1><div id=2><div id=3><div id=4><img that i want to click on with selenium\></div></div></div></div>
I want to click on the img with selenium, but it sees it as not displayed.
the img is marked as not displayed
the div4 is marked as not displayed
the div3 is marked as displayed by selenium
the div2 is marked as not displayed
the div1 is marked as displayed, as all parents div
But i definitely can see the image and others elements in the same div on my screen.
Any help on that point ?
Thanks !
EDIT : I use JS to modify these properties, particularly div 3, which is not displayed and marked as not displayed at loading, but then after e few action, it became (it is and is marked as) displayed.
Edit 2 : I found out that the styles of the two divs marked as not displayed by selenium have both the style display:block; (seen in the chrome dev tools). Any ideas ?
Edit3 : based on the link given in the comments, i add the computed style of the div :
div4 : it has non zero height and width, display is set on block. It even has a min width and min height.
div3 : it has non zero height and width, display is also set on block
div2 : it has a 0 height a non zero width and a display:block; so it might be the problem.
div1 : it has a 0 height, a non sero width, no display parameters, and hidden overflow-x and y. Thought this one is marked as deisplayed by Selenium...
Any ideas ?
I managed to solve my problem with a simple trick : call the Js function that is supposed to be triggered by the click, using
JavascriptExecutor js;
if (driver instanceof JavascriptExecutor) {
js = (JavascriptExecutor) driver;
} else {
throw new Exception(" Webdriver do not manage JS");
}
js.executeScript("function()");
Another solution that could be suitable is to use a Robot to use the mouse to click on this img, if you have its coordinates of course (or if you can compute it) :
Robot robot = new Robot();
robot.mouseMove(300, 300);
robot.mousePress(InputEvent.BUTTON1_MASK);
robot.mouseRelease(InputEvent.BUTTON1_MASK);
Though i did not find a solution to the displayed/not displayed problem.
Enjoy :)

Inconsistent click handling when using :active pseudo class

Can anyone explain why the click handler is not invoked consistently in this example?
http://jsfiddle.net/4QBnf/
For instance, if you click in the upper left half of the div, it does not reliably increment the counter.
If I remove the padding-top from this block it works just fine:
.click-check:active {
background-color:blue;
padding-top: 25px;
}
I have tested this in a number of different browsers and it behaves the same way.
I found two possible issues with your code. You can view the fixes here:
http://jsfiddle.net/4QBnf/6/
CSS Box Model vs jQuery Box Model
Whenever you click on the top half of your box, you aren't technically clicking on .click-check, you are actually clicking on .count. This image shows the location of .count relative to .click-check:
jQuery counts this as a click on .click-check, but CSS doesn't. The number increments, but the CSS "active" effect isn't applied.
You can resolve this by removing the .count div and placing everything inside of .click-check.
jQuery Counter
The second issue is with your jQuery code. The code currrently reads:
$('.click-check').click(function() { $('.count').html(count++); });
count isn't increased until after this line is done. This means that the first click appears to have no effect.
This line will increment count, then display it to the user:
$('.click-check').click(function() { $('.click-check').html(++count); });
I've applied both updates to your example here:
http://jsfiddle.net/4QBnf/6/
Update
An alternate way to resolve the issue is to do everything through jQuery. This synchronizes all of the appearance and logic into a single box-model interpretation.
var count=0;
$('.click-check').mousedown(function() {
$('.click-check').addClass("active");
$('.click-check').html(++count);
setTimeout(function(){
$('.click-check').removeClass("active");
}, 50);
});
http://jsfiddle.net/4QBnf/15/

Flex 4 <s:Scroller> Recalculate Range?

I am building a Flex 4 application which uses a <s:Scroller> component to vertically scroll overflown content. Let me explain what happens before I ask my question:
The body of the page is loaded from a database
Once the information has loaded, the "body" of the application (in this case the list of items you see below) is constructed
Once the list is constructed, the entire encapsulating component is transitioned into view using TweenMax, like so:
myComponent.visible = true;
TweenMax.to(myComponent, 1, {
alpha : 1,
y -= 20 //Slides the component up 20px from its original location
});
Below is the result. Notice how the scrollbar is scrolled the whole way down, but you can see the tips of a few white letters that were cut off at the very bottom.
Using my custom menu, I can navigate away from the page, and come back to it, and Flex will correctly recalculate the range of the scroller so I can scroll down and see all of the desired content. This issue only happens if the initial URL that the user enters is a longer page like this one.
Any ideas on how I can force Flex to recalculate the range of the scroller?
Thank you for your time.
Ok, after many hours of researching, piecing together, and trial and error here is what I came up with.
What I was doing wrong:
When I first posted this question, the "component" that I had mentioned was already added as a child element of the <s:Scroller>, but collapsed and hidden away, like this:
<comp:MyComp alpha="0" height="0" visible="false"/>
When the data would be loaded and the component's visual appearance would be restored and transitioned into place, like this:
myComp.visible = true;
myComp.height = NaN;
myComp.invalidateSize();
myComp.height = myComp.measuredHeight;
TweenMax.to(myComp, 1, {
alpha : 1,
y -= 20 //Slides the component up 20px from its original location
});
This method of approach didn't force the <s:Scroller> to recalculate its proper size until later, sometimes not until myComp was transitioned away and another component was transitioned into place using the same method. Even then, the size of the scroller would fit the size of the previous component, not the one that is currently displaying.
Now, what I am doing correctly:
My research showed me that anytime the addElement() method is called, either directly within the <s:Scroller> itself or by any of its children, the scroller's measure() method is called, and properly re-sizes the scroller.
Instead of placing the components inside of the scroller and simply hiding them until I need them, I dynamically created them in ActionScript, set their properties, and added and removed them as needed using the addElement() and removeElement() methods respectively. Now, as old elements are transitioned away and new ones take their place, the scroller re-sizes itself correctly.
There was one final problem that I was faced with. If the very first page the user was viewing (i.e. there was no previous component that was transitioned away and destroyed) required a scroller, it wouldn't show up.
I corrected this final issue by adding an event listener that listened for when the new component had finished transitioning into place. Inside of the event handler, I explicitly set the height of the component using this code:
newComp.height = NaN;
newComp.invalidateSize();
newComp.height = newComp.measuredHeight;
Now that the component has an explicit height, the scroller now appears, even if it is the first page.
The scroller now works as expected in all cases, and does not cut off any content or disappear when it shouldn't.
I hope that it is helpful to someone.

Why is there this extra space that is not inspect-able on chrome?

My page didn't require a horizontal scroll bar initially, but now one appears mysteriously that is beyond any of the elements that are covered on inspect on Chrome and firebug. No elements pass that blue line so I'm not sure how to fix this.
I know I can hide the scrollbar with overflow-y:hidden, but that's not the point. It shouldn't be there at all.
EDIT Here's the jsfiddle: http://jsfiddle.net/S8RUp/
A bit messy, but I think it gets the point across.
The jsFiddle link has too many overflowing contents to be useful. What you can do to ease debugging is to use a bit of code like this to show you only elements that are over a threshold width:
// using jQuery - you can use other library or include it temporarily for debugging purposes
$('*').each(function() {
var w = parseInt($(this).width(), 10);
// you can put something larger than 700, depending on your situation
if (w > 700) {
console.log(w, this);
}
});
It will have a few false positives (the html node for example), but you'll probably find the culprit easily enough.