I've been trying to make a fixed element only inside it's wrapping div, but can't get it to work even though I've tried all of the examples I've found here.
My site can be seen here. (doesn't work with screens under 800px yet)
I need the project sidebar to stay fixed until the wrapper around it ends and a new section begins. Here is an illustration of what I try to achieve
I've been using the ScrollToFixed - plugin and tried out most of the examples I've found on stackoverflow. My basic structure look like this:
<section class="projects" id="nobelbopel">
<div class="description" id="#nobelbopel-desc"></div>
<div class="projectimages"></div>
</section>
<section class="projects" id="ujevnt">
<div class="description" id"#ujevnt-desc"></div>
<div class="projectimages"></div>
</section>
I want the .description to stop at the top of the browser top, but don't outside of it's wrapping div (.projects). The height of the wrapping div (.projects) is also varying, and I think thats my main problem..
I've tried using this code, but it only works partially:
$('#nobelbopel-desc').scrollToFixed( {
marginTop: 154,
limit: $('#ujevnt').offset().top
- $('#nobelbopel-desc').height() - 154 } );
$('#ujevnt-desc').scrollToFixed( {
marginTop: 154,
limit: $('#bygdalarm').offset().top
- $('#ujevnt-desc').height() } );
and this:
$('#nobelbopel-desc').scrollToFixed({
marginTop: 154,
limit: $('#ujevnt').offset().top - 154
});
As you can see from the code I want it 154 px from the top)
but I need a code that works whether the height of the wrapping div is 100 or 1000px, and preferably based on the basic class-structure than specific divs as it is now.
Related
I created a button and when clicked it's scroll down to the next section of the page.
scroll(el) {
el.scrollIntoView({
behavior: 'smooth',
block: 'start'
});
}
<span class="btn"><a (click)="scroll(forecast)">CheckForecast</a</span>
<div #forecast class="container-fluid">
Now, when it scrolls down, the top of the section get hided behind the fixed top navBar. I need to compensate the hight of my top navBar for it to scroll all the way down!?
Thanks guys.
This is the code that worked for me at the end:
scroll(el) {
el.scrollIntoView({
behavior: 'smooth',
block: 'start'});
setTimeout(() => {
window.scrollBy(0, -40);
}, 500);}
Beside the fact that your HTML and JS is totally wrong. Here is a solution, that you may need to fit your needs but is working and very simple:
function scrollto(elna) {
let el = document.getElementById(elna);
el.scrollIntoView();
}
<span class="btn"><a onclick="scrollto('forecast')">CheckForecast</a></span>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<div id="forecast" class="container-fluid">Some forecast</div>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
The br-tags are only there to have some space and to see any effect at all.
But to make some remarks. If you provide a snippet make sure that there aren't any syntactic errors.
Your opening a-tag is missing, the keyword function is missing and you haven't included angular in your snippet.
To make it fit to angular you'll need to find out how you get the needed reference to your element. There are plenty of tutorials out there.
I am trying to animate all of the parents of an element after the one clicked.
I have tried several iterations of the following:
$(this).parent().nextAll().animate({
marginTop: '-=50px'
}, 500);
But I don't think I am getting the syntax right...
The parent element has a class of ".useritem" and I have a feeling I have to use it but I am not sure where as I thought specifying that the parent>of this item>all of them after>move up 50 px, would work.
Any help, guidance or advice would go a long way, thank you.
Edit 1: HTML
My HTML is created dynamically based on the server response. It will look like this however:
<div id='useritem' class='useritem'>
<div id='msgnotification' class='msgnotification'>0</div>
<img id='userimg' class='userimg' src='data/here'>
<div id='usertxt' class='usertxt'>
<div id='name' class='name'>User</div>
<div id='username' class='username'></div>
</div>
<div id='useradd' class='useradd'><i class='fa fa-user-plus'></i></div>
</div>
There are multiples of these stacked and when a user clicks on 'useradd' it's width is animated to 0 and the marginTop code should fire on every 'useritem' under it moving them up.
Thank you for your input and thank you to #Barmar for pointing out that my code /should/ have worked, I went over it again and realised where I was going wrong. I had wrapped the marginTop code in a timeout to wait for the initial clicked parent element to have a set animated width of 0. But of course when you try to call 'this' again, the element isn't there so the code didn't have an initial selector.
I fixed this by using .delay() instead. And now my initial code is working just without the timeout!
Thank you again for your input and time. This is the updated code:
$(this).parent().animate({
'width': 0,
'padding-left': 0,
'padding-right': 0
}, 300, function() {
$(this).next().animate({
marginTop: '-=61px'
}, 300);
});
Setup: I am developing a PhoneGap/Cordova app for iOS and Android using jQuery Mobile. The app requires a calendar which I am creating myself due to the fact that an exhaustive search of plugins didn't yield any results that satisfied all my needs. I am using seven div's - one for each day of the week - which are all float:left'd and each is set to width:14.28571428571429% as this is 1/7 of 100%. I should mention that the calendar div container is set to width: 100%. Chrome developer tools also confirms that the container (id="calendar") is using 100% of the width real estate.
Problem: Everything looks and works great on the desktop, however once I start testing on my iPhone or iPad, a small margin (about 2%) appears to the right of the calendar.
Supporting Details: I have done quite a bit of research on this, and it appears that this is due to subpixel rendering. I read about Subpixel Rendering on WikiPedia and found this two year old article regarding the way different browsers handle fractions of pixels. It seems to me that 0.28[…]% is being chopped off in mobile Safari.
The problem is, I don't know how to fix it. What confuses me even further, is that this appears to be a webkit issue, but the calendar renders just fine in desktop Chrome.
Code:
<div id="calendar">
<div class="cal-week">
<a href="javascript:monthPrev();">
<div class="day day-inactive">28</div>
</a>
<a href="javascript:monthPrev();">
<div class="day day-inactive">29</div>
</a>
<a href="javascript:monthPrev();">
<div class="day day-inactive">30</div>
</a>
<a href="javascript:monthPrev();">
<div class="day day-inactive">31</div>
</a>
<a href="javascript:selectDate(11,01,2012);">
<div class="day">1</div>
</a>
<a href="javascript:selectDate(11,02,2012);">
<div class="day">2</div>
</a>
<a href="javascript:selectDate(11,03,2012);">
<div class="day">3</div>
</a>
<div class="clearfix"></div>
<!-- fun fact: this is the first week of November, 2012 -->
</div>
[…]
</div><!-- /calendar -->
I'm having a terrible time with something similar in Firefox, so maybe you can fit my fix to fit your need.
My problem is/was that I need to calculate screen width during a changePage, which on Firefox sometimes results in the scrollbar being substracted in the width calculation, so if I need width 1000px I'm getting 983px (sans 17px scrollbar).
It took forever to console the wrong value returned by Javascript. I'm now using this to fix:
wrapWidth = document.body.clientWidth,
// FIREFOX SCROLLBAR WIDTH FIX
// When caluclating the width of the screen Firefox includes
// the scrollbar width although the page height is less
// than available screen height.
// Therefore page width is off by the toolbar width (17px).
// browser window: window.innerWidth ~ e.g. 924
// wrapper page: document.body.clientWidth ~ e.g. 907
// if the page height is smaller than screen height, correct by 17px.
fireFoxCorrection = ( window.innerWidth !== wrapWidth && wrap.height() <= window.innerHeight ) ? window.innerWidth-wrapWidth : 0,
This gives me 17px when the error occurs and 0 when it doesn't, so I can safely do
element_width = calculatedWidth + fireFoxCorrection
How about trying if you can pin the down the correction in your setup using window.innerWidth and document.body.clientWidth. If you could extract the difference, you could divide it by elements and add this as to the width of each element.
For anyone who stumbles on this:
After much (painful) searching through Webkit documentation, improper SubPixel handling is a well documented bug and needs to be fixed to make these types of issues go away permanently. The only sure work-around I can find is a negative pixel margin fix. This qusetion goes into some good detail on the matter.
In regards to my particular issue with seven columns, a negative pixel on each of the seven columns was creating a margin on the right-hand side of the screen. What fixed me was the idea of only applying the negative margins to every other column. So now columns 0, 2, 4, and 6 all have a margin-left: -1px and the other three do not. It works for now, let's hope they get to addressing this issue sooner rather than later.
Cheers.
JQuery mobile footers are not properly fixed to the bottom of the screen. In the normal behavior they follow the bottom with a lag. And in most case it remains quite buggy (it doesn't show at the bottom of the screen).
My question is why is this?
Take into consideration that:
Solutions seems to work quite well for modern browser and CSS (position: absolute,
bottom: 0px). I guess that some navigators don't support that? Which ones? And why is
that?
Sencha touch seems to give a much better alternative on the footer case. But what's the secret? Is it compatible with all browsers?
Jquery is at its .rc1 at the time of this question. It probably won't be fixed in the JQuery mobile 1.0 release. (jQuery Mobile and a fixed footer)
From the release notes:
http://jquerymobile.com/blog/
iOS5: Dramatically improved page transitions and true fixed toolbars
The team has spent a ton of time working on trying to improve
transitions and fixed toolbars because we know these are important
features to developers. After spending hundreds of hours working on
refinements, we now believe that the path to substantial,
cross-platform improvements in these areas can only happen when mobile
platforms start supporting overflow properties natively.
JavaScript-based momentum scroller scripts are too heavy, unresponsive
and narrowly compatible to be a way forward.
That’s why we’re very excited by iOS5′s upcoming support for a
touch-targeted version of overflow:auto , and proper support for
position:fixed which allows for internal scrolling regions with the
native momentum scrolling with CSS. In Beta 3, we’ve added an
enhancement layer to leverages these new CSS capabilities to will
enable us to bring both truly “fixed” toolbars and super smooth
transitions in iOS5, all by using web standards and very little
additional code.
https://github.com/jquery/jquery-mobile/commit/2369e2fa322e721c687408f790230efe4f621fef
https://github.com/jquery/jquery-mobile/commit/2a6c7fc1b982c4308a0450a308f5a66a10e949cf#diff-8
https://github.com/jquery/jquery-mobile/commit/23e79fb1dbba9f4eb15e29b4842579bdd0d1b100
There are some JavaScript scrollable-content plugins that you can use to create a fixed footer that doesn't suck:
iScroll -> http://cubiq.org/iscroll-4
ScrollView -> http://jquerymobile.com/test/experiments/scrollview/
Flexcroll -> http://www.hesido.com/web.php?page=customscrollbar
I'm sure there are more but these are three I've had some success with. I've settled on using iScroll personally.
To get a nice fixed footer you can set the header to position: absolute and top: 0, set the footer to position: absolute and bottom: 0, and then set the content area to position: absolute, top: <bottom of header> and bottom: <top of footer>.
One issue I have found with this is that setting the document to 100% height will not allow the address bar to be scrolled out of view. To fix this, when the load event fires on the window object I set the height of the document to 100px more than the screen height (window.innerHeight). I then scroll to the top of the page ($.mobile.silentScroll(0)), and set a timeout to reset the height of the document to 100%.
$(window).bind('load', function () {
$.mobile.activePage.css({
height : (window.innerHeight + 100) + 'px',
'min-height' : (window.innerHeight + 100) + 'px'
}).find('[data-role="footer"]').css({
bottom : '100px'
});
$.mobile.silentScroll(0);
setTimeout(function () {
$.mobile.activePage.css({
height : '100%',
'min-height' : '100%'
}).find('[data-role="footer"]').css({
bottom : '0px'
});
if ($.mobile.activePage[0].id in myScroll) {
myScroll[$.mobile.activePage[0].id].refresh();
}
}, 750);
});
The above example:
Changes the height of the current pseudo-page to 100px more than the height of the screen.
Changes the position of the footer so it stays in view for the whole process.
Scrolls to the top of the page (i.e. scrolls the address bar out of view).
Sets a timeout to re-size the current pseudo-page to 100% height and reset the position of the footer. The timeout is necessary so the scroll can occur before the height is reset to 100%.
I used iScroll in this code and saved each iScroll instance in an array so that I could refresh the iScroll content area whenever I made changes to the DOM that affected the size of the scrollable area.
I also trigger the load event on the window object whenever there is an orientation change:
$(window).bind('orientationchange', function () {
$(window).trigger('load');
});
I'm working with Jquery.Mobile 1.2alpha, doesn't seem to be an issue anymore. The data-position-'fixed' works great
<footer data-role="footer" data-position="fixed">
<div data-role="navbar">
<ul>
<li>Url 1</li>
<li>Url 2</li>
<li>Url 3</li>
<li>Url 4</li>
</ul>
</div>
</footer>
Additional suggestion to disable the "webview bounce" if you're developing for a wrapper app.
http://community.phonegap.com/nitobi/topics/uiwebview_bounce
Fixed footer solution that worked for me:
<div data-role="footer" data-position="fixed" style="position: absolute">
Ok so I have this Page and as you can see if you scroll down below the map you will see the logo and header for "Barinos Market"...if you click on the read more link the text expands ..which is exactly what i want. The problem I am trying to resolve is when the user clicks read more I need the barinos market image on the left to scroll down with the text and be half way down the div....here is the code...
<div id="barino_info">
<div id="barino_header"></div>
<div class="info_body">
<div id="barino_left_body">
</div>
<div class="right_body">
<div class="right_body_outer">
<ul class="play_navigation">
<li class="active">The Story</li>
<li>The Video</li>
<li><a onclick="show_gallery('barino');" href="#" class="navlinks barino_gallery_bottom" ref="bottom_barino_gallery">The Gallery</a></li>
<li>The Equipment</li>
</ul>
<div class="right_body_inner tab_content">
Barino's Market is an ......
The image is a background url on #barino_left_body
Any ideas on a strategy on how to achieve this..i was thinking of maybe jquery offset or something like that
I am using this plugin to do the expanding...here is my jquery to do it
$('.right_body_inner, .doughboy_right_body_inner, .haw_right_body_inner, .river_right_body_inner, .vib_right_body_inner, .barino_equipment, .dough_equipment, .river_equipment, .haw_equipment, .vib_equipment').expander({
slicePoint: 355, // default is 100
expandEffect: 'fadeIn',
expandSpeed: '8', // speed in milliseconds of the animation effect for expanding the text
userCollapseText: '(less..)' // default is '[collapse expanded text]'
});
After the "read more" is clicked, you can calculate the height of the surrounding <div> and add (or animate) the top margin of #barino_left_body to half the surrounding <div> height plus half the height of #barino_left_body.
$('.read-more').click(function(event){
var parentHeight = $(this).parents('.info_body').height();
var imageHeight = $('#barino_left_body').height();
var centerImage = (parentHeight-imageHeight)/2;
$('#barino_left_body').animate({"marginTop": centerImage}, 250);
event.preventDefault();
});
P.S. I'm curious as to why you made it a background image.
Try this code on for size, I might get some references wrong with those parent/prev, if you can't figure it out, post the errors.
JS
$('.right_body_inner, .doughboy_right_body_inner, .haw_right_body_inner, .river_right_body_inner, .vib_right_body_inner, .barino_equipment, .dough_equipment, .river_equipment, .haw_equipment, .vib_equipment').expander({
slicePoint: 355, // default is 100
expandEffect: 'fadeIn',
expandSpeed: '8', // speed in milliseconds of the animation effect for expanding the text
userCollapseText: '(less..)', // default is '[collapse expanded text]',
afterExpand: function($thisElement) {
$thisElement.parent().prev().height($thisElement.height())
},
onCollapse: function($thisElement, byUser) {
$thisElement.parent().prev().css('height','');
}
});
I add 2 callbacks basically.
The first one afterExpand sets the height to the height of the expanded div. The CSS you have already sets the position of the image properly.
The second one onCollapse sets removes my previous definition for height, returning to the div to it's CSS definition and bringing the layout back to it's original design.
Used .css() in the second function just so you can see the different approaches to setting height, you can decide between the two.
I'm not sure if you can move a background image with jQuery. I think you cannot. However you do can move a normal image, so that's what I would do.
I would select the image through jquery and then use animate() to set the new position of it. css() would work too. The top will be ((the total size of the div) - (the size of the image))/2
var h1 = $("#barino_left_body").height();
var h2 = $("#myimage").height();
var position = (h1-h2)/2;
$("#myimage").animate({"top":position},250);
You do this when expanding the text.
This should do the trick. But if you really need to use the image as background I don't know your answer. :(
I hope it helped.