Page 1 of 3 123 LastLast
Results 1 to 10 of 23

Thread: Changing layer placement through Javascript

  1. #1
    Join Date
    Jul 2005
    Posts
    36
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default Changing layer placement through Javascript

    Crazy idea, but hopefully there is a way to do this. As you know, here is the basic layer code

    Code:
    <div id="layer1" style="position:absolute; width:0px; height:0px; z-index:1; left:116px; top:0px;">
    Now, here is where my questions comes. Is it possible for the "left" attribute to be altered by a javascript? This way all the layers in that particular page will be shifted to the left accordingly.

    So, here is an example of how this javascript would be set up

    if user's screen resolution is 800 X 600 then subtract X pixels from the "left" attribute in all layers
    if user's screen resolution is 1024 X 764 then add 0 pixels to all "left" attribute in all layers
    If user's screen resolution is 1280 X 1024 then add X more pixels to the "left" attribute in all layers

    and so on...

    I have tried doing relative positioning instead of absolute positioning but once you start to add more and more layers and lay them up to of each other with different Z index values, you run into some problems (well thats on my end since I don't know how to do it right). This way every layer has an "absolute" positioning, yet the left attribute will vary depending on the screen resolution.
    Last edited by EliteSeraphim; 07-24-2005 at 07:34 AM.

  2. #2
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    It is better to design your page so that such shenanigans are not required. However, if you must resort to this sort of thing, it can be done but, be aware that users without javascript enabled or with some of its functions disabled will see some pretty odd sights. Basically what you want to do is collect all the divisions with the word 'layer' in their id attribute and then adjust them as desired with respect to their left style property all based upon the screen width. Let's start with the last thing (the screen width), then collect the layers and finally add the adjustment already calculated for them:
    Code:
    <script type="text/javascript">
    function leftAdjLayers(){
    var layers, leftAdj=0;
    if (screen.width==800)
    leftAdj-=12 //set to amount to subtract for 800x600
    if (screen.width==1024)
    leftAdj=0  // no change for your screen resolution that you designed the page for
    if (screen.width==1280)
    leftAdj+=22 //set to amount to add for 1280x1024
    layers=document.getElementsByTagName('div')
    for (i = 0; i < layers.length; i++)
    if (layers[i].id.indexOf('layer')!==-1)
    layers[i].style.left=parseInt(layers[i].style.left)+leftAdj+'px'
    }
    window.onload=leftAdjLayers:
    </script>
    You can add other screen widths as you see fit, don't forget 1152! Oh, and don't forget that there is never any guarantee that folks will be viewing your page fullscreen, especially at those higher resolutions!
    Last edited by jscheuer1; 07-24-2005 at 12:08 PM.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  3. #3
    Join Date
    Jul 2005
    Posts
    36
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    So all I need is to implement this code and then add the word "layer" to all of the div ID's I want changed?

    and yeah, the site I am working with has alot of intricatate layers and whatnot so I thought this would be a good idea to go ahead and fix that problem until the future when we get a hold of a more skilled programmer that can code the entire site using realitve positioning. For now, I think this will work great. This is really not a big deal, it just that the right now, the site ish pushed to the left a bit on higher resolutions instead of being centered like it is on 1024 X 768. Now, here is a question regarding what you said. Is there a way to only enable this script to take effect if and only if the users browsing the site has the required Javascript functions? If not, I'd much rather have the site slightly pushed to the left instead of having them see a bunch of strange things.

    EDIT: You know what, I think I might be making this too hard and much more complicated that what it could be. Is there a way to set this script so it works similar to a ratio? something like this:

    For every 1 more pixel the screen width is greater than 1024, then move all layers to the left 1 pixel.

    That way everything would align itself proportionally without having to worry about finding the specific values and entering them into the code above. This way it is much easier to manipulate and more practical. What do you think? possible?
    Last edited by EliteSeraphim; 07-24-2005 at 04:50 PM.

  4. #4
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Well, the script will not have any effect for browsers not using javascript. I said that could make for some pretty odd sights, in that if you are relying upon the script to get your layout right and using z-index for some of the layers, as indicated in your snippet of an example layer, things could get weird looking, yes. Even more so if a browser has only partial support of javascript, as is possible with Mozilla and even IE depending upon user configuration. Your idea of using a ratio is interesting but, wouldn't the ratio be more like half a pixel for every one? Say you get a window width 10px wider than 1024, wouldn't 5px be how far to the right you would want to move things to remain relative to center? That can be done, approximately, using window.innerWidth and document.body.clientWidth for Mozilla and IE respectively, to detect the user's window width. I think I have those right, always have to check when writing code, to be sure. Still there is a problem. Once the page loads and everything is adjusted, more or less, to spec and Oh Oh! the user changes resolutions or, more likely, viewport (window) size. Then all your nice calculations are toast (apologies to cr3) and things may look worse than if you never bothered with them. Now the nitty gritty. If your page is not a medium to slow load to begin with and there are no form elements or anything else that can get messed up by reloading the page, you can reload on resize but, I only know how to do that for Mozilla and IE so, there is a good chance other browsers will not cooperate. If I get terribly bored I may write up a demo but, this seems unpromising to me.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  5. #5
    Join Date
    Jul 2005
    Posts
    36
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Like you said, how about making the script so it only does 1 calculation for every page load? so, lets say the page loads and adjustes itself to a 1280 X 1024 resolution, but then the user changes resolutions or resizes the window. When the changes occur, no further calculations will be made and the page will remain positioned like it was loaded. Then once the user clicks on a link to another page, another calculation will be made in order to re-center the page to the new specifications. As long as this works with the most popular browsers such as IE and Mozilla, I am good.

    Just so you get an idea of the page that I am working on, here is the link. It is, more or less, centered in 1024 X 768. Like I said though, I don't know how to do relative positioning very well, and since this design is somewhat complex, even more odds against me getting it working properly.

    http://www.projectcoe.com/pc/index.html

    If you can get a demo of that ratio script whenever you have time, I would really appreciate it. We are still discussing various aspects of the design so it will be a while before that we change from our current layout: http://www.projectcoe.com/PCMain.html Then, if you find the time to do this ratio script, we can easily implement it on all the pages.

    PS: What do you think of the layout? I am more of an artist than a programmer
    Last edited by EliteSeraphim; 07-25-2005 at 04:29 AM.

  6. #6
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    The Layout's good for that sort of thing. I really didn't look at the code very much but, from the way it looks visually, it should be able to be written so that it is centered at any resolution wide enough for it, left aligned for those that don't. I did write a script for what we were discussing but, it will render a part of the content off screen to the left if the window is too small. Other than that it works well. I'm looking into correcting for that and adding a 'memory' feature to readjust on resize without reload.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  7. #7
    Join Date
    Jul 2005
    Posts
    36
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    yeah, thats an even better solution. If the viewer's resolution is smaller than 1024 than 768, then it would be best to just align the site on the left. Also, I am not sure if you got to see the new layout since I capitalized one of the links above incorrectly. Here is the real link in case it didn't work for you when you tried it: http://www.projectcoe.com/pc/index.html

    Also, that memory feature is a much better suited idea as well since I don't think viewers will change resolutions very often.

  8. #8
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    Well, it is a beta version but, it tests out well on your index.html. It will degrade (not execute) in IE5Mac, probably throw errors in IE5PC. The memory resize only works in IE6 but degrades in others (except IE5PC). FF works except memory resize. Safari not tested and I have my doubts but, let's see if anyone reports anything. I started out thinking this would be a configurable script but, since Mozilla and IE see the DOM differently, the script has to configure itself based upon what it finds. Let me know about any bugs that may crop up. The script goes in the head, or is linked to the head:
    Code:
    <script type="text/javascript">
    
    /*Absolute Elements Left Adjust to Window Width
      © John Davenport Scheuer (jscheuer1) 2005
      as first published in Dynamic Drive Help Forums
      http://www.dynamicdrive.com/forums/
      Permission to use granted, this credit must remain */
    
    function iecompattest(){ // Credit: Dynamic Drive
    return (document.compatMode && document.compatMode.indexOf("CSS")!=-1)? document.documentElement : document.body
    }
    
    var layOrigNew=new Array();
    
    function leftAdjLayers(runKind){
    var agt=navigator.userAgent.toLowerCase();
    if(agt.indexOf('mac')!==-1&&agt.indexOf("msie")!==-1)
    return;
    var layers, wWidth, leftAdj=0, layersReAdj=0;
    wWidth=window.innerWidth? window.innerWidth : iecompattest().offsetWidth
    leftAdj=Math.floor((wWidth-1024)/2)
    layers=document.getElementsByTagName('*')
    
    if (runKind=='reDo'){
    if(window.opera||!document.all)
    return;
    for (i = 0; i < layers.length; i++){
    if (layOrigNew[i]==undefined)
    return;
    if (layers[i].style.position=='absolute'&&layOrigNew[i][0]!==' ')
    layers[i].style.left=layOrigNew[i][0]+'px'
    }
    }
    
    for (i = 0; i < layers.length; i++){
    layOrigNew[i]=[' ', ' ']
    if (layers[i].style.position=='absolute'){
    layOrigNew[i][0]=(parseInt(layers[i].style.left)==parseInt(layers[i].style.left)&&0<parseInt(layers[i].style.left))? parseInt(layers[i].style.left) : ' '
    layOrigNew[i][1]=(parseInt(layers[i].style.left)==parseInt(layers[i].style.left)&&0<parseInt(layers[i].style.left))? parseInt(layers[i].style.left)+leftAdj : ' '
    }
    }
    
    for (i = 0; i < layOrigNew.length; i++)
    if (layOrigNew[i][1]<0&&layOrigNew[i][1]!==' '){
    layersReAdj=Math.min(layOrigNew[i][1],layersReAdj)
    }
    
    if (layersReAdj<0){
    for (i = 0; i < layers.length; i++)
    layOrigNew[i][1]=(layOrigNew[i][1]!==' ')? layOrigNew[i][1]-layersReAdj : ' '
    }
    
    for (i = 0; i < layers.length; i++)
    if (layers[i].style.position=='absolute'&&layOrigNew[i][1]!==' ')
    layers[i].style.left=layOrigNew[i][1]+'px'
    }
    
    if ( typeof window.addEventListener != "undefined" )
        window.addEventListener( "load", leftAdjLayers, false );
    else if ( typeof window.attachEvent != "undefined" ) {
        window.attachEvent( "onload", leftAdjLayers );
    }
    else {
        if ( window.onload != null ) {
            var oldOnload = window.onload;
            window.onload = function ( e ) {
                oldOnload( e );
                leftAdjLayers();
            };
        }
        else
            window.onload = leftAdjLayers;
            }
    window.onresize=function(){
    leftAdjLayers('reDo');
    }
    </script>
    Added Later: Oddly enough IE5PC just ignores it!
    Last edited by jscheuer1; 07-25-2005 at 02:42 PM.
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

  9. #9
    Join Date
    Jul 2005
    Posts
    36
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Default

    Wow, beautiful! Amazing work with this, John, I trully appreciate it! I just tested it out on the index.html and yes, it works perfectly in both IE6 and Mozilla which is what the vast majority of our viewers are going to be using anyway. I also went through all the resolutions on my monitor and I don't see any bugs with any of them, so as far as I can see, no bugs on the javascript itself. With the two most popular browsers covered, I think that should do it. Of course, if you find a way to support other browsers, that would be great, if not, the defeault alignment off the left side will work out just fine.

    Again, numerous thanks for the code and I'll be sure to let you know if I find any errors.

    EDIT: Ok, nothing too difficult but is there a way to add an ignore function that tells the javascript to disregard certain layer id's when aligning the site? check out this page http://www.projectcoe.com/pc/games/h....html?var1=sc3 (this page does not contain the alignment script since I have yet to send it to our web manager)

    All of the text and images in that panel where the boxart is are made up relative layers (they are "relative" because they are inside the DD tab code and use the margins of the tabbed content as their reference instead of the user's window. The actual positioning in each of the layers is set to "absolute" though). When the javascript takes over, those layers are shifted to the left on higher resolutions. Would it possible to add to the javascript a place in which I can list all of the layer IDs to ignore? Because once the other layers are shifted through javascript, the relative ones will automatically adjust itself without further modification.
    Last edited by EliteSeraphim; 07-25-2005 at 06:24 PM.

  10. #10
    Join Date
    Mar 2005
    Location
    SE PA USA
    Posts
    30,495
    Thanks
    82
    Thanked 3,449 Times in 3,410 Posts
    Blog Entries
    12

    Default

    That is easy to do, done in fact. I am a little dubious as to its working in actual practice though. Test show it will exclude an id(s) entered in the array but, from some of my other tests (writing the script to begin with) I saw that Mozilla and IE6 saw things differently as far as which element had the absolute positioning property. The results were the same though, so it may only be internal differences. Here is the updated script, let me know if it acts as expected and don't forget to configure your id's!

    Code:
    <script type="text/javascript">
    
    /*Absolute Elements Left Adjust to Window Width
      with exclude Id's Array option
      © John Davenport Scheuer (jscheuer1) 2005
      as first published in Dynamic Drive Help Forums
      http://www.dynamicdrive.com/forums/
      Permission to use granted, this credit must remain */
      
    var excludeIds=new Array() // <<< Do not edit or remove this line
    /*Set Id's to be excluded, use as many as you need */
    excludeIds[0]='firstidtoexclude'
    excludeIds[1]='secondidtoexclude'
    excludeIds[2]='thirdidtoexclude'
    
    /////////////////////No Need to Edit Below/////////////////////
    
    function iecompattest(){ // Credit: Dynamic Drive
    return (document.compatMode && document.compatMode.indexOf("CSS")!=-1)? document.documentElement : document.body
    }
    
    function exIds(el){
    var idTest=1
    for (j = 0; j < excludeIds.length; j++)
    if (excludeIds[j]==el.id)
    idTest=0
    return idTest
    }
    
    var layOrigNew=new Array();
    
    function leftAdjLayers(runKind){
    var agt=navigator.userAgent.toLowerCase();
    if(agt.indexOf('mac')!==-1&&agt.indexOf("msie")!==-1)
    return;
    var layers, wWidth, leftAdj=0, layersReAdj=0;
    wWidth=window.innerWidth? window.innerWidth : iecompattest().offsetWidth
    leftAdj=Math.floor((wWidth-1024)/2)
    layers=document.getElementsByTagName('*')
    
    if (runKind=='reDo'){
    if(window.opera||!document.all)
    return;
    for (i = 0; i < layers.length; i++){
    if (layOrigNew[i]==undefined)
    return;
    if (layers[i].style.position=='absolute'&&layOrigNew[i][0]!==' ')
    layers[i].style.left=layOrigNew[i][0]+'px'
    }
    }
    
    for (i = 0; i < layers.length; i++){
    layOrigNew[i]=[' ', ' ']
    if (layers[i].style.position=='absolute'&&exIds(layers[i])){
    layOrigNew[i][0]=(parseInt(layers[i].style.left)==parseInt(layers[i].style.left)&&0<parseInt(layers[i].style.left))? parseInt(layers[i].style.left) : ' '
    layOrigNew[i][1]=(parseInt(layers[i].style.left)==parseInt(layers[i].style.left)&&0<parseInt(layers[i].style.left))? parseInt(layers[i].style.left)+leftAdj : ' '
    }
    }
    
    for (i = 0; i < layOrigNew.length; i++)
    if (layOrigNew[i][1]<0&&layOrigNew[i][1]!==' '){
    layersReAdj=Math.min(layOrigNew[i][1],layersReAdj)
    }
    
    if (layersReAdj<0){
    for (i = 0; i < layers.length; i++)
    layOrigNew[i][1]=(layOrigNew[i][1]!==' ')? layOrigNew[i][1]-layersReAdj : ' '
    }
    
    for (i = 0; i < layers.length; i++)
    if (layers[i].style.position=='absolute'&&layOrigNew[i][1]!==' ')
    layers[i].style.left=layOrigNew[i][1]+'px'
    }
    
    if ( typeof window.addEventListener != "undefined" )
        window.addEventListener( "load", leftAdjLayers, false );
    else if ( typeof window.attachEvent != "undefined" ) {
        window.attachEvent( "onload", leftAdjLayers );
    }
    else {
        if ( window.onload != null ) {
            var oldOnload = window.onload;
            window.onload = function ( e ) {
                oldOnload( e );
                leftAdjLayers();
            };
        }
        else
            window.onload = leftAdjLayers;
            }
    window.onresize=function(){
    leftAdjLayers('reDo');
    }
    </script>
    - John
    ________________________

    Show Additional Thanks: International Rescue Committee - Donate or: The Ocean Conservancy - Donate or: PayPal - Donate

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •