Phonegap 2.8 Position: fixed is not working properly - javascript

After spending 16 hours and having sacrificed critters to various gods I must regretfully say that I'm on the verge of mental meltdown.
I am writing an PhoneGap 2.8 application for Android (in the future will port to iOS). As main frameworks I use jQuery (with many plugins), Require, Underscore and Backbone.
On one fatal morning I got a task that header menu of my application must "imitate" the way facebook app's header does (follow the scroll).
Initially I believed that adding "position:fixed" attribute to the header div would would be simple enough- have I never been more wrong. As it turns out, position:fixed css attribute doesn't work properly in WebView and the issue has endured for years now.
This issue has been discussed in length in various forums and articles and various "solutions" have been proposed- none are working in my case.
I have tried to set header's position to fixed when scrolling and to absolute when scrolling is done. Theoretically it works, but it is laggy.
Having tried that I looked into different plugins or frameworks that could help in the case.
iScroll - Forces a specified structure to html and severe lack of documentation threw me away from it.
jQueryMobile - Since it is a whole framework, integrating it to my project would mean changing alot of stuff. As I understand, it wont provide a persistent header.
I have heard of Bartender and GloveBox but neither of them have documentation and they aren't in constant development (last commits are > year old ).
Using jsHybugger I inspected the header when it is in position: fixed an I have noticed that Blue box that overlays a div being selected in inspector is staying where click area is for the header. So if I scroll, the header moves with viewport but hitarea stays in place. It got me wondering, if there is a way to force WebView to recalculate the click area?
All and any help is very much appreciated.

So, inspired by this link, I made a quick fiddle on how this could work without position:fixed. Note that the fiddle is not the same as the code here, it just illustrates how this is supposed to work.
HTML
<div class="page-wrapper">
<div class="header"><h3>header</h3></div>
<div class="content-wrapper">
<div class="content">
<!-- Your content goes here -->
</div>
</div>
</div>
CSS
body {
height: 100%;
padding: 0;
margin: 0;
}
.page-wrapper {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
position: relative;
overflow: hidden;
}
.header {
position: absolute;
top:0;
left:0;
right:0;
padding: 3px 0;
color: #FFF;
background: #000;
text-align: center;
}
.content-wrapper {
position: absolute;
padding:0;
top: 65px;
left: 0;
right: 0;
bottom:0;
background: #CCC;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
.content {
padding: 15px;
}

Its not the problem of phonegap. Actually position: fixed doesnt work in android version lesser than 4.0
There is a quick css fix for it:
<div class="header"> this is fixed positioned div<div>
Css:
.header{ position:fixed ; -webkit-backface-visibility: hidden; top:0; left:0; width: 100px; height:30px; background: red; }

I came across after inheriting a project which was using the positioning system. Most people would probably know not to go down this road now but just in case someone does end up here looking for a solution...
It's possible to achieve the above with flexbox layouts.
In this way the css was as follows:
.pageWrapper {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
overflow: hidden;
padding-top: env(safe-area-inset-top);
padding-bottom: env(safe-area-inset-bottom);
display: flex;
flex-direction: column;
}
.screen-content-wrapper {
padding:0;
flex: 1;
overflow-y: scroll;
-webkit-overflow-scrolling: touch;
}
I didn't edit my content css so only used the above to achieve what i was after.
Hopefully someone will find this helpful.

Related

When many list are added, the page is obscured. How can I fix it?

Thank you! Now, It works very well :D
I have a CSS problem.
I use overflow: auto. But, when many list are added, the page is obscured. How can I fix it?
I used parcel-bundler. Here is my app. Link
Help me.
This is common when using flexbox to center a box vertically. You can fix it by adding margin: auto to .todo
.todo {
background: #fff;
min-width: 500px;
width: 80%;
padding: 10px;
border-radius: 10px;
position: relative;
margin: auto;
}
Remove you overflow:auto; from wrapper and set it to todo with max-height: 100%;
(wait I saw a problem created on your button then because it is loosing its position please use #AdamAzad answer)

Sticky sidebar not sticking in Vue.js

After way too much time agonizing over the breakage of a simple sticky sidebar component I've used without issue on numerous projects, I identified a partial solution that caused other issues.
This sidebar makes use of flexbox to keep the sidebar in place and treat a container div like the body of the page.
Unfortunately, it broke as soon as I started using it in Vue.js. I initially assumed it was because the element heights were not responding to dynamically populated content, but this is not the case.
The wrapper structure looks like so:
<html>
<body>
<div class="wrapper">
<div id="sidebar>
</div>
<div class="container">
</div>
</div>
</body>
</html>
And the CSS:
html {
position: relative;
height: 100%;
box-sizing: border-box;
width: 100%;
overflow-x: hidden;
height: 100%;
}
body {
overflow-x: hidden;
margin: 0;
min-height: 100%;
position: relative;
background-size: 100vw 100vh;
background-attachment: fixed !important;
width: 100%;
}
.wrapper {
display: flex;
align-items: stretch;
}
#sidebar {
height: 100vh;
position: sticky;
position: -webkit-sticky;
}
.container {
width: 100%;
margin-right: auto;
margin-left: auto;
}
NB: I did successfully cause the sidebar to look like it was sticking by setting the body height to 100%, but the actual links still scrolled, even though you could see the sidebar. Furthermore, this broke the layout properties of the Flatpickr datepicker being used on one of the most important pages in the site. Obviously, this is not a tenable solution, because a visible but interaction-less sidebar is useless, and I need my pages to actually work.
To be clear-- I chose to use sticky rather than fixed because I wanted to take advantage of flexbox to set the page content's container effectively next to the sidebar, rather than simply pushing it over using margin to keep it from being overlaid by the sidebar.
Here's a (messy, I apologize-- it's pulled out of a muuuuuuuch larger project) Codesandbox to show you the sidebar in context.
https://codesandbox.io/s/8897m88kl

