SitePoint Sponsor

User Tag List

Results 1 to 5 of 5
  1. #1
    SitePoint Member
    Join Date
    Dec 2011
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Positioning nested element in response to arrow key - Javascript/jQuery/CSS

    I'm relatively inexperienced with JavaScript and jQuery, but I've figured out how to cause a response to an arrow button press. However, I would like a nested element to change its position in response to the arrow button press. I've tried using
    Code:
    document.getElementById("item").style.left = 10px;
    - That causes the parent element to change its position to 10px left of the window. I'm using IE as the test browser.

    Eventually, the item will only go to the width of the parent tag. I know how to calculate that, but I first need to get the nested element to move, say 10px to the right whenever the right arrow key is pressed. Any help would be greatly appreciated.

    Here is my complete code:

    Code:
    <!DOCTYPE HTML>
    <html>
    	<head>
    		<title>Practice</title>
    		<style type="text/css">
    		.holder
    		{
    		  position: relative;
    		  top:100px;
    		  left:100px;
    		  border:2px solid;
    		  border-color:blue;
    		  width:200px;
    		  height:200px;
    		  z-index:1;
    		}
    
    		.base
    		{
    		  position: relative;
    		  top:190px;
    		  left:0px;
    		  background-color: black;
    		  width:50px;
    		  height:10px;
    		  z-index:2;
    		}
     		</style>
     		<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
     		<script type="text/javascript">
     			function goRight() {
     				var lzrItem = document.getElementById("base");
     				lzrItem.style.left = "10px";
     			}
     		</script>
     		<script>
    		    $(document).keydown(function(event) {
    		      switch (event.keyCode) {
    	            case 37:
    	            	alert('left');
    	            	break;
    		        case 38:
    		        	alert('up');
    		        	break;
    		        case 39:
    		        	x = $(".base").position();
    		        	alert(x.top);
    		        	alert(x.left);
    		        	alert('You pressed the right arrow');
    		        	goRight();
    		        	break;
    		        case 40:
    		        	alert('down');
    		        	break;
    		      }
    		    });
            </script>
    	</head>
    	<body>
    		<div class="holder" id="holder" >
    			<div class="base" id="base">
    			</div>
    		</div>
    	</body>
    </html>
    Thanks,
    Mike

  2. #2
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Hi Mike,

    Thanks for a well asked question

    It's always nice to get a good bit of source code posted to work with

    Since you're already using jQuery, let's continue with that approach.

    If you want to move an element, you can set it's CSS position using the jQuery .css() method. In this case, the "goRight()" function will be called everytime the keydown event ticks over.

    To move the element, we simply need to get its current left position and add 10 to it.
    Code javascript:
    function goRight() {
        $b = $("#base");
        $b.css("left", $b.position().left + 10);
    }

    You can write similar functions for the up, down and left directions (tip: when moving left, don't set the "right" css value, but decrease the left value by the desired amount)

    Now, as for the "bounding", keeping the "base" inside of the "holder":

    For the right bound you'll want to limit the maximum left value to the width of the box minus the width of the element that's moving.

    For the bottom bound you'll want to limit the maximum top value to the height of the box minus the height of the element that's moving.

    For the left and top bounds, it the maximum value would be set to zero if they become negative.

    I modified your code and have a local working example of how the bounding could work, so if you get really stuck with it, let me know and I'll send you a jsFiddle
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  3. #3
    SitePoint Guru
    Join Date
    Sep 2006
    Posts
    731
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    To be able easily to read CSS properties of an element, they need to be applied inline.

    Here's a working example without jQuery.

    To simplify calculations, border width isn't considered.

    A function table is usually prefereable to switch-case.
    Code:
    <!DOCTYPE HTML>
    <html>
        <head>
            <title>Practice</title>
            <style type="text/css">
            .holder
            {
              position: relative;
              top:100px;
              left:100px;
              border:2px solid;
              border-color:blue;
              width:200px;
              height:200px;
              z-index:1;
            }
    
            .base
            {
              position: relative;
              top:190px;
              left:0px;
              background-color: black;
              width:50px;
              height:10px;
              z-index:2;
            }
            </style>
        </head>
        <body>
            <div class="holder" id="holder" >
                <div class="base" id="base" style='top:190px;left:0px'>
                </div>
            </div>
            <script type='text/javascript'>
    
                function moveDiv( elem, step )
                {
                  var funcs = [],
                      st = elem.style,
                      op = elem.parentNode,
                      hTravel = op.offsetWidth - elem.offsetWidth,
                      vTravel = op.offsetHeight - elem.offsetHeight;
    
                  funcs[ 'f37' ] = function(){ st.left = ( d = parseInt( st.left ) ) - Math.min( step, d ) + 'px'; }
                  funcs[ 'f39' ] = function(){ st.left = ( d = parseInt( st.left ) ) + Math.min( step, hTravel - d ) + 'px'; }
                  funcs[ 'f38' ] = function(){ st.top = ( d = parseInt( st.top ) ) - Math.min( step, d ) + 'px'; }
                  funcs[ 'f40' ] = function(){ st.top = ( d = parseInt( st.top ) ) + Math.min( step, vTravel - d ) + 'px'; }
    
                  return function( evt )
                  {
                    var e = evt || window.event,
                        key = e.keyCode || e.which,
                        fName = 'f' + key;
    
                    funcs[ fName ] ? funcs[ fName ]() : 0;
                  }
                }
    
                document.onkeydown = moveDiv( document.getElementById( 'base' ), 5 );
            </script>
        </body>
    </html>
    Tab-indentation is a crime against humanity.

  4. #4
    Under Construction silver trophybronze trophy AussieJohn's Avatar
    Join Date
    Sep 2005
    Location
    Sydney, Australia
    Posts
    776
    Mentioned
    11 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by Logic Ali View Post
    To be able easily to read CSS properties of an element, they need to be applied inline.
    Sad but true, which is why libraries are handy, they abstract this "inconvenience" away

    It's not *too* hard to implement something like this though. If you wanted to take a non-jquery approach you could roll-your-own "getStyle" method:

    Code javascript:
    var theElement = document.getElementById("base");
     
    function getStyle(el, prop){
        if (el.currentStyle) {
            return el.currentStyle[prop]
        }
        else if (window.getComputedStyle) {
            return window.getComputedStyle(el,null).getPropertyValue(prop);  
        }
        return false;
    }
     
     getTheStyle(theElement,"top");
    var details = {
    . . web: "afterlight.com.au",
    . . photos: "jvdl.id.au",
    . . psa: "usethelatestversion.com"
    }

  5. #5
    SitePoint Member
    Join Date
    Dec 2011
    Posts
    3
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Hi AussieJohn

    That worked thank you. I had finally figured out how to do make it work using basic JavaScript (primarily because I couldn't figure it out with jQuery). Your jQuery recommendation works well and is easier to read, so I'm using jQuery. I had tried to use jQuery initially, but I think I was mixing it with JavaScript. for example, I was trying to declare a basic JavaScript variable and then apply jQuery methods to it.

    Anyway, thanks again. You recommendation solved my problem.


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
  •