Advertisement
If you have a new account but are having problems posting or verifying your account, please email us on hello@boards.ie for help. Thanks :)
Hello all! Please ensure that you are posting a new thread or question in the appropriate forum. The Feedback forum is overwhelmed with questions that are having to be moved elsewhere. If you need help to verify your account contact hello@boards.ie

jQuery button not appearing with back button use

Options
  • 29-04-2011 2:19pm
    #1
    Registered Users Posts: 19,019 ✭✭✭✭


    Hi all,
    I'm currently working on a simple (ahem) button container that should stick to the bottom of the window (like .buttonContainer{position:fixed; bottom:0;)}) but it's for mobile devices, so after discovering (much to my surprise) that mobile safari browsers and (AFAIK most Android devices too) fail to support position:fixed I turned to a javascript solution using the jQuery mobile library to instantly hide the button div on 'touchstart' and then to show it at the bottom of the viewport window (by calculating the scrolled distance and, accounting for div height, repositioning the button div).

    This all works fine when I load the page from scratch or navigate to it from a main menu etc.

    My problem is that if at any time I use the browser back button, my button div completely fails to render. Has anyone any ideas?

    Snipped code below:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="pt" lang="pt">
    <head>
    ..head stuff..
    </head>
    <body>
    
    <div id="page-wrapper" data-role="page">
        ..page contents..	
    </div>
    <div id="permanent-checkout-button-wrapper">
    	<div id="permanent-checkout-button">
    		<a id="permanent-checkout-button-link" rel="nofollow" href="<?php echo $base . '/cart/'; ?>"><span id="permanent-checkout-button-link-text">Finalizar Compra</span></a>
    	</div>
    </div>
    <script type="text/javascript">
    	$( function() {
    		  $('#dafiti-page-wrapper').bind( 'touchstart', function( e ) {
    			   $("#permanent-checkout-button-wrapper").hide();
    		    } ); 
    	} );
    	function showNavBar() { 
    		var win_y = $(window).height(); 
    		var scroll_y = $(window).scrollTop(); 
    		$("#permanent-checkout-button-wrapper").fadeIn("slow");
    		$("#permanent-checkout-button-wrapper").css({ top: ((win_y - 42) + scroll_y) + "px" }); 
    	} 
    	$(document).ready(showNavBar);
        $(window).bind( "scroll", showNavBar );
    </script> 
    </body>
    </html>
    


