1. #1
    Sencha User digerata's Avatar
    Join Date
    Mar 2007
    Location
    Clarkston, Michigan
    Posts
    61
    Vote Rating
    0
    digerata is on a distinguished road

      0  

    Default [2.??] Document scrolling doesn't work in standards mode

    [2.??] Document scrolling doesn't work in standards mode


    I'm grappling with a problem where I can't scroll the document body if the document is in standards mode. I have an example:

    HTML Code:
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
    	"http://www.w3.org/TR/html4/loose.dtd">
    
    <html>
    <head>
    	<meta http-equiv="Content-type" content="text/html; charset=utf-8" />
    	<title>scrolling test</title>
    	
    	<style>
    	body {
    		background-color: white;
    	}
    	.section {
    		padding-bottom: 25px;
    		margin-bottom: 25px;
    		position: relative;
    		background-color: #ccc;
    		display: block;
    		height: 445px;
    	}
    	</style>
    	<link rel="stylesheet" href="scripts/extjs/resources/css/core.css" />
    </head>
    <body>
    	
    <div id="section1" class="section">
    	<a href="javascript:scroll(null, 'section1');">Scroll by Body</a>
    		<a href="javascript:scroll('section1', 'section1');">Scroll by Div</a>
    	<p>Testing 1</p>
    	<p>document.compatMode is <code id="writeroot">not supported</code>.</p>
    </div>
    
    <div id="section2" class="section">
    	<a href="javascript:scroll(null, 'section2');">Scroll by Body</a>
    		<a href="javascript:scroll('section2', 'section2');">Scroll by Div</a>
    	<p>Testing 2</p>
    </div>
    
    <div id="section3" class="section">
    	<a href="javascript:scroll(null, 'section3');">Scroll by Body</a>
    		<a href="javascript:scroll('section3', 'section3');">Scroll by Div</a>
    	<p>Testing 3</p>
    </div>
    
    
    
    <!-- <script type="text/javascript" src="scripts/yui/build/yahoo-dom-event/yahoo-dom-event.js"></script> -->
    <!-- <script type="text/javascript" src="scripts/yui/build/animation/animation-min.js"></script> -->
    <!-- <script type="text/javascript" src="scripts/extjs/adapter/yui/yui-utilities.js"></script> -->
    <!-- <script type="text/javascript" src="scripts/extjs/adapter/yui/ext-yui-adapter.js"></script> -->
    <script type="text/javascript" src="scripts/extjs/adapter/ext/ext-base.js"></script>
    <script type="text/javascript" src="scripts/extjs/ext-all-debug.js"></script>
    <script type="text/javascript">
    function scroll(whatId, toId) {
    	var top = Ext.get(toId).getTop();
    
    	if(whatId) {
    		console.log("Scrolling " + whatId + " to: " + top);
    		Ext.get(whatId).scrollTo("top", top, true);
    	} else {
    		console.log("Scrolling body to: " + top);
    		Ext.getBody().scrollTo("top", top, true);
    	}	
    }
    
    function init() {
    	if (document.compatMode)
    		document.getElementById('writeroot').innerHTML = document.compatMode;
    }
    </script>
    
    <script type="text/javascript">
    Ext.onReady(init, null);
    </script>	
    </body>
    </html>
    (I'm sorry, you'll have to fix the script and css include to your specific local folders)

    This example works in Safari 3 and 4 regardless of standards or quirks mode. In IE 7 and Firefox 3 (Mac and Win), the scrolling doesn't work. If I remove the doctype to switch to quirks mode, scrolling works. I switched the code to use the ext adapter to see if it was YUI causing it, but saw the same results.

    I'm using Ext JS 2.2

    Any ideas?

    Thanks!

    -Mike
    Last edited by digerata; 30 Mar 2009 at 9:49 AM. Reason: Add Ext JS version

  2. #2
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,509
    Vote Rating
    374
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    Quirks is best for Ext anyway - I'd remove the doctype.
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM


  3. #3
    Sencha User digerata's Avatar
    Join Date
    Mar 2007
    Location
    Clarkston, Michigan
    Posts
    61
    Vote Rating
    0
    digerata is on a distinguished road

      0  

    Default


    Thank's for the input, Jozef. But removing the doctype isn't really an option for us. There has got to be something else??

  4. #4
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,509
    Vote Rating
    374
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    Well, if you are going to seriously use Ext and if you want least possible problems in IE then removing the doctype is the best solution - search forums there are tons of discussions on the matter.

    If you really have to keep doctype, then try to play with css: position: static would be the first place I'd touch. Also, there are Ext.Element scroll routines, what about using them? http://extjs.com/deploy/dev/docs/?class=Ext.Element
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM


  5. #5
    Sencha User digerata's Avatar
    Join Date
    Mar 2007
    Location
    Clarkston, Michigan
    Posts
    61
    Vote Rating
    0
    digerata is on a distinguished road

      0  

    Default


    I've been using Ext seriously since it was yui-ext and I've been able to skirt around any issues like this, I believe, because we have avoided use of the panels and window in favor of custom UI. All of our production sites using Ext specify doctypes. Without reading the search results on this topic (I will for sure, thx), I do get the general consensus from much of the web world that doctype is a good thing and its use is imperative for future proofing websites. I know it is invaluable for our cross browser development thus far. What I have read on searching quirks mode in the forums so far was all related to Ext GWT.

    In this case, it appears that the real way to scroll a page in strict mode is to use:

    Code:
    // WORKS in all strict mode browsers!
    window.scrollTo(0, top);
    I dug into the source of jquery to find out how they do it. Their scrollTo method checks to see if the element being scrolled is the body and then use window.scrollTo if so.

    Interesting to note, this method works in both quirks and strict in IE7, FF3 Win/Mac, Safari 3/4. It seems like it would be possible to change Element's scrollTo() behavior to match.

    However, I'm not sure how to wrap that into an animation since window is not an Ext Element.

  6. #6
    Sencha User digerata's Avatar
    Join Date
    Mar 2007
    Location
    Clarkston, Michigan
    Posts
    61
    Vote Rating
    0
    digerata is on a distinguished road

      0  

    Default


    I forgot to reply to your question on Element.scroll. Both scroll, scrollTo, and scrollIntoView fail in strict mode, as well.

  7. #7
    Sencha User digerata's Avatar
    Join Date
    Mar 2007
    Location
    Clarkston, Michigan
    Posts
    61
    Vote Rating
    0
    digerata is on a distinguished road

      0  

    Default


    For anyone else who hits this wall, here is some code that will get around it. (I'm not proud of it. It is quick and dirty. I have little knowledge of the inner workings of animation, so no warranty here.)

    Oh, and this is only if you are using YUI. For the other adapters, you could probably look at the source and copy this.

    Add the following block as its own js file that is included into your code.

    Code:
    (function() {
    /**
     * Anim subclass for scrolling the window to a position defined by the "scroll"
     * member of "attributes".  All "scroll" members are arrays with x, y scroll positions.
     * <p>Usage: <code>var myAnim = new YAHOO.util.Scroll(el, { scroll: { to: [0, 800] } }, 1, YAHOO.util.Easing.easeOut);</code></p>
     * @class Scroll
     * @namespace YAHOO.util
     * @requires YAHOO.util.Anim
     * @requires YAHOO.util.AnimMgr
     * @requires YAHOO.util.Easing
     * @requires YAHOO.util.Bezier
     * @requires YAHOO.util.Dom
     * @requires YAHOO.util.Event
     * @requires YAHOO.util.CustomEvent 
     * @extends YAHOO.util.ColorAnim
     * @constructor
     * @param {String or HTMLElement} el Reference to the element that will be animated (DISREGARDED for WindowScroll)
     * @param {Object} attributes The attribute(s) to be animated.  
     * Each attribute is an object with at minimum a "to" or "by" member defined.  
     * Additional optional members are "from" (defaults to current value), "units" (defaults to "px").  
     * All attribute names use camelCase.
     * @param {Number} duration (optional, defaults to 1 second) Length of animation (frames or seconds), defaults to time-based
     * @param {Function} method (optional, defaults to YAHOO.util.Easing.easeNone) Computes the values that are applied to the attributes per frame (generally a YAHOO.util.Easing method)
     */
    var WindowScroll = function(el, attributes, duration,  method) {
        if (el) { // dont break existing subclasses not using YAHOO.extend
            WindowScroll.superclass.constructor.call(this, el, attributes, duration, method);
        }
    };
    
    WindowScroll.NAME = 'WindowScroll';
    
    // shorthand
    var Y = YAHOO.util;
    YAHOO.extend(WindowScroll, Y.Scroll);
    
    var superclass = WindowScroll.superclass;
    var proto = WindowScroll.prototype;
    
    proto.doMethod = function(attr, start, end) {
           var val = null;
       
           if (attr == 'scroll') {
               val = [
                   this.method(this.currentFrame, start[0], end[0] - start[0], this.totalFrames),
                   this.method(this.currentFrame, start[1], end[1] - start[1], this.totalFrames)
               ];
               
           } else {
               val = superclass.doMethod.call(this, attr, start, end);
           }
           return val;
    };
    
    proto.getAttribute = function(attr) {
           var val = null;
           
           if (attr == 'scroll') {
               val = [ 
    				(document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft),
    				(document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) 
    			];
           } else {
               val = superclass.getAttribute.call(this, attr);
           }
           
           return val;
       };
    
    proto.setAttribute = function(attr, val, unit) {
           var el = this.getEl();
           
           if (attr == 'scroll') {
    		window.scrollTo(val[0], val[1]);
           } else {
               superclass.setAttribute.call(this, attr, val, unit);
           }
       };
    
    	Ext.apply(Ext.lib.Anim, { scrollWindow: function(el, args, duration, easing, cb, scope){
    			console.log("running!");
    	        if(typeof easing == "string"){
    	            easing = YAHOO.util.Easing[easing];
    	        }
    			var anim = new WindowScroll(el, args, duration, easing);
    	        anim.animateX(function(){
    	            Ext.callback(cb, scope);
    	        });
    	        return anim;
    		}
    	});
    })();
    You can then turn around and animate the page scrolling using:

    Code:
    Ext.getBody().animate({scroll: { to: [0, top] }}, .5, null, 'easeOut', "scrollWindow");
    I tested this as working under strict mode with the latest Opera, IE7, FF3 Mac/Win, Safari 3/4.

    Thanks again for your help Jozef.

    -Mike

  8. #8
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,509
    Vote Rating
    374
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    One thought still rounds about in my head because I just cannot believe that such thing like scrolling wouldn't be handled in the core Ext.

    It looks you're using Ext with yui and maybe also another 3rd party libraries. I know that you have a good reason for doing so but I'd like tho know if the problem is there if you use pure Ext, with ext adapter, with no 3rd parties and not using any direct DOM functions. I mean, to scroll: Ext.get('element-id').scroll(..arguments...)
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM


  9. #9
    Sencha User digerata's Avatar
    Join Date
    Mar 2007
    Location
    Clarkston, Michigan
    Posts
    61
    Vote Rating
    0
    digerata is on a distinguished road

      0  

    Default


    Quote Originally Posted by jsakalos View Post
    One thought still rounds about in my head because I just cannot believe that such thing like scrolling wouldn't be handled in the core Ext.
    You and me both!

    Quote Originally Posted by jsakalos View Post
    It looks you're using Ext with yui and maybe also another 3rd party libraries. I know that you have a good reason for doing so but I'd like tho know if the problem is there if you use pure Ext, with ext adapter, with no 3rd parties and not using any direct DOM functions. I mean, to scroll: Ext.get('element-id').scroll(..arguments...)
    The example I posted is actually using the base ext adapter with the YUI stuff commented out. That was my second or so thought, as well. Straight Ext does not work either.

    The answer to your question is Ext.get('element-id').scroll(..arguments...) does work. But only for elements whose parent is a scrollable div. If the element does not have a scrollable parent div, it does not work. (Even when the page is indeed overflowing and should scroll)

    Testing straight dom manipulation and looking at what jquery does; it looks like, in strict mode, the *only* way to scroll the page is to use window.scrollTo().

  10. #10
    Sencha - Community Support Team jsakalos's Avatar
    Join Date
    Apr 2007
    Location
    Slovakia
    Posts
    27,509
    Vote Rating
    374
    jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future jsakalos has a brilliant future

      0  

    Default


    Well, then it sounds like a bug. Maybe it would be worth to prepare a showcase and post it to Bugs forum. Or should I move this thread to Bugs?
    Jozef Sakalos, aka Saki

    Education, extensions and services for developers at new http://extjs.eu
    News: Grid Search Plugin, ExtJS 5 Complex Data Binding using MVVM