Make a div scroll out to reveal main content which is placed below

I want to achieve the type of effect seen at Forde + Nichol - http://fordenicol.com/
I would like the initial div to scroll away and then reveal the main content below and be able to continue scroll down the page. I have looked at a variety of reveals and footer reveals that are available online but fixed height cause an issue when attempting to continue scroll through content.
https://jsfiddle.net/3gkazmb8/2/
HTML
<div class="overlay"></div>
<div class="content">
<p>Content Information</p>
</div>
</body>
CSS
body {
padding-bottom: 600px;
}
.overlay {
height: 1200px;
position: relative;
z-index: 2;
background: red;
}
.content {
height: 1800px;
position: fixed;
left: 0;
right: 0;
bottom: 0;
background-image: url(http://lorempixel.com/g/400/200/);
background-color: #000;
z-index: 1;
}
.content p{
color: yellow;
font-size: 50px;
padding-top: 500px;
}
This is the layout and general idea of how I want to achieve the effect but the fixed height and positions of the divs cause the content to be hidden.
Any help would be greatly appreciated.
Here we go,
Scroll Magic is an awesome plugin I have used in the past,
Use that with GSAP animation library and you will have smooth animations.
The tutorial is in the link I have attached
http://scrollmagic.io/examples/basic/section_wipes_natural.html
Finally got there. Unfortunately it wasn't fully possible with CSS so had to revert to using the plugin Curtains to achieve the transition - http://curtains.herokuapp.com/
Thanks everyone for your replies!

jQuery .height() wrong in Safari

I have a problem reading out the correct height of a DIV with jQuery in Safari. I am using jQuery("#x").height() to read out the height of the element. In the real situation, I use the result later on in the page. It works well in Chrome, Firefox and IE, but not in Safari.
Here is some code that I have extracted from my page that demonstrates the problem:
The CSS:
#x {
position: absolute;
top: 0px;
margin-top: 80px;
right: 54%;
width: 40vw;
height: auto;
max-width: 330px;
padding: 10px 3.1vw 16px;
background: #ddd;
}
.y {
position: relative;
width: 100%;
max-width: 330px;
height: auto;
max-height: 330px;
}
.y img {
width: 100%;
height: auto;
}
(some parameters seem superfluous or strange, but I need them in my context and it doesn't change the problem if I leave them out)
HTML:
<div id="x">
<h2>Header</h2>
<div class="y">
<img src="https://placehold.it/330" alt="my image">
</div>
<p class="z"><span>Some text</span><br>Some more text...</p>
</div>
Now, with this jQuery code I am getting different results depending on the browser:
console.log(jQuery("#x").height());
I put all this into a codepen: http://codepen.io/anon/pen/MyELJV?editors=1111
If you load it in Firefox, the console output is 469. If you load it in Safari, it's 154. (addition: in both Chrome/MacOS and in IE11/Win7 the value is 466). Some small part of the difference is due to different default styles, but the main problem is that Safari doesn't take the image into account when getting the height.
If tried different things (that didn't solve the problem):
I tried innerHeight(), outerHeight() and outerHeight(true) instead of height() - no basic difference (slightly different values, but still the problem in Safari).
I added width=330 heigth=330 as attributes to the img tag, it works in the codepen, but not in my real situation (with another image). Apart from that, the whole thing is responsive, so I'd like to omit these attributes anyway.
By the way: The original images are all 330x330px (i.e. all have aspect ratio 1:1), but they are scaled down on smaller screens.
I'd be very grateful for a solution...
I changed your css so that safari doesn't change height of image.
#x {
position: absolute;
top: 0px;
margin-top: 80px;
right: 54%;
width: auto;
height: auto;
/* max-width: 330px; */
padding: 10px 43px 16px;
background: #ddd;
}
.y {
position: relative;
width: 100%;
max-width: 330px;
height: auto;
max-height: 330px;
}
.y img {
width: auto;
height: auto;
}
Also use load function to fetch exact height of #x.
$(window).load(function(){
console.log($("#x").height());
});
You can refer the changed code here.
I fought a lot with this issue. Safari have a lot of troubles getting the height of an element but I found a javascript method that return the correct height of a specific element.
Here I give you the link and the support confirmation. Actually I used that in a project where I was needing to control an animation depending of an element height.
I hope that it could help someone in my same situation.
https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect
Use the getBoundingClientRect and access to the height attribute like this:
element.getBoundingClientRect().height

how to change the CSS background-image of a class-pseudoelement by Javascript only?

I'm getting nowhere with this. I have an element, which is using a :before pseudo selector.
CSS is like this:
.initHandler:before {
width: 100%;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
display: block;
height: 110%;
z-index: 999999;
background-color: white; /*background:white url(../images/ajax-loader.gif) no-repeat center center;*/
content: "initializing...";
text-align: center;
font-color: #ccc;
line-height: 150px;
vertical-align: bottom;
}
This gives me a white background for my app, which is loading "behind the curtain". On iOS I'm using a startup image, which I'm setting in the page head before jquery and jquerymobile are loaded.
I now want to change the background of my initHaendler:before element to the determined iOS splashscreen.
However I need to this in pure javascript and I have no idea how to select a class/pseudoelement to set a css value.
Can someone help out?
Thanks!
Setting CSS pseudo-class rules from JavaScript seems to suggest that you can't and offers a workaround by appending a stylesheet to the document. I'm unsure if it'd work on iOS but it's worth a shot

Categories