Comments

  • Registered Users Posts: 11,979 ✭✭✭✭Giblet


    Another case of jQuery ruining someones day.
    <style>
    .content { overflow-y: scroll; width:100%;height:100%}
    .fixed { position:absolute;bottom:0; }
    </style>
    <div class="content">
    </div>
    <div class="fixed"></div>
    

    This works in ie6 as well.

    Also, touchstart wont let you scroll.
    You should bind to touchstart and touchfinish/touchend and have a semaphore on touchmove.

    jQuery mobile is also a bunch of crap, it's very slow and never bind anything to scroll if you don't need to.


  • Registered Users Posts: 19,019 ✭✭✭✭murphaph


    Hi Giblet,
    First off, thanks for the reply :)

    Ok, I'm not fully understanding it however. Do you mean that I should be able to implement this static div at the bottom of the browser window any javascript, using just the css you've supplied?

    (I presume not because I've tried it and I get a button that appears static on a mobile browser (using an iphone to test at the mo), ie, the button div scrolls with page contents-not what we want)

    I would however be delighted if I could make this blasted button without any javascript if that is indeed what you're suggesting.

    If you're saying that I still need javascript to implement a pseudo static div at the bottom of the window, could you please expand a bit on that? Cheers for the help...not my strong point all of this but the boss says I have to do it :pac:


  • Registered Users Posts: 11,979 ✭✭✭✭Giblet


    If you have this structure
    <body>
    <div class="content"></div>
    <div class="fixed"></div>
    </body>
    
    You can position the fixed div absolutely and it will appear "fixed" in that position.
    The other content goes in the content div, and that has an overflow property to allow it to scroll. You might need to have overflow:hidden on the body and a height/width 100%

    For example, I could set the height of the content div to 96% and the height of the fixed to 4% inside a body with a height of 100%.
    Which will give you something like a dock at the bottom of the screen, with the content div having the ability to scroll without affecting the fixed div.

    You do not need javascript for this.


  • Registered Users Posts: 19,019 ✭✭✭✭murphaph


    Thanks for that clarification. Will have to wait until Monday to try it out. I appreciate your time ;)


  • Registered Users Posts: 19,019 ✭✭✭✭murphaph


    Hmmm, still not working. This demo code (basically your suggestion) works fine in desktop browsers, content div has vertical scroll bar and looks fine. But as soon as I point an ipad (safari mobile) at it, it loses the vertical scroll bar and content cannot be scrolled. The "last" text is never visible.
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html> 
    <head> 
    
    <style>
    body {height:100%;overflow: hidden;margin:0; padding:0;}
    .content {position:absolute;overflow-y: scroll; width:100%;height:90%;background-color:#ff0000;}
    .fixed { position:absolute;bottom:0;background-color:#00ff00;height:10%;width:100%; }
    </style>  
    </head>
    
    <body> 
    <div class="content">content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />content <br />last</div>
    <div class="fixed">fixed</div>
    </body>
    </html>
    

    I have to say I'm stumped. This avoids the use of poistion:fixed, yet still doesn't work on mobile safari. Any ideas?

    Edit: It scrolls with 2 finger scrolling only. I would be worried that many users would miss most of the page contents using this in this form. If I google "mobile safari scroll-y etc." I find sites that maintain single finger iphone scrolling with fixed content is only possible using a javascript implementation. Might be heading back to javascript by the looks of it....thoughts welcome!


  • Advertisement
  • Registered Users Posts: 11,979 ✭✭✭✭Giblet


    Well, it comes down to this.
    Do you want the scroll event of the body to reposition an element flush to the bottom, or do you want to handle the one finger scroll of the content?

    They both, as a solution, annoy the hell out of me. If you can live with the constant repositioning of a div, which will flicker a bit, then you can try reposition the footer div, and maybe add the fixed position support to css and test for it in javascript before you hook up the scroll event. Otherwise, you can hook up the touchmove event to perform the scroll action of the div. Two finger scrolling perform an onscroll event on the div. I find that testing and binding touchmove might make this more backward compatible, as without touch move, it still works in older browsers, even without javascript.


    Test for fixed position support.
    function () {
      var container = document.body;
      if (document.createElement &&
          container && container.appendChild && container.removeChild) {
          var el = document.createElement("div");
          if (!el.getBoundingClientRect) {
              return null;
          }
          el.innerHTML = "x";
          el.style.cssText = "position:fixed;top:100px;";
          container.appendChild(el);
          var originalHeight = container.style.height, originalScrollTop = container.scrollTop;
          container.style.height = "3000px";
          container.scrollTop = 500;
          var elementTop = el.getBoundingClientRect().top;
          container.style.height = originalHeight;
          var isSupported = elementTop === 100;
          container.removeChild(el);
          container.scrollTop = originalScrollTop;
          return isSupported;
      }
      return null;
    }
    


  • Registered Users Posts: 19,019 ✭✭✭✭murphaph


    Giblet wrote: »
    Well, it comes down to this.
    Do you want the scroll event of the body to reposition an element flush to the bottom, or do you want to handle the one finger scroll of the content?
    Personally I think this button is stupid but I don't get to decide to remove it unfortunately.

    This is what I've been told:

    The app must scroll with a single finger as the critical page is a list of catalogue items and if the page doesn't scroll, 90% of users will think there are only a few items on each page.

    The button wrapper must be present at the bottom of each page.

    So, in answer to your question, both!

    I get the feeling this is not possible without using something like the iscroll library that uses hardware acceleration to provide a pseudo fixed positio item. I've looked at the demo on an iphone and it doesn't flicker. I think I'll have to create an iphone specific set of views earlier than we wanted (we wanted to create a generic mobile layout that could be customised bit by bit for different devices).


  • Registered Users Posts: 11,979 ✭✭✭✭Giblet


    I had this exact problem with a client before too :)
    Try binding something like this in my example
    $('.content').bind('touchmove',function(event){
    $(this).scrollTop(e.touches[0].pageY).scrollLeft(e.touches[0].pageX); // This is prob not the property but should be similar
    });
    

    I haven't actually got any dev stuff here to test this though


Advertisement