Just a quick jQuery Mobile question.
I am working with ui-grid-a (for the basic case of 50/50 split) and I can populate and render the grid without issue. However in some cases there are fewer items than the content size and I was curious if it was possible to have the grid not wrap the content, but instead fill the available space in the div.
I have tried a few different methods.
1) Basic configuration no modification- the ui-grid seems to wrap the content inspection shows the height on the data-role=content is much smaller than the page. Thus the grid is "filling" the content.
2) As a result I then worked to expand the content. Using some JS fiddle code (below) I was able to set a height to the content (and inspection confirmed this) however the grid remains only a fraction of the content area
jQuery code in .ready() to adjust the content size to fill page
var screen = $.mobile.getScreenHeight();
var header = $(".ui-header").hasClass("ui-header-fixed") ? $(".ui-header").outerHeight() - 1 : $(".ui-header").outerHeight();
var footer = $(".ui-footer").hasClass("ui-footer-fixed") ? $(".ui-footer").outerHeight() - 1 : $(".ui-footer").outerHeight();
var contentCurrent = $(".ui-content").outerHeight() - $(".ui-content").height();
var content = screen - header - footer - contentCurrent;
$(".ui-content").height(content);
3) I tried binding this to the page load thinking that maybe the grid was calculated before the Javascript on ready fired. But no luck.
Any suggestions would be very welcome. I am not restricted to jQuery, I've tried many CSS options however those styles don't seem to help when using the custom jQuery Mobile UI (Content/Page)
Thank you in advance,
As requested a sample markup mirroring my own (I have some addition divs within this that are popups, but this represents the main content)
<div data-role="page" id="home" data-theme="b">
<div data-role="header">
<h1>Home</h1>
</div>
<div data-role="content">
<div class="ui-grid-a">
<div class="ui-block-a">
Test
</div>
<div class="ui-block-b">
Test
</div>
<div class="ui-block-a">
Test
</div>
<div class="ui-block-b">
Test
</div>
<div class="ui-block-a">
Test
</div>
<div class="ui-block-b">
Test
</div>
</div>
</div>
</div>
First I want to give a big thank you to #Omar for his help in creating this solution.
There are a couple of components that factor into this problem. First the page load sequence as to when the element heights are calculated for header and footer and content. To account for this you can bind to the pagebeforecreate event:
$(document).bind("pagebeforecreate", function (e, data) {
$(document).on("pagecontainertransition", contentHeight);
$(window).on("throttledresize orientationchange", contentHeight);
});
Now I will discuss how to resize a grid dynamically
Next you must account for the screen size of the device and calculate the appropriate size for each of the row elements using the code
var screen = $.mobile.getScreenHeight();
You must then calculate the size of the content and the size available for that content
var header = $(".ui-header").hasClass("ui-header-fixed") ? $(".ui-header").outerHeight() - 1 : $(".ui-header").outerHeight();
var footer = $(".ui-footer").hasClass("ui-footer-fixed") ? $(".ui-footer").outerHeight() - 1 : $(".ui-footer").outerHeight();
var contentCurrent = $(".ui-content").outerHeight() - $(".ui-content").height();
var content = screen - header - footer - contentCurrent;
From here you can calculate the grid size
var numRows = 3;
$(".ui-content .ui-block-a .ui-btn,.ui-content .ui-block-b .ui-btn").height((content / numRows) - 32);
}
Next as you may have more than one grid
In this case you can add a descending selector to specify which grid you would like to resize
$("#GridID.ui-content .ui-block-a .ui-btn, #GridID.ui-content .ui-block-b .ui-btn").height((content / numRows) - 32);
Finally since this event binds to page only once you have to resize all grids at the same time, however the grids may be on different pages and you must select those sizes as each page may have different sizes of content
var header = $("#pageID .ui-header").hasClass("ui-header-fixed") ? $("#pageID .ui-header").outerHeight() - 1 : $("#pageID .ui-header").outerHeight();
var footer = $("#pageID .ui-footer").hasClass("ui-footer-fixed") ? $("#pageID .ui-footer").outerHeight() - 1 : $("#pageID .ui-footer").outerHeight();
var contentCurrent = $("#pageID .ui-content").outerHeight() - $("#pageID .ui-content").height();
var content = screen - header - footer - contentCurrent;
Here is a fiddle to demonstrate the full functionality
http://jsfiddle.net/m6bbbpg1/
Hopefully this will help someone else as this seems to be a fairly common task when creating generic mobile webpages
Related
i'm trying to make my twitter widget (which is in its own div) the same height as another div (called mainslider). I've tried some stuff with JavaScript and JQuery but i'm not too experience with this.
An extract of my code is below:
<div class="mainslider" id="mainsliderid">
(SLIDER CODE HERE THAT I REMOVED)
</div>
<script>
var twitterheight = $('mainsliderid').height();
</script>
<div class="maintwitter">
<a class="twitter-timeline" href="https://twitter.com/twitter" data-widget-id="704258053198254080" height="twitterheight" width="100%">Tweets by #twitter</a>
<script>
!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';
if(!d.getElementById(id)){
js=d.createElement(s);
js.id=id;js.src=p+"://platform.twitter.com/widgets.js";
fjs.parentNode.insertBefore(js,fjs);
}}(document,"script","twitter-wjs");
</script>
</div>
So i solved the problem myself, and it was really simple.
Due to the nature of the slideshow i had, its height was set proportionally to its width. Because i am using proportions of the screen width to change both the twitter and slideshows width i could just use the unit 'VW' which is 1 % of the screen width and just had to multiply it by the correct value. Works fine now.
I am working on a basic WYSIWYG word processor dealing with lengthy documents. Currently I am taking a HTML article element filled with approximately 5000 divs and applying some jQuery code to style and format it. 5000 is likely to be the absolute maximum.
Firstly, I use regex to apply CSS and this is working nicely at about
107ms.
Secondly, I iterate over the divs, storing their height and
every 1000px, inserting some HTML to act as a page break (the
pagination is vertical - imagine pages in MS Word). The second part
takes around 1200ms.
For initial page loading, I'm okay with that. Unfortunately, the article element needs to be contenteditable.
When a user changes the content of the article, I can simply apply my regex on the div they have changed (0-1ms) and that is no problem, however, any change to the content means (a possible) altering of the height between page breaks, and therefore necessitates repagination.
Having the browser lock up for a second every time the user hits return, delete, ends up on a new line or numerous other additional events that would alter the pagination is obviously not practical. While performance is better when making changes nearer the end of document, the user requires the same level of responsiveness when making changes to page one.
I need to address this performance issue and make the UI responsive when repaginating.
Here's an example of the HTML before the JS code is run on it:
<article contenteditable="true">
<header contenteditable="false"><h1>Header Text</h1></header>
<div>Content</div>
<div>Content</div>
<div>Content</div>
...
<footer contenteditable="false"><h3>Footer Text</h3></footer>
</article>
And after the JS code is run:
<article contenteditable="true">
<header contenteditable="false"><h1>Header Text</h1></header>
<div class="regex-set-class">Content</div>
<div class="regex-set-class">Content</div>
<div class="regex-set-class">Content</div>
<section contenteditable="false">
<h3>Footer Text</h3>
<figure><hr><hr></figure>
<h1>Header Text</h1>
<h2>Page Number</h2>
</section>
<div class="regex-set-class">Content</div>
<div class="regex-set-class">Content</div>
<div class="regex-set-class">Content</div>
...
<footer contenteditable="false"><h3>Footer Text</h3></footer>
</article>
And here is the JS code performing the pagination:
function PaginateDocument()
{
// Variables
var height = 0;
var page_count = 1;
// Remove existing page breaks
$("section").remove();
// Iterate over each div elements
$("div").each(function()
{
// Check whether page is too long
if (height + $(this).outerHeight(true) > 1000)
{
// Create page break
$(this).before("<section contenteditable=\"false\"><h3>" + page_footer + "</h3><figure><hr /><hr /></figure><h1>" + page_header + "</h1><h2>" + page_count + ".</h2></section>");
// Adjust variables
page_count++; height = 0;
}
// Increment current page height
height += $(this).outerHeight(true);
});
}
I am very new to JQuery. I am trying to create a webpage which can be responsive as per the screen size it is viewed on. Usually I do it with CSS but this time I think will have to try JQuery.All div's will have images so need to give them height else they wont display.
The issue is when the page is loaded the left side main image div jumps like half the screen size and then resizes to the height that is generated by JQuery. For eg: the default height of the div is some 396 px and as per the screen it is given 798px so it sizes first to 396 and then to 798 and it shows and looks very bad.
The layout is such that there is no header but has a fixed footer and hamburger icon is in the footer which min-height 50px. I am using Bootstrap.
I have not used any css for main div's as I am using col-md-9 and col-md-3. I have also attached the layout below
The code is below
-- no header--
<div class="row">
<div class="row" id="main-services">
<div class="col-md-9" id="left-services"></div>
<div class="col-md-3" id="right-services">
<div class="row btn-menu top-right-services" id="top-right-services"></div>
<div class="row bottom-right-services" id="bottom-right-services"></div>
</div>
</div><!--class="row" id="main-services"-->
</div>
--fixed footer with min height 50px, the main menu is here--
JQUERY
script(document).ready(function($) {
jQuery(window).on('load resize', function(){
//get windows height
var winWidth = jQuery(window).width();
var winHeight = jQuery(window).height();
var imgHeight= winHeight-50;
var onequater=(winHeight*1)/4 ;
var threequater=((winHeight*3)/4)-50 ;
jQuery('#left-services').css('height',imgHeight+'px');
jQuery('#right-services').css('height',imgHeight+'px');
jQuery('#top-right-services').css('height',onequater+'px');
jQuery('.right-project-menu').css('height',onequater+'px');
jQuery('#bottom-right-services').css('height',threequater+'px');
});
});
and I have also tried the code here resize div - jquery
layout image
Please help me
I have a project where the requirement is to move the footer ( #footer ) upward while scrolling down the page in a parallax-like effect. When you start scrolling down the page, the footer should start moving upward only until it's visible in the (bottom part of the) viewport.
The footer should have covered most of the preceding <div> half way up and in full when it has reached the top of the viewport.
The page may have a similar html structure like this :
<body>
<div id="sectionA" class="div">First section</div>
<div id="sectionB" class="div">Second section</div>
<div id="sectionC" class="div">Third section
<div class="box"></div>
<div class="box"></div>
<div class="box"></div>
</div>
<div id="footer" class="div cf">Footer</div>
</body>
The parallax-like effect is achieved via javascript/jQuery adding a dynamic negative value to the top CSS property of the (relative positioned) footer. Here is the code for what it matters :
var $window = jQuery(window),
$footer = jQuery("#footer"),
$viewport = window.innerHeight,
$startEffect = $footer.offset().top - $viewport;
function footerParallax() {
var $scrollPos = $window.scrollTop() - $startEffect,
$ratio = 0.6;
$footer.css({
top: -($scrollPos * $ratio)
});
}
$window.scroll(function () {
footerParallax();
});
The (obvious) issue is that as soon as the top property starts getting a negative value, the footer starts moving away from the bottom of the page.
I have prepared a JSFIDDLE and assigned colors to each section and body to make it clearer. The body (dark-red) is visible under the footer after scrolling to the bottom.
What have I tried?
modifying the margin-top instead of the top property: this does the trick, however the preceding <div> that has to be covered by the footer (#sectionC in the example above) overlaps the contents of the footer and breaks its layout regardless that it is not visible due to its z-index property (added some floating boxes in the fiddle to make it evident.... a clearfix hack didn't help either.)
setting a static position to the footer: neither top or margin-top have effect over a static element.
Changing/reducing dynamically the height of #sectionC instead of top of footer to produce the effect of moving the second upwards : the footer stops moving as soon as height is equal to 0 (neither negative size or negative paddings are allowed)
Changed the height dynamically of the html and/or body tags to no avail.
I have also tried some parallax plugins like skrollr and skrollr-stylesheets and some others.
The problem with this solution (same with others) is that it relays in an specific (offset) position of the footer measured in px and set in a data attribute, but if the content changes dynamically, for example using the masonry plugin to arrange elements in another section of the document, the measures become inaccurate and the footer may start moving too early or too late.
By the way, other CSS sticky-footer techniques won't work because, well, they actually push the footer to the bottom of the page, and here we are doing the opposite.
I guess the question is either :
how to keep the footer stick to the bottom of the page while it is moved upwards? - or -
how to reduce the gap to 0 between the end of the document and the bottom edge of the footer?
I am starting to think that this issue has not a real solution the way it is, or maybe I am already too tired to see the obvious. I am interested in learning alternative solutions or hacks via CSS / javascript / jQuery or all of the above.
Bear in mind that I am not asking how to create the parallax effect UNLESS a totally different approach (or tweaks to the existing js code) solves the position issue.
IMPORTANT : Please consider that this is a WP site with an XHTML 1.0 Transitional DOCTYPE, and has installed many other jQuery plugins like masonry, scrollTo, jQuery UI, etc. I may have not control to change many things from the original structure (and I don't want to) so the idea is to implement this without breaking too many things and from a modular script.
EDIT #1 : Added a graphic to clarify the question.
Figure A. shows a regular web page scrolled down to the end. The red square represents the viewport and the footer (grey) is slighted moved to the right for illustration purposes. The body has a reddish background color (not visible in normal conditions) just for illustration purposes too. NOTE: the height of each section as well as the height of the footer is determined by their content (forms, images, text, etc.) so is NOT fixed.
Figure B. shows the current issue: If footer slides up in a parallax-like effect (see JSFIDDLE for reference) while scrolling down the page, it starts covering any preceding section above it (WITHOUT modifying neither its own height or the height of the preceding sections) AND it also starts separating itself from the bottom of the page, therefore the body's color background becomes visible. NOTE: the bigger the viewport is (fullscreen mode for instance) the higher the footer is moved upward (and more content is covered by it)
Figure C. is the expected result: the footer should be stuck to the bottom of the page, in other words, it should be the last visible element after the page has been totally scrolled down (and not the body background as in Figure B.) Notice that the contents and the size of each section (including the footer) should (ideally) remain untouched. Having said that, adding padding bottom to the footer or increasing its height is not the expected result since it would break its original visual layout.
Updated Version
Below is an updated version that should better matches your requirements.
This version goes back to relative positioning for the footer element and uses margin-top to position it.
margin-top is calculated off of the previous elements offset, height and current window scroll position. It then uses either
the viewport height if the footer starts offscreen
the initial top value of the footer element ($startEffect) if the footer started onscreen
to determine the actual value for margin-top.
To help keep the footer's layout from being affected by this, wrapping the content of the footer in an absolutely positioned div did the trick for the sample code provided.
Example Fiddle
CSS:
#footer > div {
position: absolute;
top: 0;
left: 0;
...
}
HTML:
<div id="footer" class="div cf"><div>Footer</div></div>
Code:
var $window = jQuery(window),
$footer = jQuery("#footer"),
$viewport = window.innerHeight,
$startEffect = $footer.offset().top;
$prev = $footer.prev(),
$useStartEffect = $startEffect < $viewport;
function footerParallax() {
var $scrollPos = $window.scrollTop() - $startEffect,
$ratio = 0.6;
var prevOffset = $prev.offset().top + $prev.height() - $window.scrollTop();
var marginTop = 0;
if(prevOffset < $viewport && prevOffset < $startEffect) {
if($useStartEffect) {
marginTop = (prevOffset - $startEffect)*$ratio;
} else {
marginTop = (prevOffset - $viewport)*$ratio;
}
}
$footer.css({
"margin-top": marginTop + 'px'
});
}
$window.scroll(function () {
footerParallax();
});
footerParallax();
How was it solved?
As I mentioned in my question, I was too tired to see the obvious but #dc5's answer put me on the right track :
To help keep the footer's layout from being affected,
wrapping the content of the footer in an absolutely
positioned div does the trick
Based on that comment, the answer became simpler than the whole code he proposed needing only :
(dynamically) wrapping the content of the footer in an absolutely positioned div using jQuery's .wrapInner() method
animating the footer by setting the margin-top property instead of the top property
So this extra CSS :
#footerInnerWrapper {
position: absolute;
top:0;
left:0;
width: 100%;
background-color: #666 /* same as footer */
}
and the tweaked original code
var $window = jQuery(window),
$footer = jQuery("#footer"),
$viewport = window.innerHeight,
$startEffect = $footer.offset().top - $viewport;
// add inner wrapper
$footer.wrapInner('<div id="footerInnerWrapper" />');
function footerParallax() {
var $scrollPos = $window.scrollTop() - $startEffect,
$ratio = 0.6;
$footer.css({
// top: -($scrollPos * $ratio)
marginTop: -($scrollPos * $ratio)
});
}
$window.scroll(function () {
footerParallax();
});
did the trick. See JSFIDDLE
This does what I think you need, the footer sticks when it has scrolled in view entirely:
jsFiddle
Code added:
function footerParallax() {
var $scrollPos = $window.scrollTop() - $startEffect,
$ratio = 0.6,
$newTop = -($scrollPos * $ratio),
$oldTop = parseInt($footer.css('top')),
$nonRelTop = $footer.offset().top - $oldTop,
$wanted = ($window.scrollTop()+$viewport-$footer.height());
if ($nonRelTop + $newTop < $wanted) {
$('#sectionC').css('display', 'none');
$wanted = ($window.scrollTop()+$viewport-$footer.height());
$nonRelTop = $footer.offset().top - $oldTop;
$newTop = $wanted - $nonRelTop;
} else {
$('#sectionC').css('display', 'block');
}
$footer.css('top', $newTop);
}
$window.scroll(footerParallax);
And in the CSS I added this so that $footer.css('top') wouldn't produce NaN:
#footer {
top:0;
/* ... */
}
EDIT: A completely new approach after more clarification of OP. I now have a fixed position footer that starts increasing in height to take over the entire screen when the user has scrolled passed half of the document. The HTML, CSS and Javascript have all been updated to achieve this:
jsFiddle
I could use a little help with the following issue. What I've got is a fairly basic one-page website. Stripped down, it's structure looks pretty much like this:
<div class="full_height" id="home">
<div class="container">
<div class="row">
<div class="span8">
CONTENT GOES HERE
</div>
</div>
</div>
</div>
This div structure repeats 5 times, with consecutive id's [home, second, third, fourth, fifth]. The problem I'm having is that I'd like the .full_height containers to be the same size as the window upon loading the site and resize along with the window size upon resizing. In addition, the div's size should never become any smaller than it's children.
My current attempt looks like this:
$(window).on("resize load", resizeWindow);function resizeWindow( e ) {
var newWindowHeight = $(window).height()-160;
var idSelector = ["home","second","third","fourth","fifth"];
for (var i = 0; i < idSelector.length; i++) {
var element = document.getElementById(idSelector[i])
if( element.offsetHeight < element.scrollHeight){
$("#"+idSelector[i]).css("height", "auto" );
}
else{
$("#"+idSelector[i]).css("height", newWindowHeight );
}
}
}
Now, the script above sort of does what I'm looking for but with some hick-ups.
i) Upon loading the site it only adjusts the div height to the windows size, not meeting the children requirement. It only does this upon resizing the window.
ii) While resizing the window, the div height will flicker back and forth between "auto" and window size. Depending on when you stop resizing it will take either of the two sizes as its height.
Any ideas?
You need to start with 100% height all the way up the HTML tree:
html, body, #full_height {
height:100%;
}