I'm using the $.messager from EasyUI, and everytime I click on the button the dialog displays, but the page scrolls down.
Here is the code im using :
$(function () {
var button = $('.form_button');
button.click(function(e) {
var user_id = $(this).attr('user_id');
$.messager.defaults.ok = 'Yes';
$.messager.defaults.cancel = 'No';
$.messager.confirm('Confirm','Are you sure you want to block this user?',function(r){
if (r){
alert(user_id);
}
});
e.preventDefault();
});
});
Update you can get current scroll position by $(window).scrollTop()
var currentPos = $(window).scrollTop();
$(window).animate({scrollTop:currentPos }, '500');
you should use following in your function when you click that button.
scrollTop will take your window at normal position (when the page was loaded)
$(window).animate({scrollTop:0}, '500');
This is a bug in the framework, as the demos on its home page exhibit the same behaviour. You should file a bug.
Fortunately, you can make several workarounds though. Scrolling to the top may be the easiest, but IMHO that's a UX nightmare. You should calculate the center of the current viewport, and show the window there. Maybe this can be done in CSS too, I am not sure.
Related
In jQueryMobile, on the page load, I would like to scroll to a given position. I know how to do it in classic jQuery, but in jQueryMobile there is an auto scroll top on the page load.
I tried to do :
$( document ).ready(function() {
$.mobile.silentScroll(1000);
});
That doesn't work. My page stay blocked to the top of the page.
While if i click on a link with onclick="$.mobile.silentScroll(1000);" that works perfectly !
I just would like to scroll to a yPosition on the page load :) !
=======EDIT============
After suggestions of White Raven and Omar I've tried to do this :
$( document ).delegate("#pagePkmn", "pageinit", function() {
$.mobile.silentScroll(1000);
});
OR this :
$(document).one("pagecontainershow", function () {
$.mobile.silentScroll(1000);
});
But still no effect ...
Thanks for your attention.
Using $(document).ready() is a bad idea:
http://view.jquerymobile.com/1.3.1/dist/demos/faq/dom-ready-not-working.html
It is recommended to use pageinit
=== EDIT ===
You can always use the ghetto way:
setTimeout(function(){$.mobile.silentScroll(1000);}, 1000); // scroll after 1 second
Use pagecontainershow as it triggers after page is shown and JQM performes a default scroll to page's top.
$(document).one("pagecontainershow", function () {
/* scroll */
});
I'm designing a responsive website and am using media queries to handle the responsiveness. However along with the CSS I want to disable certain jQuery click functions at a certain window width.
Right now I can do this successfully on page load but I want to also be able to do it assuming the user resized the window.
(paragraph 3) So for example if the user starts off with a really big window on his/her computer and he/she resizes it to be a very small window he/she should not be able to activate the click functions anymore. Conversely if a user starts off with a very small window on his/her computer and resizes it to be very big he/she should be able to activate the click functions.
I have tried multiple solutions but none seem to work.
Basically I want to make some clickable objects not clickable anymore or at least have them click and do nothing at a certain window width.
Simply checking at page load and no other time makes it so that what should happen in paragraph 3 doesn't happen.
$(document).ready(function(){
if($(window).width() > 992){
$('#portclick').click(function(){
$('#pagecont').slideToggle(500);
$('#icons').slideToggle(500);
})}})
$(document).ready(function(){
if($(window).width() > 992){
$('#name').click(function(){
$('#projects').slideToggle(500);
})}})
I tried remove the id attribute that I'm using to call the function on at certain window widths and readd them at the width but this doesn't seem to work either. Removing the id doesn't seem to disable to click function at all.
And my most recent solution which comes the closest is just to bind the click function to window resize. So far this works but it is extremely buggy so when you get to a width where the click function works and you try clicking it will do the toggle function about 100 times before it stops. But it does sustain the condition described in paragraph 3.
$(document).ready(function() {
$(window).resize();
});
$(window).resize(function(){
if($(window).width() > 992){
$('#portclick').click(function(){
$('#pagecont').slideToggle(500);
$('#icons').slideToggle(500);
})}
else return})
$(window).resize(function(){
if($(window).width() > 992){
$('#name').click(function(){
$('#projects').slideToggle(500);
})}
else return})
Does anybody have an idea for a working solution that would work flawlessly like css media queries do? I don't think this is that complicated of a problem to work around so I'm hoping for some good answers! Thank you guys so much in advance!
Several problems here. First, resize fires almost constantly while the window is moving, so don't actually trigger anything on that. Second, you should only bind your event handlers once (or if you must bind more than once, make sure you clear out the old ones.) You can simplify thusly:
$(document).ready(function() {
var isLargeWindow;
$(window).on('resize', function() {
isLargeWindow = $(this).width() > 992;
});
$('#whatever').on('click', function(e) {
if (isLargeWindow)
// do large window stuff
else
// do small window stuff
});
});
My simplest way of doing that is not using the resize event at all just attach
the click event and add an early return term if the window size doesn't suite your needs.
Example code:
$('#portclick').click(function(){
winWidth = $(window).width();
/* You can add an height value too */
winHeight = $(window).height();
if ( winWidth < 992 ) return;
/* Youe Code Executes */
});
If you want the if statement to be called after the resize has happened then do something like this:
http://jsfiddle.net/sLk5ro6c/1/
$(window).resize(function (e) {
window.resizeEvt;
$(window).resize(function () {
clearTimeout(window.resizeEvt);
window.resizeEvt = setTimeout(function () {
doneresizing();
}, 250);
});
});
function doneresizing() {
if ($(window).width() > 500) {
// DO SOMETHING HERE
alert('example');
}
}
This way the code won't be called every time during the resizing of the window
I have this code and it works exactly as I want. The menu bar sits on top and recognizes the section it is on or in. You can click the links in the yellow menu to move between the sections.
Demos: http://jsfiddle.net/spadez/2atkZ/9/ and http://jsfiddle.net/spadez/2atkZ/9/embedded/result/
$(function () {
var $select = $('#select');
var $window = $(window);
var isFixed = false;
var init = $select.length ? $select.offset().top : 0;
$window.scroll(function () {
var currentScrollTop = $window.scrollTop();
if (currentScrollTop > init && isFixed === false) {
isFixed = true;
$select.css({
top: 0,
position: 'fixed'
});
$('body').css('padding-top', $select.height());
} else if (currentScrollTop <= init) {
isFixed = false;
$select.css('position', 'relative');
$('#select span').removeClass('active');
$('body').css('padding-top', 0);
}
//active state in menu
$('.section').each(function(){
var eleDistance = $(this).offset().top;
if (currentScrollTop >= eleDistance-$select.outerHeight()) {
var makeActive = $(this).attr('id');
$('#select span').removeClass('active');
$('#select span.' + makeActive).addClass('active');
}
});
});
$(".nav").click(function (e) {
var divId = $(this).data('sec');
$('body').animate({
scrollTop: $(divId).offset().top - $select.height()
}, 500);
});
});
However, the code itself gets quite laggy as soon as you start putting any content in the boxes. According to help I've received, it's that I am repeatedly changing page layout properties via the animation and querying page layout properties in the scroll handler, thus triggering a large number of forced layouts.
User Tibos said that:
You could get a big improvement by disabling the scroll handler during
the click animation and instead triggering the effects with no checks
made (set the active class on the clicked element).
Could anyone show me how I can achieve this optimization?
Demo page and another concept demo: http://codepen.io/vsync/pen/Kgcoa
The KEY here is to position your select inside another element, so when it get's FIXED to the screen, it won't affect the other elements by the sudden lack of height it once physically occupied. I've added a little CSS also. It's important to use the jQuery version 1.11 or above, because they fixed a but that caused the same class to be added again and again, regardless if an element already has it. bad for performance. Also, I've used a for loop and not jquery each loop on the sections elements, because a for loop is much faster due to the lack of function callback an each function has. Also, a very important thing is to make sure that every element that can be cached is actually cached, so we don't look for it endlessly in the DOM...
For showing which section we're on, I'm looping on all the sections, starting for the last one, which is important to, and checking if each top has passed the window's top using getBoundingClientRect method for knowing such thing. This helps knowing where we are.
var pos,
$el = $('#select'),
navItems = $el.find('.nav'),
menuHeight = $el[0].clientHeight,
scrollY,
sections = $('.section').toArray(), // cache sections elements
pointOfAttachment = $('.jumbo')[0].clientHeight - menuHeight;
// Bind events
$(window).on('scroll.nav', updateNav)
.on('resize.nav', updateNav);
function updateNav(){
scrollY = window.pageYOffset || document.documentElement.scrollTop;
for( var i = sections.length; i--; ){
if( sections[i].getBoundingClientRect().top < 0 ){
navItems.filter('.' + sections[i].id).addClass('active').siblings().removeClass('active');
break;
}
navItems.removeClass('active');
}
if( scrollY > pointOfAttachment )
$el.addClass('fixed');
else
$el.removeClass('fixed');
}
Why is this optimal?
The key for good performance is to do as minimal as possible to achieve your goal, and minimal here means accessing the DOM as little as possible and changing it even less times than accessing it. This is HIGHLY optimal code which ONLY changes the DOM when a change is required and never in any other situation.
You shouldn't need to do this on each scroll event. You could throttle the event and only run the callback something like every 20ms. The user shouldn't notice. You can do this with underscore, or write your own solution.
Another thing that would ease the lagg is to move as much out of the scroll event callback as possible. You don't need to query $('body') all the time for example, save that to a variable.
Hello Stackoverflow bootstrappers!
I don't see that this question has been asked before, and I am really interested to see the outcome.
How to duplicate the bug:
Open the page: (my current url testing this bug) http://dnwebdev.com/dev/
Resize the page down to a tablet
Use the navbar
(notice that the url has changed to include #section) this only occurs if you resize the browser. This causes the spying/scrolling to be off.
NOTE: if you open it on a mobile device the problem does not occur so a client won't face it, it was just bugging me.
Thank you, looking forward to your responses.
Edit: When clicking on the title brand the url adds #section-1 without the need to resize, which is also throwing me off. At this point I am thinking it is a bootstrap thing.
The only Javascript I have on my page is the following:
function close_toggle()
{
if ($(window).width() <= 768)
{
$('.nav a').on('click', function() {
$(".navbar-toggle").click();
});
}
else
{
$('.nav a').off('click');
}
}
close_toggle();
$(window).resize(close_toggle);
The code above closes the toggle after a selection is made in mobile.
if ($(window).width() <= 768)
{
var offset = 75;
}
else
{
var offset = 90;
}
$('.navbar li a').click(function(event) {
event.preventDefault();
$($(this).attr('href'))[0].scrollIntoView();
scrollBy(0, -offset);
});
The code above (based on screensize) will offset the scrollspy
Edit #2
The only reason I need any offset is due to fixed-top which causes scrollspy to freak out.
Help is much appreciated.
Fixed-top seems to carry the bug with scroll spy leaving me no choice but to use javascript.
To handle navigation correct highlighting, you have to consider, that all the calculations made by scrollSpy are being performed when scrollTop value is equal to zero.
So the solution looks like this:
var refreshScrollSpy = function (element, navElement, offset) {
// cache current scroll position to come back after refreshing
var cacheScrolltop = $(element).scrollTop();
$(element)
.scrollTop(0)
.scrollspy(‘refresh’)
.scrollTop(cacheScrolltop);
};
I have no idea how I should even call this problem … the title of this question doesn't make any sense at all, I know!
Following case: I have a single-page layout where users scroll downwards. I have sections .layer which, when inside the viewport should change the hash in the addressbar to its id. So e.g. the .layer#one is inside the viewport the url in the addressbar looks like this www.whatever.com/#!/one
$(window).scroll(function() {
hash = $('.layer:in-viewport').attr('id');
top.location.hash = "!/" + hash;
});
This works just fine and is exactly like I want it. The reason I have this syntax with the !/ is that if I would simply set the location to hash only the scroll-behaviour would be buggy because the browser tries to stick to the hash position.
The problem is now, that I want to be able to make browser history-back button working!
This would normally be rather simple with the hashchange function that comes with jQuery like so…
$(window).bind( 'hashchange', function( event ) {
//query the hash in the addressbar and jump to its position on the site
});
The only problem I have with this is that the hashchange function would also be triggered if the hash is changed while scrolling. So it would again jump or stick to the current position in the browser. Any idea how I could solve this? I could probably unbind the hashchange while scrolling, right? But is this the best solution?
Sure, you could just unbind and rebind whenever the hash changes on scroll. For example:
var old_hash;
var scroller = function() {
hash = $('.layer:in-viewport').attr('id');
if ( old_hash != hash ) {
$(window).off('hashchange', GoToHash); // using jQuery 1.7+ - change to unbind for < 1.7
top.location.hash = "!/" + hash;
setTimeout(function() { // ensures this happens in the next event loop
$(window).on('hashchange', GoToHash);
}, 0);
old_hash = hash;
}
}
var GoToHash = function() {
//query the hash in the addressbar and jump to its position on the site
}
$(window).scroll(scroller);