1. #1
    Ext User
    Join Date
    Mar 2007
    Posts
    12
    Vote Rating
    0
    rexxe is on a distinguished road

      0  

    Default Element.getCenterXY() doesn't take scrollX or Y into account

    Element.getCenterXY() doesn't take scrollX or Y into account


    In the code for YAHOO.ext.Element.getCenterXY(), it never takes the scrollX or Y into account. I have a use case where I want to move an object to the center of the page anytime the user scrolls. Using getCenterXY() only yields the center of the object as if the user had never scrolled. For example, if the center is x 300, y 300, and then the user scrolls down where the center is now x 400 and y 400, getCenterXY() continues to yiled 300,300. The code below is what I've been using which works:

    Code:
    getCenterXY:function(){
         var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft;
         var scrollY = document.documentElement.scrollTop || document.body.scrollTop;
         var centerX=Math.round(((YAHOO.util.Dom.getViewportWidth()-this.getWidth())/2) + scrollX);
         var centerY=Math.round(((YAHOO.util.Dom.getViewportHeight()-this.getHeight())/2) + scrollY);
         
         return[centerX < 0 ? 0 : centerX,centerY < 0 ? 0 : centerY];
    }

  2. #2
    Sencha User jack.slocum's Avatar
    Join Date
    Mar 2007
    Location
    Tampa, FL
    Posts
    6,955
    Vote Rating
    16
    jack.slocum will become famous soon enough

      0  

    Default


    getCenterXY returns the center XY for the viewport, not the body. Unfortunately, I can't change that behavior because it could break existing code. I can however add an optional boolean param to include scroll in the calc...

    getCenterXY(true) would include scroll offsets. How does that sound?

    Jack

  3. #3
    Ext User
    Join Date
    Mar 2007
    Posts
    12
    Vote Rating
    0
    rexxe is on a distinguished road

      0  

    Default


    Sounds good. Keep up the excellent work. It's been a real time saver.....

  4. #4
    Sencha User jack.slocum's Avatar
    Join Date
    Mar 2007
    Location
    Tampa, FL
    Posts
    6,955
    Vote Rating
    16
    jack.slocum will become famous soon enough

      0  

    Default


    How's this look?
    Code:
    getCenterXY : function(offsetScroll){
            var centerX = Math.round((YAHOO.util.Dom.getViewportWidth()-this.getWidth())/2);
            var centerY = Math.round((YAHOO.util.Dom.getViewportHeight()-this.getHeight())/2);
            if(!offsetScroll){
                return [centerX, centerY];
            }else{
                var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft || 0;
                var scrollY = document.documentElement.scrollTop || document.body.scrollTop || 0;
                return[centerX + scrollX, centerY + scrollY];
            }
        }
    I took out the negative checks because negative coords are valid center XY values.

  5. #5
    Ext User
    Join Date
    Mar 2007
    Posts
    12
    Vote Rating
    0
    rexxe is on a distinguished road

      0  

    Default


    Your variable names are incorrect, you switch to scrollX and scrollY instead of scrollLeft and scrollTop. Also, in IE I get an Invalid Argument error, which obviously is not very informative in finding the problem

    Quote Originally Posted by jacksloc
    How's this look?
    Code:
    getCenterXY : function(offsetScroll){
            var centerX = Math.round((YAHOO.util.Dom.getViewportWidth()-this.getWidth())/2);
            var centerY = Math.round((YAHOO.util.Dom.getViewportHeight()-this.getHeight())/2);
            if(!offsetScroll){
                return [centerX, centerY];
            }else{
                var doc = document;
                var scrollTop = Math.max(doc.documentElement.scrollTop, doc.body.scrollTop);
                var scrollLeft = Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft);
                return[centerX + scrollX, centerY + scrollY];
            }
        }
    I took out the negative checks because negative coords are valid center XY values.

  6. #6
    Sencha User jack.slocum's Avatar
    Join Date
    Mar 2007
    Location
    Tampa, FL
    Posts
    6,955
    Vote Rating
    16
    jack.slocum will become famous soon enough

      0  

    Default


    I edited the post after I tested it and got the js error but not quick enough.

    Take a look again.

  7. #7
    Ext User
    Join Date
    Mar 2007
    Posts
    12
    Vote Rating
    0
    rexxe is on a distinguished road

      0  

    Default


    I still get an error in IE. It may be a problem with my code itself, so I'll research it. But there is still an issue. The getHeight and getWidth functions don't take into account elements that have a display of none. When display is none, width and height yield 0, so I have a function which temporarily changes the visibility and display to get the width and height. This is what I have, though it doesn't use your extension code yet since I'm just now migrating over to it:

    Code:
    getDimensions: function() {		
    		if ($D.getStyle(this.el, "display") != "none")
    	      return {width: this.el.offsetWidth, height: this.el.offsetHeight};
    	
    	   	// All *Width and *Height properties give 0 on elements with display none,
    		// so enable the element temporarily
    		var els = this.el.style;
    		var originalVisibility = els.visibility;
    		var originalPosition = els.position;
    		els.visibility = 'hidden';
    		els.position = 'absolute';
    		els.display = '';
    		var originalWidth = this.el.clientWidth;
    		var originalHeight = this.el.clientHeight;
    		els.display = 'none';
    		els.position = originalPosition;
    		els.visibility = originalVisibility;
    		return {width: originalWidth, height: originalHeight};
    	}

  8. #8
    Ext User
    Join Date
    Mar 2007
    Posts
    12
    Vote Rating
    0
    rexxe is on a distinguished road

      0  

    Default


    Fixed the invalid argument error. Was a problem with my code......

  9. #9
    Ext User
    Join Date
    Mar 2007
    Posts
    12
    Vote Rating
    0
    rexxe is on a distinguished road

      0  

    Default


    Nevermind on the height and width, it looks like it is working now.

    Thanks for your help.....

    Quote Originally Posted by rexxe
    I still get an error in IE. It may be a problem with my code itself, so I'll research it. But there is still an issue. The getHeight and getWidth functions don't take into account elements that have a display of none. When display is none, width and height yield 0, so I have a function which temporarily changes the visibility and display to get the width and height. This is what I have, though it doesn't use your extension code yet since I'm just now migrating over to it:

    Code:
    getDimensions: function() {		
    		if ($D.getStyle(this.el, "display") != "none")
    	      return {width: this.el.offsetWidth, height: this.el.offsetHeight};
    	
    	   	// All *Width and *Height properties give 0 on elements with display none,
    		// so enable the element temporarily
    		var els = this.el.style;
    		var originalVisibility = els.visibility;
    		var originalPosition = els.position;
    		els.visibility = 'hidden';
    		els.position = 'absolute';
    		els.display = '';
    		var originalWidth = this.el.clientWidth;
    		var originalHeight = this.el.clientHeight;
    		els.display = 'none';
    		els.position = originalPosition;
    		els.visibility = originalVisibility;
    		return {width: originalWidth, height: originalHeight};
    	}

  10. #10
    Sencha User jack.slocum's Avatar
    Join Date
    Mar 2007
    Location
    Tampa, FL
    Posts
    6,955
    Vote Rating
    16
    jack.slocum will become famous soon enough

      0  

    Default


    I thought you might be interested in these two functions which will be in the next release.
    Code:
    beginMeasure : function(){
            var p = this.dom;
            if(p.offsetWidth || p.offsetHeight){
                return; // offsets work already
            }
            var changed = [];
            var p = this.dom; // start with this element
            while(p && p.tagName.toLowerCase() != 'body'){
                if(YAHOO.util.Dom.getStyle(p, 'display') == 'none'){
                    changed.push({el: p, visibility: YAHOO.util.Dom.getStyle(p, 'visibility')});
                    p.style.visibility = 'hidden';
                    p.style.display = 'block';
                }
                p = p.parentNode;
            }
            this._measureChanged = changed;        
        },
        
        endMeasure : function(){
            var changed = this._measureChanged;
            if(changed){
                for(var i = 0, len = changed.length; i < len; i++) {
                	var r = changed[i];
                	r.el.style.visibility = r.visibility;
                    r.el.style.display = 'none';
                }
                this._measureChanged = null;
            }
        },
    Calling beginMeasure() ensures any offset calculations will work.

    Calling endMeasure() restores the parentNodes' states.

Similar Threads

  1. Replies: 15
    Last Post: 13 Jul 2007, 4:19 AM

Thread Participants: 2