I am loading data on page and using infinite scroll to load more data as the user scrolls (default 20 items on page load. But depending on the screen resolution like 1080 the page loads and the vertical scroll bar is not visible or active for the user to scroll. I added a button for the user to click to load more and as they scroll that load button will hide.
Problem: on page load if a vertical scroll is active or visible how can i hide the button from the start rather then having to scroll the first time for it to hide. Also how can i keep the load button visible until a vertical bar is active.
div/button:
<div id="loadUsers" class="btn" data-bind="click: Next" style="position:fixed; width:auto; height:20px; padding:5px; bottom:10px; ">
Load more users...
</div>
knockout Next method
Next = function () {
var _page = $.views.Roster.ViewModel.CurrentPage() + 1;
$.views.Roster.ViewModel.CurrentPage(_page);
$.views.Roster.GetPage(_page);
};
hide load button once scrolling is enabled
$(document).ready(function () {
$('#main').scroll(function () {
$('#loadUsers').hide()
var div = $(this);
if (div[0].scrollHeight - div.scrollTop() == div.height()) {
Next();
}
});
});
visible binding:-
<div id="loadUsers" class="btn" data-bind="click: Next, visible: displayBtn()" style="display:none; ">
Load more users...
</div>
Script:-
self.displayBtn= function(){
return ($(document).height() < window.innerHeight);
}
With this function you can know if the vertical scrollbar is active :
var isVBActive = function(){
return ($(document).height() > window.innerHeight);
}
And with the resize event can hide or show the button :
$(window).resize(function() {
if(isVBActive())
$('#button').hide();
else
$('#button').show();
});
I hope it helps.
Related
Not sure if this is a bit of a tall order, but what I'm looking to achieve is to be able to scroll to the top of a specific page and toggle the div to show a hidden search form.
Below is what I have at the top of the page
<p>
<center>
<a href="javascript:toggle('filterresults')">
<div class="mobile-button">☰ Filter Results</div>
</a>
</center>
</p>
<div id="filterresults" style="display:none">SEARCH FORM HERE</div>
What I would like is as a user scrolls down the page a button fixed to the bottom appears allowing them to scroll back to the top and open the toggled div which is set to hide.
Is this possible? If so, any ideas how to implement it. Thank's for any advise offered.
UPDATE
Ok, this is what I've figured out so far which does what I want, this only thing I could do with is having the button fade in as the user scrolls down so far of the page
<script type="text/javascript">//<![CDATA[
var x = document.getElementById('filterresults');
function myFunction() {
if (x.style.display === 'block') {
x.style.display = 'none';
} else {
x.style.display = 'block';
}
$("html, body").animate({ scrollTop: 0 }, "slow");
}
</script>
<button onclick="myFunction()">Toggle Results</button>
I have a button:
<button type="button" class="btn btn-sm btn-primary" data-bind="attr: { 'data-target': '#MoreOptions' + Provider() }" data-toggle="collapse">More Options</button>
That controls when this div is open or closed to show 'more options'.
<div class="panel-collapse" data-bind="attr: { id: 'MoreOptions' + Provider() }, css: { collapse: $root.IsCollapsed }">---</div>
And I use a Knockout.js observable to keep it open when the data refreshes inside the div. I don't want a data refresh to collapse the div. The issue is when I do this and keep the div open, the button thinks that the div is closed. So the next time the user clicks the button, the div closes real quick and opens back up again, requiring two clicks on the button to get the div to close.
The expected behavior is to keep the div open during a data refresh, but have the button know that the div is open and close it with just one click.
I've set the CSS collapse with knockout in the div and I'm looking for a similar way to set the button for it to know that the div is not collapsed.
I've noticed that when the button is clicked to expand the div, the aria-expanded attribute is set to true where it didn't exist when the button is initially rendered; and when the button is clicked to collapse the div, the CSS property 'collapsed' is added to the button. I've played around with adding and changing these via knockout with no success.
It should be noted that the button is refreshed with the data.
I've decided to remove the bootstrap toggle button functionality and just go with the jQuery toggle in combination with knockout. The jQuery way just offers more control.
<button type="button" class="btn btn-sm btn-primary"
data-bind="click: $root.ChangeMoreOptions">
More Options
</button>
<div id="MoreOptionsDiv" style="padding-top: 10px; display: none;">
--- content ---
</div>
Knockout:
//Open or close div
self.ChangeMoreOptions = function () {
if (self.IsCollapsed() === true) {
$('#MoreOptionsDiv').slideToggle('slow', function () {
// Animation complete.
});
self.IsCollapsed(false);
} else {
$('#MoreOptionsDiv').slideToggle('slow', function () {
// Animation complete.
});
self.IsCollapsed(true);
}
}
//Keep div open on refresh if it is already open
//Search for 'none' in the style display: none
self.FixMoreOptions = function () {
if (($('#MoreOptionsDiv').attr('style').search('none') > -1)
&& (self.IsCollapsed() === false)) {
//Toggle closed div back to open
$('#MoreOptionsDiv').slideToggle('slow', function () {
// Animation complete.
});
}
}
I’ve made my navigation for mobile sticky with this code:
<div class="stickyTest" id="stickyTest2">
<ul id="nav">
<li class="homeicon"></li>
<?php echo $_menu ?>
</ul>
<script type="text/javascript">
document.observe('dom:loaded', function() {
new MobileNavigation();
var searchToggle = $('mobile-search-toggle'),
searchForm = $('search_mini_form');
if (searchToggle && searchForm) {
searchToggle.observe('click', function() {
searchForm.toggleClassName('shown');
});
}
});
</script>
<script type="text/javascript">
function ajaxsearchsubmit(form){
var search = encodeURIComponent(form.w.value);
document.activeElement.blur();
window.location="http://www.test.co.uk/search/go?w="+search;
return false;
}
</script>
<div class="clear"></div>
</div>
And the css:
.stickyTest {
background: #362011;
position:fixed;
z-index:1000;
width:100%;
top:0px;
}
#stickyTest2 {margin-top:40px;}
Now my problem is that I only need the position:fixed of the .stickyTest class and the margin-top:40px of the #stickyTest2 id to be applied for when the user scrolls down and the top navigation goes out of view. So two questions:
How do I apply those specific styles on scroll?
Is there a way to detect when the top navigation goes out of view? I know I could do something that the sticky nav styles are applied when the user scrolls beyond 200px for example but with different screen sizes etc. I’d like to know if there is a more flexible method?
How do I apply those specific styles on scroll?
If you can use jQuery library, you can detect the scroll event with this code :
$(window).scroll(function(){
// your code
});
Then you can use addClass() and removeClass() to play with class.
Is there a way to detect when the top navigation goes out of view?
You can get the height of the navigation bar with this piece of code, with jQuery again and do a test in your scroll() function with the scrollTop() method, like this for instead :
var stickyHeight = $('.stickyTest').height();
$(window).scroll(function(){
// if your top navbar is out of view
if($(window).scrollTop() > stickyHeight){
$('.stickyTest').addClass('fixed');
}else{
$('.stickyTest').removeClass('fixed');
}
});
See a live example
Source :
scroll() : https://api.jquery.com/scroll/
addClass() : https://api.jquery.com/addclass/
removeClass() : https://api.jquery.com/removeclass/
scrollTop() : https://api.jquery.com/scrollTop/
I have html page/ screen split into 4 main parts/ divs. Header, footer, main body and left vertical navigation panel. the navigation panel width is 20% and main body div is 80% width of screen. I have button in navigation panel to hide and display. so when user click this, it hide navigation panel and make main-body width to 100% of screen and vise versa. I have achieved this functionality using jQuery but its not smooth, what I mean by this, on click navigation panel slides to left but same time it make main_body disappears until navigation panel complete scroll to left.
I want this functionally to run smooth i.e. main body div increases its width same time navigation panel is scrolling to left.
http://jsfiddle.net/toxic_kz/73c8o8tq/
jQuery
$(document).ready(function () {
$(".NavigationpanelIcon_Wrapper").click(function () {
$('#NavigationBlock').hide('slide', { direction: 'left' }, 1000);
$('.Main_body_Right_Wrapper').css('width', '100%');
});
});
HTML ASP.net-MVC - Razor
<div id="body_main_wrapper">
<div id="NavigationBlock" class="Navigation_Left_Pannel_Wrapper">
<div id="Navigation_panel_sideBar">
<div class="NavigationpanelIcon_Wrapper">
<span class="_blank_glyphicon">
<i class="glyphicon glyphicon-chevron-right"></i>
</span>
</div>
<div class="NavigationpanelText_Wrapper">
<span class="navigationpaneltext">
Available Functions
</span>
</div>
</div>
<div id="Navigation_list_wrapper">
#{Html.RenderAction("DisplayFunctionsList", "Dashboard");}
</div>
</div> <!--end Navigation_Left_Pannel_Wrapper-->
<div class="Main_body_Right_Wrapper">
#RenderBody()
</div> <!--end Main_body_Right_pannel_Wrapper-->
</div> <!--end body_main_wrapper-->
I tried to replicate this quickly Fiddle here
You could wrap both elements and float the sidebar to the left while giving it a fixed position size then give the main body a margin-left that equals to the sidebar navigation width.. then on click when you hide the sidebar and just reset the main body's margin ?
Let me know if it's not working for you..
Animating the width of .Main_body_Right_Wrapper should do the trick:
$(document).ready(function () {
$(".NavigationpanelIcon_Wrapper").click(function () {
var duration = 1000;
$('#NavigationBlock').hide('slide', { direction: 'left' }, duration);
$('.Main_body_Right_Wrapper').animate({
width: '100%'
}, duration);
});
});
Edit: I forked #AwRak's fiddle to illustrate it.
Please take a look at this FIDDLE that shows and hides the text in a container on click . What I'm trying to do is that when I click open the first hidden text and then scroll down to click open another one, I want it to scroll back to the sibling image of that opened text to keep it in view. How can I find the sibling element and scroll to it on click?
This one is not valid.
$('.slider2').click(function(e) {
var imageposition = $(this).closest('.imageclass');
$(document.body).animate({scrollTop: imageposition.offset().top}, 'fast');
});
HTML:
<div class="container" style="border:2px solid #222;">
<img class="imageclass" style="width:100px;height:100px" src ="image.jpg">
<div class="slider2">Hi</div>
<div class="internal" style="display: block;">Text<p></p></div>
</div>
<div class="container" style="border:2px solid #222;">
<img class="imageclass" style="width:100px;height:100px" src ="image.jpg">
<div class="slider2">Hi</div>
<div class="internal" style="display: block;">Text<p></p></div>
</div>
..............
JS:
$('.slider2').click(function(e) {
e.preventDefault();
$(this).next(".internal").load($(this).data("ship"));
$('.internal').slideUp('normal');
if ($(this).next().is(':hidden') === true) {
$(this).addClass('on');
$(this).next().slideDown('normal');
}
var imageposition = $(this).closest('.imageclass');
$(document.body).animate({scrollTop: imageposition.offset().top}, 'fast');
});
$('.internal').hide();
You've at least a couple of problems here
$(this).closest('.imageclass') doesn't select the image that is previous sibling of <a>
even if you get your desired image, the moment your scrolling code runs, the image has not placed itself to its final position.
using $(document.body) to scroll the window (I'm doubtful about it myself)
Below code selects the right image element, gets the scrolltop at right moment, and scrolls the html, body using working syntax.
$(function () {
$('.slider2').click(function (e) {
e.preventDefault();
$(this).next(".internal").load($(this).data("ship"));
$('.internal').slideUp('normal');
var imageposition = $('.imageclass', $(this).closest('.container'));
if ($(this).next().is(':hidden') === true) {
$(this).addClass('on');
$(this).next().slideDown('normal', function () {
$('html, body').animate({scrollTop: $(imageposition).offset().top})
});
}
});
$('.internal').hide();
});
There's a bit of a problem with how your scrolling function works because the position of the active .container alters in relation to other containers(when active and inactive state).
Also, you should not be looking for the closest position but for its parent element.
Please take a look at my code: CSS
.slider2 {
margin:40px;
}
.internal p {
padding:5px;
}
.internal h3 {
text-align:center;
}
.container {
position: relative;
}
You might need to look for a way, to detect the height of an inactive container since I made mine as a static value.
JS:
$('.slider2').click(function (e) {
e.preventDefault();
$(this).next(".internal").load($(this).data("ship"));
var containerHeight = 205;
var containerIndex = $(this).offsetParent().index();
$('.internal').slideUp('normal');
if ($(this).next().is(':hidden') === true) {
$(this).addClass('on');
$(this).next().slideDown('normal');
}
var scrollPosition = containerHeight * containerIndex;
$('body').animate({
scrollTop: scrollPosition
}, 'fast');
});
$('.internal').hide();