JavaScript - Oop / Classes - Multi Instances Merged
Hi,
I have a question about an oop/class style form of javascript programming. I have stripped the code down to the basic minimum. The problem is I have created two instances of the same class and have entered data into those classes. But as you will see the two separate instances of the class appear to share the same data. How do I get my class structure working so separate instances will retain their separate data? Here is the code: Index.html Code: <html> <head> <meta http-equiv="Content-type" content="text/html; charset=utf-8"> <script type="text/javascript" src="test.js"></script> <script type="text/javascript"> debugger; // Do this because a page resart seems to keep old data function SetGlobals() { var ui; var el; // Arr00 ui = document.getElementById("Arr00"); el = arr0.arrayGet(0); ui.innerHTML = el.m_String; // Arr01 ui = document.getElementById("Arr01"); el = arr0.arrayGet(1); ui.innerHTML = el.m_String; // Arr10 ui = document.getElementById("Arr10"); el = arr1.arrayGet(0); ui.innerHTML = el.m_String; // Arr11 ui = document.getElementById("Arr11"); el = arr1.arrayGet(1); ui.innerHTML = el.m_String; } function MyOnLoad() { SetGlobals(); } </script> </head> <body onload="MyOnLoad()" style="width:100%; height: 100%; padding: 0 0 0 0; margin: 0 0 0 0; overflow: hidden; background:#000000"> <div id="divScreen" style="display: block; width:100%; height="100%"> <div id="divMenu" style='float: left; background:#00FF00; border-color: #000000; border-width: 1px;'> <table> <tr> <td> Array 0/String 0: <label id="Arr00"></label> </td> </tr> <tr> <td> Array 0/String 1: <label id="Arr01"></label> </td> </tr> <tr> <td> Array 1/String 0: <label id="Arr10"></label> </td> </tr> <tr> <td> Array 1/String 1: <label id="Arr11"></label> </td> </tr> </table> </div> <div id="divMain" style='height: 100%; background:#0000FF; margin-left: 250px; border-color: #000000; border-width: 1px;'> </div> </div> </body> </html> Test.js Code: var BaseARR = function() { _arr = []; // new Array(); // Public functions that can access private members this.Add = function(arg) { var i, addAt; if(arg==null || (addAt = FindEnterPos(arg))<0) return false; // since adding and not deleting anything, nothing of value will be returned _arr.splice(addAt, 0, arg); return true; }; // This finds the entry position for in FindEnterPos = function(arg) { return (_arr.length + 1); }; this.arrayGet = function(i) { return ((_arr != null && i >= 0 && i < _arr.length) ? _arr[i] : null); }; }; var stringId = function(id, str) { // public has a this. , privates have just var this.m_Id = id; // int this.m_String = str; // string }; // This so allow statics var stringIdARR = function() { BaseARR.call(this); }; Similar TutorialsI have a javascript countdown clock in my camping page on my website www.bsatroop459.org. It works on IE7 and IE8 but it will not work on Firefox. Could somebody give me a clue as why my countdown clock will not work in Firefox. The is a white box I can't seem to get rid of! <script language="JavaScript"> CountActive = true; DisplayFormat = "%%D%% Days, %%H%% Hours, %%M%% Minutes, and %%S%% Seconds"; </script><script language="JavaScript" type="text/javascript"> <!-- function calcage(secs, num1, num2) { s = ((Math.floor(secs/num1))%num2).toString(); if (s.length < 2) s = "0" + s; return s; } function CountBack(secs) { DisplayStr = DisplayFormat.replace(/%%D%%/g, calcage(secs,86400,100000)); DisplayStr = DisplayStr.replace(/%%H%%/g, calcage(secs,3600,24)); DisplayStr = DisplayStr.replace(/%%M%%/g, calcage(secs,60,60)); DisplayStr = DisplayStr.replace(/%%S%%/g, calcage(secs,1,60)); document.getElementById("cntdwn").innerHTML = DisplayStr; if (CountActive) setTimeout("CountBack(" + (secs-1) + ")", 990); } function putspan(backcolor, forecolor) { document.write("<span id='cntdwn' style='background-color:" + backcolor + "; color:" + forecolor + "'></span>"); } if (typeof(BackColor)=="undefined") BackColor = "white"; if (typeof(ForeColor)=="undefined") ForeColor= "black"; if (typeof(TargetDate)=="undefined") TargetDate = "6/13/2011 9:00 AM"; if (typeof(DisplayFormat)=="undefined") DisplayFormat = "%%D%% Days, %%H%% Hours, %%M%% Minutes, %%S%% Seconds."; if (typeof(CountActive)=="undefined") CountActive = true; putspan(BackColor, ForeColor); var dthen = new Date(TargetDate); var dnow = new Date(); ddiff = new Date(dthen-dnow); gsecs = Math.floor(ddiff.valueOf()/1000); CountBack(gsecs); //--> </script> <!-- comment out below for the clock --> <form name="clock_form"> <tr><td align="center" bgcolor="maroon"><font color="yellow" face="Arial, Helvetica, sans-serif"><b>Countdown to Bartle Summer Camp 2011</b> </font></td></tr> <tr> <td align="center"><input type="text" name="clock" size="60"></a></td></tr> </form> <!-- end of comment out area --> Thank you for your time. Mike I am using this script that gets messed up when you resize the window. I figured out that I could use this other script to do stuff just after the window gets resized. Code: (function($,sr){ // debouncing function from John Hann // http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/ var debounce = function (func, threshold, execAsap) { var timeout; return function debounced () { var obj = this, args = arguments; function delayed () { if (!execAsap) func.apply(obj, args); timeout = null; }; if (timeout) clearTimeout(timeout); else if (execAsap) func.apply(obj, args); timeout = setTimeout(delayed, threshold || 100); }; } // smartresize jQuery.fn[sr] = function(fn){ return fn ? this.bind('resize', debounce(fn)) : this.trigger(sr); }; })(jQuery,'smartresize'); // usage: $(window).smartresize(function(){ // code that takes it easy... }); So I re-instantiate the misbehaving script in there so it fires whenever the window is resized (I changed it to 500 so it really only fires once after you are done resizing). This fixes it. The new instance doesn't have a problem but the old instance is still there and messed up. so I use. $($.misbehaving-script).remove(); just before instantiating after window resize, which gets rid of broken instance. Problem solved.. Except that messes up a different script! It's driving me crazy. Any advice would of course be very welcome. I'm trying to find a script that will replace all instances of HTML code within a page. I saw the Javascript replace method. How can I leverage this on my page to replace every instance of a certain piece of code? Pretend this is a <div> in my page: <div style="width:340px;">Try this code out.</div> How could I convert all instances of this code to: <div style="width:340px;">Try this testing stuff.</div> Thanks for any help! Hi I need help with spawning in my game. I have this code: Code: function spawnEnemy() { var shapes = [LeftBlock, RightBlock, middleRightBlock, middleLeftBlock, middleBlock]; var shape = shapes[Math.floor(Math.random() * shapes.length)]; var RandomBlock = new THREE.Object3D(); RandomBlock.add(shape); blocks.push(RandomBlock); for (var i = 0; i < blocks.length; i++) { RandomBlock = blocks[i]; scene.add(RandomBlock); hit = false; } } function startSpawningEnemies() { repeater = setInterval(function() { spawnEnemy(); newBlock = false; }, 1000); } Basically it chooses a random object in the array 'shapes' and it adds the shape to the scene every second. But the problem is that when I have, for example a 'Leftblock' on screen and it randomly gets called again, Leftblock will get reset to the starting position, so basically I cant have 2 of the same type of block on screen at once. So I want want every block in the array to be an entirely new instance of a block, rather than the same. Here is a code pen so you can see what is happening My Codepen Thanks in advance Reply With Quote 01-31-2015, 12:06 PM #2 Lesshardtofind View Profile View Forum Posts Visit Homepage New Coder Join Date Sep 2013 Location Houston Posts 20 Thanks 0 Thanked 4 Times in 4 Posts Hey I apologize in advance this will probably be a long post, but to get to the root of your problem it takes a bit of explaining to show how I fixed it. If you don't want to read about all the changes and why I did them if you scroll to the bottom of this post the last code snippet is the new working code. Firstly I'd like to make a few comments. 1. Try to avoid using so many globals that is what is confusing the whole thing. 2. Even though JavaScript isn't a classical language. Using some OOP approaches can simplify your code quite a bit. Now to what your actual problem was. You only had one instance of meshes for each type of block/paddle or whatever you call it. Even though you created new 3d objects you still were just passing it the values of the current existing Meshes. In order to get around this I simplified your code a lot. I removed around 200 lines of code and created a few objects to make things easier. I don't know that I can explain every single thing I did, but creating objects is very useful for instance instead of making a ton of variables for each box you can make an Object called Box and then create a new instance of it. Since your Box also needs a mesh you can create that inside of the box as well. Code: function Box(w, h, d, q, m){ var CoreInfo = { width: w, height: h, depth: d, quality: q, material: m }; var Mesh = GetNewMesh(CoreInfo); this.setMeshY = function(y){ Mesh.position.y = y; } this.setMeshX = function(x){ Mesh.position.x = x; } this.getCoreInfo = function(key){ return CoreInfo[key]; } this.setCoreInfo = function(key, val){ CoreInfo[key] = val; } this.getAllInfo = function(){ return CoreInfo; } this.getMesh = function(){ return Mesh; } this.setShadows = function(r, c){ Mesh.receiveShadow = r; Mesh.castShadow = c; } } // you will notice that it calls this to get a MESH instead of using 5+ serperate calls you can now wrap it into a function that takes an assoc array. function GetNewMesh(info){ var Q = info["qaulity"]; return new THREE.Mesh( new THREE.BoxGeometry( info["width"], info["height"], info["depth"], Q, Q, Q), info["material"]); } With this object you can create new instances of boxes just by passing all the variables it needs and save it into a new object. example use: Code: var BlockMat = new THREE.MeshLambertMaterial({color: 0x3c00ff}); var Abox = new Box(10, 160, 10, 1, BlockMat); As you can see the Box requires 5 arguments to construct. They are width, height, depth, quality, and material; You will also notice there are functions inside of the Box to call functionality they are setMeshY(y): This sets the Y position of the mesh as the y value passed to it; setMeshX(x): This sets the X position of the mesh as the x value passed to it; getCoreInfo(key): This gets some CoreInfo based on a string or "key" that you pass it. EX use Box.getCoreInfo("width"); setCoreInfo(key, value): This sets some CoreInfo based on a string or "key" that you pass it. EX use Box.setCoreInfo("width", 100); getAllInfo(): Returns ALL CoreInfo in an assoc array that is accessed by a "key." EX use var AllInfo = Box.getAllInfo(); AllInfo["width"]; getMesh: Returns The mesh object setShadows: Allows you to set shadows by passing true or false for the receive and cast arguments. Now some of your enemy boxes needed two boxes so I further created a object called Double Box; These are very much the same as a box. Just all methods need to be passed an index as well. These are identical to your original objects as Paddle1 is now at index 0, and Paddle2 is at index1 for each respective object. With those objects created we can Delete a TON of your global variables and clean some stuff up. As a matter of fact the more I looked at it you didn't even NEED globals for your set enemy paddle types at all. I was able to wrap them all up into a function that will return an object like you wanted by being passed a string. Code: function GetBlock(type){ if(type == "m"){ var temp = new DoubleBox(10, 75, 10, 1, BlockMat, 10, 75, 10, 1, BlockMat); var obj = new THREE.Object3D(); obj.add(temp.getMesh(0)); obj.add(temp.getMesh(1)) temp.setMeshX(0, fieldWidth/2); temp.setMeshY(0, -60); temp.setMeshX(1, fieldWidth/2); temp.setMeshY(1, 60); return obj; } else if(type == "mr"){ var temp = new DoubleBox(10, 30, 10, 1,BlockMat, 10, 110, 10, 1,BlockMat); var obj = new THREE.Object3D(); obj.add(temp.getMesh(0)); obj.add(temp.getMesh(1)); temp.setMeshX(0, fieldWidth/2); temp.setMeshY(0, -80); temp.setMeshX(1, fieldWidth/2); temp.setMeshY(1, 40); return obj; } else if(type == "ml"){ var temp = new DoubleBox(10, 30, 10, 1, BlockMat, 10, 110, 10, 1, BlockMat); var obj = new THREE.Object3D(); obj.add(temp.getMesh(0)); obj.add(temp.getMesh(1)); temp.setMeshX(0, fieldWidth/2); temp.setMeshY(0, 80); temp.setMeshX(1, fieldWidth/2); temp.setMeshY(1, -40); return obj; } else if(type == "l"){ var temp = new Box(10, 160, 10, 1, BlockMat); var obj = new THREE.Object3D(); obj.add(temp.getMesh()); temp.setMeshX(fieldWidth/2); temp.setMeshY(20); return obj; } else if(type == "r"){ var temp = new Box(10, 160, 10, 1, BlockMat); var obj = new THREE.Object3D(); obj.add(temp.getMesh()); temp.setMeshX(fieldWidth/2); temp.setMeshY(-20); return obj; } } While this could be cleaned up and do some extra error checking it now does EXACTLY what you need it to. You can call this function and pass it a string for each type of block you want. It will return a NEW instance of that type of block without sharing meshes as you had previously programmed it to. now you can call this function in the spawn enemy function Code: function spawnEnemy() //total enemies starts at 0 and every-time you add to array { var shapes = ["l", "r", "mr", "ml", "m"]; // these are the strings that pass to the GetBlock(type) function as type var shape = shapes[Math.floor(Math.random() * shapes.length)]; blocks.push(new THREE.Object3D().add(GetBlock(shape))); // now you just pass the function to the THREE.Object3d().add() accepting shape as a parameter. for (var i = 0; i < blocks.length; i++) { RandomBlock = blocks[i]; scene.add(RandomBlock); hit = false; } } I know I made a lot of changes and there are still plenty more that could reduce your code even further, but when I finally got to a point where it was working the way you wanted to I figured I'd hand it back over to you. HERE is the final code that works if you want to copy paste it over to test it. Code: //scene object variables var renderer, scene, camera, pointLight, spotLight; var hit; var newBlock = false; //field variables var fieldWidth = 500, fieldHeight = 200; function GetNewMesh(info){ var Q = info["qaulity"]; return new THREE.Mesh( new THREE.BoxGeometry( info["width"], info["height"], info["depth"], Q, Q, Q), info["material"]); } function Box(w, h, d, q, m){ var CoreInfo = { width: w, height: h, depth: d, quality: q, material: m }; var Mesh = GetNewMesh(CoreInfo); this.setMeshY = function(y){ Mesh.position.y = y; } this.setMeshX = function(x){ Mesh.position.x = x; } this.getCoreInfo = function(key){ return CoreInfo[key]; } this.setCoreInfo = function(key, val){ CoreInfo[key] = val; } this.getAllInfo = function(){ return CoreInfo; } this.getMesh = function(){ return Mesh; } this.setShadows = function(r, c){ Mesh.receiveShadow = r; Mesh.castShadow = c; } } function DoubleBox(B1w, B1h, B1d, B1q, B1m, B2w, B2h, B2d, B2q, B2m) { var Boxes = []; Boxes[0] = new Box(B1w, B1h, B1d, B1q, B1m); Boxes[1] = new Box(B2w, B2h, B2d, B2q, B2m); this.setMeshY = function (index, y) { Boxes[index].setMeshY(y); } this.setMeshX = function (index, x) { Boxes[index].setMeshX(x); } this.getCoreInfo = function (index, key) { return Boxes[index].getCoreInfo(key); } this.setCoreInfo = function (index, key, val) { Boxes[index].setCoreInfo(key, val); } this.getAllInfo = function (index) { return Boxes[index].getAllInfo(); } this.getMesh = function (index) { return Boxes[index].getMesh(); } this.setShadows = function (index, r, c) { Boxes[index].setShadows(r, c); } } var BlockMat = new THREE.MeshLambertMaterial({color: 0x3c00ff}); var Player = new Box(10, 30, 10, 1, new THREE.MeshLambertMaterial({color: 0x4AA02C})); function GetBlock(type){ if(type == "m"){ var temp = new DoubleBox(10, 75, 10, 1, BlockMat, 10, 75, 10, 1, BlockMat); var obj = new THREE.Object3D(); obj.add(temp.getMesh(0)); obj.add(temp.getMesh(1)) temp.setMeshX(0, fieldWidth/2); temp.setMeshY(0, -60); temp.setMeshX(1, fieldWidth/2); temp.setMeshY(1, 60); return obj; } else if(type == "mr"){ var temp = new DoubleBox(10, 30, 10, 1,BlockMat, 10, 110, 10, 1,BlockMat); var obj = new THREE.Object3D(); obj.add(temp.getMesh(0)); obj.add(temp.getMesh(1)); temp.setMeshX(0, fieldWidth/2); temp.setMeshY(0, -80); temp.setMeshX(1, fieldWidth/2); temp.setMeshY(1, 40); return obj; } else if(type == "ml"){ var temp = new DoubleBox(10, 30, 10, 1, BlockMat, 10, 110, 10, 1, BlockMat); var obj = new THREE.Object3D(); obj.add(temp.getMesh(0)); obj.add(temp.getMesh(1)); temp.setMeshX(0, fieldWidth/2); temp.setMeshY(0, 80); temp.setMeshX(1, fieldWidth/2); temp.setMeshY(1, -40); return obj; } else if(type == "l"){ var temp = new Box(10, 160, 10, 1, BlockMat); var obj = new THREE.Object3D(); obj.add(temp.getMesh()); temp.setMeshX(fieldWidth/2); temp.setMeshY(20); return obj; } else if(type == "r"){ var temp = new Box(10, 160, 10, 1, BlockMat); var obj = new THREE.Object3D(); obj.add(temp.getMesh()); temp.setMeshX(fieldWidth/2); temp.setMeshY(-20); return obj; } } //ball variables var reftBlock, lightBlock, middleRightBlock, middleLeftBlock, middleBlock, RandomBlock; //game-related variables var score = 0; var repeater; var blocks = []; var collidableMeshList = []; function setup() { // update the board to reflect the max score for match win document.getElementById("winnerBoard").innerHTML = "Move in the gaps!"; // set up all the 3D objects in the scene createScene(); // and let's get cracking! draw(); } function createScene() { // set the scene size var WIDTH = 640, HEIGHT = 360; // set some camera attributes var VIEW_ANGLE = 50, ASPECT = WIDTH / HEIGHT, NEAR = 0.1, FAR = 10000; var c = document.getElementById("gameCanvas"); // create a WebGL renderer, camera // and a scene renderer = new THREE.WebGLRenderer({antialias:true}); renderer.setClearColorHex(0xffffff); camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR); scene = new THREE.Scene(); // add the camera to the scene scene.add(camera); // set a default position for the camera // not doing this somehow messes up shadow rendering //camera.position.z = 320; // start the renderer renderer.setSize(WIDTH, HEIGHT); // attach the render-supplied DOM element c.appendChild(renderer.domElement); // set up the playing surface plane var planeWidth = fieldWidth, planeHeight = fieldHeight, planeQuality = 10; // create the plane's material var planeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff }); // create the table's material var tableMaterial = new THREE.MeshLambertMaterial( { color: 0x3c00ff }); // create the ground's material var groundMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff }); // create the playing surface plane var plane = new THREE.Mesh( new THREE.PlaneGeometry( planeWidth * 1.25, // 95% of table width, since we want to show where the ball goes out-of-bounds planeHeight, planeQuality, planeQuality), planeMaterial); scene.add(plane); plane.receiveShadow = true; var table = new THREE.Mesh( new THREE.BoxGeometry( planeWidth * 1.15, // this creates the feel of a billiards table, with a lining planeHeight * 1.04, 100, // an arbitrary depth, the camera can't see much of it anyway planeQuality, planeQuality, 1), tableMaterial); table.position.z = -51; // we sink the table into the ground by 50 units. The extra 1 is so the plane can be seen scene.add(table); table.receiveShadow = true; scene.add(Player.getMesh()); startSpawningEnemies(); Player.setShadows(true, true) /*collidableMeshList.push(MiddleBlock.getMesh(0), MiddleBlock.getMesh(1), MiddleLeftBlock.getMesh(0), MiddleLeftBlock.getMesh(1), MiddleRightBlock.getMesh(0), MiddleRightBlock.getMesh(1), RightBlock.getMesh(), LeftBlock.getMesh());*/ // set paddles on each side of the table Player.setMeshX(-fieldWidth/2 + Player.getCoreInfo("width")); //collidableMeshList.push(RandomBlock); // finally we finish by adding a ground plane // to show off pretty shadows var ground = new THREE.Mesh( new THREE.BoxGeometry( 1000, 1000, 3, 1, 1, 1 ), groundMaterial); // set ground to arbitrary z position to best show off shadowing ground.position.z = -132; ground.receiveShadow = true; scene.add(ground); // // create a point light pointLight = new THREE.PointLight(0xffffff); // set its position pointLight.position.x = -1000; pointLight.position.y = 0; pointLight.position.z = 1000; pointLight.intensity = 2.9; pointLight.distance = 10000; // add to the scene scene.add(pointLight); // add a spot light // this is important for casting shadows spotLight = new THREE.SpotLight(0xffffff); spotLight.position.set(0, 0, 460); spotLight.intensity = 1.5; spotLight.castShadow = true; scene.add(spotLight); // MAGIC SHADOW CREATOR DELUXE EDITION with Lights PackTM DLC renderer.shadowMapEnabled = true; } function draw() { // draw THREE.JS scene renderer.render(scene, camera); // loop draw function call requestAnimationFrame(draw); cameraPhysics(); playerPaddleMovement(); enemyPaddleMovement(); collision(); //addScore(); } function addScore() { if (RandomBlock.position.x < Pad.getMesh().position.x*2 && newBlock == false) { console.log("pass"); newBlock = true; if (hit == false) { score++; } else { score-- } document.getElementById("scores").innerHTML = score; } } function enemyPaddleMovement() { if(score < 10) { for (var i = 0; i < blocks.length; i++) { blocks[i].position.x -= 3; } } if(score >= 10) { for (var i = 0; i < blocks.length; i++) { blocks[i].position.x -= 5; } } } function playerPaddleMovement() { if (Key.isDown(Key.D)) Player.setMeshY(80); else if (Key.isDown(Key.F)) Player.setMeshY(40); else if (Key.isDown(Key.H)) Player.setMeshY(0); else if (Key.isDown(Key.J)) Player.setMeshY(-40); else if (Key.isDown(Key.K)) Player.setMeshY(-80); } //Handles camera and lighting logic function cameraPhysics() { // move to behind the player's paddle camera.position.x = Player.getMesh().position.x - 100; camera.position.y += (Player.getMesh().position.y - camera.position.y) * 0.05; camera.position.z = Player.getMesh().position.z + 100 + 0.04 * (Player.getMesh().position.x); // rotate to face towards the opponent camera.rotation.y = -60 * Math.PI/180; camera.rotation.z = -90 * Math.PI/180; } //Handles paddle collision logic function collision() { var originPoint = Player.getMesh().position.clone(); for (var vertexIndex = 0; vertexIndex < Player.getMesh().geometry.vertices.length; vertexIndex++) { var ray = new THREE.Raycaster( originPoint, Player.getMesh().geometry.vertices[vertexIndex] ); var collisionResults = ray.intersectObjects( collidableMeshList ); if ( collisionResults.length > 0) { console.log("true"); hit = true; } } } function resetBall() { } //checks if either player or opponent has reached 7 points function matchScoreCheck() { } function spawnEnemy() //total enemies starts at 0 and every-time you add to array { var shapes = ["l", "r", "mr", "ml", "m"]; var shape = shapes[Math.floor(Math.random() * shapes.length)]; blocks.push(new THREE.Object3D().add(GetBlock(shape))); for (var i = 0; i < blocks.length; i++) { RandomBlock = blocks[i]; scene.add(RandomBlock); hit = false; } } function startSpawningEnemies() { repeater = setInterval(function() { spawnEnemy(); newBlock = false; }, 1000); //this calls spawnEnemy every spawnRate /////////spawn 'spawnAmount' enemies every 2 seconds } I also commented out your addScore() function because it references RandomBlock which is not defined in its scope and the error message was annoying for debugging. I also commented out the collision as you will need to think of a new method for doing that. Most likely just build a function that accepts an array and then just pass it your blocks array and let it loop through it. Overall cool game good luck to ya. Don't hesitate to reach out if you have any other questions. Reply With Quote Users who have thanked Lesshardtofind for this post: TeaAnyOne (01-31-2015) 01-31-2015, 02:31 PM #3 TeaAnyOne View Profile View Forum Posts New to the CF scene Join Date Jan 2015 Posts 4 Thanks 2 Thanked 0 Times in 0 Posts Wow! I didn't expect such a huge reply, it seems that my original code has changed a lot and I will have to give it a hard look through it to understand it. I will contact you if I have any questions, I have a lot of work ahead of me. Thanks a lot Reply With Quote 01-31-2015, 04:45 PM #4 TeaAnyOne View Profile View Forum Posts New to the CF scene Join Date Jan 2015 Posts 4 Thanks 2 Thanked 0 Times in 0 Posts I suppose I do have one more question. How do I get the position.x of the Randomblocks. I tried using a for loop like this: for (var i = 0; i < blocks.length; i++) { if (blocks[i].position.x === Player.getMesh().position.x*2 && newBlock === false) { console.log("pass"); newBlock = true; if (hit === false) { score++; } else { score--; } } document.getElementById("scores").innerHTML = score; } } it works but it seems kind of buggy as it stops counting to 10 when it changes speed. Is there another way to retrieve the position? Reply With Quote 01-31-2015, 07:43 PM #5 Lesshardtofind View Profile View Forum Posts Visit Homepage New Coder Join Date Sep 2013 Location Houston Posts 20 Thanks 0 Thanked 4 Times in 4 Posts That should work for getting the position since the Blocks are objects of type THREE.Object3d so any methods they have should work for you. You may be having problems because you never despawn enemies ultimately getting a huge number of 3d objects in your array blocks, or you may find your position requirement doesn't mathematically work with your speed up. Sometimes just using a few extra console.logs to track your numbers inside of functions that don't seem to be working can help you to get an idea of what values it is seeing for the numbers and when. It might make the problem super obvious. This more like shotgun debugging which is discouraged by many, but I found it to help a lot when I was first learning code. Ultimately you want to understand your logic in each function and how it can fail when you program it, and then use error checking to make sure no parameters get outside of your allowed variance. Reply With Quote Users who have thanked Lesshardtofind for this post: TeaAnyOne (01-31-2015) 01-31-2015, 08:27 PM #6 TeaAnyOne View Profile View Forum Posts New to the CF scene Join Date Jan 2015 Posts 4 Thanks 2 Thanked 0 Times in 0 Posts OK ill see if I can get it working. Thanks for all your help! It helped me a lot. Reply With Quote 01-31-2015, 08:31 PM #7 Old Pedant View Profile View Forum Posts Supreme Master coder! Join Date Feb 2009 Posts 28,310 Thanks 82 Thanked 4,754 Times in 4,716 Posts Originally Posted by Lesshardtofind Ultimately you want to understand your logic in each function and how it can fail when you program it, and then use error checking to make sure no parameters get outside of your allowed variance. Very well said! I want to have multiple instances of jcarousellite on the same page, but as you can see, they both scroll together. I am javascript brain dead, so any help would be appreciated, even if it's something obvious. http://goo.gl/vMLPA I found the following guide, but I need my hand held. http://myintarweb.com/dispatch/multiple-jcarouselite I'm working on code for my forums that will allow users to post text which can be moused over to display an image that will follow the cursor (provided the cursor is hovering above the specific text). The code works, but it obviously can't be used for more than one picture per page because getElementById finds the first div and always displays it onmouseover of any attempted mouseover text. The Javascript in <head> is Code: <script type="text/javascript"> // Pop up code begin function ShowPopup(hoveritem) { hp = document.getElementById("hoverpopup"); // Set popup to visible hp.style.visibility = "Visible"; } function HidePopup() { hp = document.getElementById("hoverpopup"); hp.style.visibility = "Hidden"; } // Follow mouse script begin var divName = 'hoverpopup'; // div that is to follow the mouse // (must be position:absolute) var offX = 5; // X offset from mouse position var offY = 5; // Y offset from mouse position function mouseX(evt) {if (!evt) evt = window.event; if (evt.pageX) return evt.pageX; else if (evt.clientX)return evt.clientX + (document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft); else return 0;} function mouseY(evt) {if (!evt) evt = window.event; if (evt.pageY) return evt.pageY; else if (evt.clientY)return evt.clientY + (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); else return 0;} function follow(evt) {if (document.getElementById) {var obj = document.getElementById(divName).style; obj.left = (parseInt(mouseX(evt))+offX) + 'px'; obj.top = (parseInt(mouseY(evt))+offY) + 'px';}} document.onmousemove = follow; </script> So the display code is Code: <a id="hoverover" style="cursor:default;" onMouseOver="ShowPopup(this);" onMouseOut="HidePopup();">text here</a> <div id="hoverpopup" style="visibility:hidden; position:absolute;"><img src="url here"></div> I just want to be able to have more than one instance on each page and still be able to declare the image url in the body and not within the javascript. Hi, I have written a code below: Code: <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <script type="text/javascript"> function emailRowContent(isSelected, emailAddress, severity) { var emailRowObj = document.getElementById('emailRow'); emailRowObj.childNodes[1].childNodes[0].checked = isSelected; emailRowObj.childNodes[3].childNodes[0].value = emailAddress; emailRowObj.childNodes[5].childNodes[0].checked = severity; } function LoadUp() { var emailAddressListObj = document.getElementById('emailAddressList'); var arrayOfEmails = new Array(5); for (i = 0; i < 5; i++) { arrayOfEmails[i] = new emailRowContent( "checked", "fjkum@unknown.com" + i, i ); //emailAddressListObj.appendChild( arrayOfEmails[i] ); /* Somehow this line breaks */ } } </script> <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> <title>Insert title here</title> </head> <body onload="javascript:LoadUp();"> <div id="emailRow" class="emailRowClass"> <div><input type="checkbox" class="checkbox1"></div> <div><input type="text" class="textfield"></div> <div><input type="checkbox" class="checkbox2"></div> </div> <div id="emailAddressList" class="emailAddressClass"></div> </body> </html> Basically, what I want to do is to dynamically create 5 instances of "emailRow" onto the web page making use of Javascript DOM. But have no success in getting it to work. Can anyone shed some light? Mike Im using the following script: Code: <script type="text/javascript"> function unhide(hiddentext) { var item = document.getElementById(hiddentext); if (item) { item.className=(item.className=='hidden')?'unhidden':'hidden'; } } </script> <style type="text/css"> .unhidden { display: block; } .hidden { display: none; } </style> to hide and unhide a block of text on my page, using onclick events. the problem is its not allowing me to use it multiple times in a page. when i use a second instance of it, both stop working. the above demonstrated script is working with the following elements: middle (approx) of page: Code: <td class="desc_cell"><strong>Download Station</strong><br /> 17" Macbook Pro<br /><a href="javascript:unhide('itemlist');" onclick="changeText(this,'Hide Item List');" id="text1link"]Old Text>Click Here For Full Item List</a><div id="hiddentext" class="hidden">list of items goes herelist of items goes herelist of items goes herelist of items goes herelist of items goes herelist of items goes herelist of items goes herelist of items goes herelist of items goes herelist of items goes herelist of items goes herelist of items goes herelist of items goes herelist of items goes here</div> </td> bottom of page: [code]<p align="center" style="citylist">Allen Park MI, Anchor Bay Gardens MI, Anchor Bay Harbor MI, Anchor Bay Shores MI, Andersonville MI,<a href="javascript:unhide('hiddentext');" onclick="changeText(this,' View Less...');" id="text1link"]Old Text>View More...</a></p><div id="hiddentext" class="hidden">Armada MI, Auburn Heights MI, Auburn Hills MI, Austin Corneorth Farmington MI, Northville MI, Norton MI, Novi MI, Oak MI, Oak Grove MI, Oak Park MI, Oakley Park MI, Oakwood MI, Orchard Lake MI, Ortonville MI, Oxbow MI, Oxford MI, Perry Lake Heights MI, Pleasant Ridge MI, Plymouth MI, Point Lakeview MI, Pontiac MI, Preston Coom MI, Wolcott Mills MI, Wolverine Lake MI, Wood Creek Farms MI, Woodhaven MI, Wyandotte MI, Yates MI, and many more!</div> The statement does what I want it to do, except if there is multiple instances of the word, it only outputs one, how can I work it so all instances are output in red? (while still using .slice) var phrase = prompt("Enter a messate: ", 'Message'); var searchFor = prompt("Enter search text: ", 's'); var matchPhrase = ""; var searchIndex = -1; /* if there's a match, create a text string by * add the phrase text from before the match, * add <font> tags around the match text, * add the rest of the phrase from after the match */ searchIndex = phrase.indexOf(searchFor); if (searchIndex >=0 ) { // Copy text from phrase up till the match. matchPhrase += phrase.slice(0, searchIndex); matchPhrase += '<font color="red">' + searchFor + '</font>'; matchPhrase += phrase.slice(searchIndex + searchFor.length); phrase++ } else { matchPhrase = "No matches" } document.writeln(matchPhrase); Reply With Quote 01-31-2015, 09:08 AM #2 Philip M View Profile View Forum Posts Supreme Master coder! Join Date Jun 2002 Location London, England Posts 18,371 Thanks 204 Thanked 2,573 Times in 2,551 Posts Use a regular expression. So I want to swap an image when it's clicked on (and then swaps right back after release) and currently I have working code for this, HOWEVER (and the reason for my post) I want this to be a redundant image, so it would be the same image used about 25 times on the page (same image, with same image swap effect) it's basically a download button then slightly changes it's style when clicked on. The problem is that my current code requires me to give each image it's own specific id / name and I have to recreate more sript code for each image id as well. The following example code would be what is currently required for just 2 images (they are the exact same image with exact same swap) but as you can see for every additional download button on the page I have to add a new id for it and a bunch of additional code, so it's quite ridiculous as to how much code is required for 25 of the exact same images on the page. in the header I have: Code: <script language="JavaScript"> <!-- // PRELOADING IMAGES if (document.images) { downloadbtn_down=new Image(); downloadbtn_down.src="images/download_pressed.png"; downloadbtn_up =new Image(); downloadbtn_up.src ="images/download.png"; } if (document.images) { downloadbtn2_down=new Image(); downloadbtn2_down.src="images/download_pressed.png"; downloadbtn2_up =new Image(); downloadbtn2_up.src ="images/download.png"; } // EVENT HANDLERS function pressButton(btName) { if (document.images) eval('document.'+btName+'.src='+btName+'_down.src'); } function releaseButton(btName) { if (document.images) eval('document.'+btName+'.src='+btName+'_up.src'); } //--></script> and for each image in the body I have (example is for 2 images): Code: <a href="indexpg.htm" onMouseDown="pressButton('downloadbtn');return true;" onMouseUp="releaseButton('downloadbtn');return true;" onMouseOut="releaseButton('downloadbtn');return true;" onClick="return true;" ><img id=downloadbtn width=422px height=80px border=0 alt="Download" src="images/download.png" ></a> <a href="indexpg.htm" onMouseDown="pressButton('downloadbtn2');return true;" onMouseUp="releaseButton('downloadbtn2');return true;" onMouseOut="releaseButton('downloadbtn2');return true;" onClick="return true;" ><img id=downloadbtn2 width=422px height=80px border=0 alt="Download" src="images/download.png" ></a> I want to be able to just use the same piece of code without having to add a new id for every download button on the page and tons of redundant code, especially since the image is the same it doesn't make sense to have to give each one a specific id and specific javascript for each of those id's. I would think this would be quite simple, but I know nothing about javascript, and I have searched a lot without any luck. PLEASE HELP ME! I have this script which is set to generate random anagrams of my name in rotation which works fine, but I can't work out how to put multiple instances of it on one page. if someone could point me in the right direction i'd be very grateful. thanks the code is var quotations = new Array() quotations[0]= "germaine arnold" quotations[1]= "endearing moral" quotations[2]= "analog reminder" quotations[3]= "regained normal" quotations[4]= "renaming ordeal" quotations[5]= "nominal regrade" quotations[6]= "arraigned lemon" quotations[7]= "ringleader moan" quotations[8]= "mineral groaned" function display() { a=Math.floor(Math.random()*quotations.length) document.getElementById('quotation').innerHTML=quotations[a] setTimeout("display()",5000) } and i'm calling the function using: <div id="quotation"> <SCRIPT type="text/javascript">display()</SCRIPT> </div> I'm pretty new to Javascript and just started with some OOP concepts, so this might be an obvious one and I apologize if the question is much longer than it should be... Basically I am trying to create a reusable class object with several internal functions, that is completely abstracted, meaning the class object itself should never have to reference the global declarations or window object. This class should be aware of itself at any point in the execution of it's own functions, and that is what I'm having trouble with at the moment. What I'm trying to do is create reusable javascript "Apps" for my HTML web application, where multiple instances can be instantiated and used independently from one another. My main problem is "this" loses context in the Ajax callback and onclick handlers. I'm not sure how to persist the context of "this", or at least keep a reference to prototype instance itself. Let's set up a simple class called "App" to demonstrate what I mean... Code: var myApp = new App("MyFirstApp"); function App(argName) { this.name = argName; this.GetDirectory("C:\Program Files"); } App.prototype.GetDirectory = function(argPath) { // "this" equals the App object instance (good!), meaning this.name should equal "MyFirstApp" Ajax.GetDirectory(argPath, this.GetDirectoryCallback, this.GetDirectoryTimeout, this.GetDirectoryError); } App.prototype.GetDirectoryCallback = function(argFilePaths) { // "this" equals the "window" object (bad!), meaning this.name should equal a null reference // argFilePaths contains a string of file paths (delimited using ;) returned by the server var mFilePaths = split(argFilePaths, ";"); // for each file path, add a div to the document body containing that file path, with an onclick handler for (var i in mFilePaths) { var mFilePath = mFilePaths[i]; var mFilePathDiv = document.createElement("div"); mFilePathDiv.innerHTML = mFilePath; mFilePathDiv.setAttribute("onclick", "javascript:this.FilePathDivClickHandler();return false;"); document.getElementById("body").appendChild(mFilePathDiv); } } App.prototype.FilePathDivClickHandler = function() { // I need a reference to the App object instance here, but I'm not sure where to grab it... // what I want to do is call GetDirectory again, referencing the div's innerHTML which contains another file path, like this: this.GetDirectory(event.target.innerHTML); } The onclick handler using "this" is obviously not going to work because "this" is a reference to the "window" object which does not have a function called FilePathDivClickHandler(). So what I can do is nest the GetDirectoryCallback() function inside the GetDirectory() function so that GetDirectoryCallback() can reference the variables in the outer function (GetDirectory). Code: App.prototype.GetDirectory = function(argPath) { // "this" equals the App object instance (good!), meaning this.name should equal "MyFirstApp" // "this" will still lose context inside the callback, so we can set up a variable called "instance" that the callback can reference var instance = this; Ajax.GetDirectory(argPath, GetDirectoryCallback, GetDirectoryTimeout, GetDirectoryError); function GetDirectoryCallback(argFilePaths) { // "this" equals the window object (bad!), meaning this.name should equal a null reference // "instance" equals the App object instance (good!), meaning instance.name should equal "MyFirstApp" // argFilePaths contains a string of file paths (delimited using ;) returned by the server var mFilePaths = split(argFilePaths, ";"); // for each file path, add a div to the document body containing that file path, with an onclick handler for (var i in mFilePaths) { var mFilePath = mFilePaths[i]; var mFilePathDiv = document.createElement("div"); mFilePathDiv.innerHTML = mFilePath; mFilePathDiv.setAttribute("onclick", "javascript:instance.FilePathDivClickHandler();return false;"); document.getElementById("body").appendChild(mFilePathDiv); } } } Even though we have persisted the App object instance through the use of the "instance" variable in the outer function, the onclick event handler still does not work; when it fires, "instance" is an unknown object. Would placing the FilePathDivClickHandler() function inside the GetDirectory() function, much like what was done with the callback, allow me to use "instance" correctly for the onclick handler? Hi Guys, What is the best way to create a javascript class that has all its methods and properties private unless I want them to be public? Many thanks for any help, S Hey all, I am reading a book called JavaScript patterns. In it, this method is created: Code: var klass = function(Parent,template){ var Child, F, i; Child = function () { if (Child.uber && Child.uber.hasOwnProperty("__construct")) { Child.uber.__construct.apply(this, arguments); } if (Child.prototype.hasOwnProperty("__construct")) { Child.prototype.__construct.apply(this, arguments); } } Parent = Parent || Object; F = function () {}; F.prototype = Parent.prototype; Child.prototype = new F(); Child.uber = Parent.prototype; Child.prototype.constructor = Child; for (i in template) { if (template.hasOwnProperty(i)) { Child.prototype[i] = template[i]; } } return Child; } Does anyone have an understanding of why we instantiate a new F() to the Child prototype rather than instantiate the Parent prototype? As you can see above, we assign Parent prototype to F prototype and then instantiate F() object to Child prototype. I'm not sure why it's being done this way. Code: F.prototype = Parent.prototype; Child.prototype = new F(); Thanks for response. I'm quite new to javascript and don't often understand what I'm reading, so the search results I found didn't seem to help me much. Being such, if this question has been addressed elsewhere, my apologies. On my site, I have a navigation pane with 4 links. Two of these links show collapsable submenus. When one clicks a link, I want the CSS class of that link to change. For the two "real" links, I've just changed the class on the page itself. For the two collapsible menus, I'm trying to employ javascript. Ultimately for these two links, I want the class to change when clicked, and change back when clicked again. Here's the code for the page: Code: <div id="navigation"> <ul> <li><h3><a href="javascript:;" onclick="changeclass(this);" onmousedown="toggleSlide('slidemenu');" class="colmain">COLLAPSIBLE MENU 1</a></h3></li> <div id="slidemenu" style="display:none; overflow:hidden; height:100px;"> <li><h4><a href="#" class="sub">SUBMENU LINK 1</a></h4></li> <li><h4><a href="#" class="sub">SUBMENU LNK 2</a></h4></li> </div> <li><h3><a href="#" class="main">LINK 1</a></h3></li> <li><h3><a href="javascript:;" onclick="changeclass(this);" onmousedown="toggleSlide('slidemenu2');" class ="colmain">COLLAPSIBLE MENU 2</a></h3></li> <div id="slidemenu2" style ="display:none; overflow:hidden; height:100px;"> <li><h4><a href="#" class="sub">SUBMENU LINK 1</a></h4></li> <li><h4><a href="#" class="sub">SUBMENU LINK 2</a></h4></li> </div> <li><h3><a href="#" class="main" >LINK 2</a></h3></li> </ul> </div> Here's the javascript I'm working with, which I adopted from http://www.webdeveloper.com/forum/sh...d.php?t=167660 : Code: /*<![CDATA[*/ var colstatus; function changeclass(obj) { if (colstatus) colstatus.className='colmain'; { obj.className='colmainshow'; colstatus=obj; } else { obj.className='colmain'; colstatus=obj; } } /*]]>*/ I have three questions about this. 1. Seeing as I've been working with javascript for a grand total of six days so far, could you explain the best way to make my code work? What's the significance of colstatus=obj? 2. The javascript works if I leave out the else statement. It will change the class after being clicked, but, of course, doesn't change it back. However, if I click the other collapsible menu, it will change as expected, but the first will revert back to the original class. Why is this happening? 3. Seeing as the code is adopted, I have no idea what /*<![CDATA[*/ and /*]]>*/ mean. Would you explain? Thanks in advance for your patience and answers! Could someone please explain the difference in these two methods of creating objects: //anonymous self invoking function providing private methods var a_module = (function() { var private_variable = "some value"; function private_function() { //some code } return { public_property: "something" //etc } }() ); //Can use a_module.public_property with this Is there any difference between the above and this: var A_module - new Object(); A_module(property1, property2) = { this.property1 = property1; this.property2 = property2; this.methodName = function(){//code} } A_module.prototype.property = "//property" A_module.newMethod = function() {//code} Are they both just different ways of creating objects with methods and properties? Hey all, my first post here. I'm primarily a designer but need to get more into the code aspect of things (and will be getting jQuery asap), but at the moment i'm very behind on time on a project and could use some quick help. Basically, I'm making a dynamically loading text box input area for RMA returns for our products. But thats kind of irrelevant, here's my question: I have an external style sheet with only this in it (more will be added later for future sections, thats why im making it it's own "css-forms.css" file: Code: .formpad { padding:3px 3px 3px 3px; } In my main .html, some of my javascript for my dynamic table contains lines like these: Code: var esnImeiInput = "<INPUT type=\"text\" name=\"esn_imei[]\" size=\"20\">"; var invoiceInput = "<INPUT type=\"text\" name=\"invoice[]\" size=\"8\">"; var datePurchaseInput = "<INPUT type=\"text\" name=\"date_purchase[]\" size=\"8\">"; var noteInput = "<INPUT type=\"text\" name=\"notes[]\" size=\"18\">"; var trOpenTag = "<tr>"; var trCloseTag = "</tr>"; var tbOpenTag = "<table>"; var formRows = modelInput + reasonInput + esnImeiInput + invoiceInput + datePurchaseInput + noteInput + "<br />"; for(x=0;x<10;x++) { formRows += modelInput + reasonInput + esnImeiInput + invoiceInput + datePurchaseInput + noteInput + "<br />"; } Where inside those vars (INPUT's) would i REFER to the 'class' of .formpad? Basically I just want to add cellpadding to the table that is being dynamically loaded. If anyone has time to help via IM that'd be cool too, this is pretty easy stuff for true coders. (the test page for all of this is currently at: http://planetcellinc.com/rma-rev726.html Any help appreciated, thanks! -Hrl2k Hi, could someone please help. I have this code, and it currently outputs:"name-category" but I need it to output "category-name". Sorry if this is easy, I just keep getting errors! Code: highlightWork : function(workType) { // remove all active classes $(".work").removeClass("active"); for (var x=0;x<workTypes.length;x++) { if (workType.toLowerCase()==workTypes[x][0].toLowerCase()) { $("."+workTypes[x][0]+"-category").addClass("active"); // set current highlight $("."+workTypes[x][0]).addClass("highlight"); } else { // remove current highlights $("."+workTypes[x]).removeClass("highlight"); if (workType.length!=0) { $("."+workTypes[x][0].split(" ")[0]+"-category").addClass("inactive"); } } } }, I have a problem with some forms and utilizing the proper code to make them work. Need some help if anyone out there has some working knowledge could help let me now, anyone ?? Eric I will post the code and the problem if someone would chim in thanks Hi there, I have a couple of scripts which both do exactly what I want, but when I try use them both at the same time only one of them will work, could you tell me if i need to change anything in them to get them both to work at the same time or if im missing something really simple? Thanks Script 1 Code: <script type="text/javascript"> var imgPaths = ['pic1.jpg', 'pic2.jpg', 'pic3.jpg', 'pic4.jpg', 'pic5.jpg']; //preload the images var imgObjs = new Array; for(var i=0; i < imgPaths.length; i=i+1) { imgObjs[i] = new Image(); imgObjs[i].src = imgPaths[i]; } function togglePic(num) { if(currPic == 0 || currPic != num) { document.getElementById("image").src = imgObjs[num].src; currPic = num; } else { document.getElementById("image").src = imgObjs[0].src; currPic = 0; } } //load the default image window.onload=function() { document.getElementById("image").src = imgObjs[0].src; currPic = 0; //flag storing current pic number } </script> Script 2 Code: <script type="text/javascript"> window.onload=function () { setStyles(); }; function setStyles() { ids = new Array ('style1','style2','style3','style4'); for (i=0;i<ids.length;i++) { document.getElementById(ids[i]).className=''; document.getElementById(ids[i]).onclick=function() { return Cngclass(this); } } } function Cngclass(obj){ var currObj; for (i=0;i<ids.length;i++) { currObj = document.getElementById(ids[i]); if (obj.id == currObj.id) { currObj.className=(currObj.className=='')?'selected':''; } else { currObj.className=''; } } return false; } </script> HTML Code: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title></title> </head> <body> <div id="style"> <div id="styleimage"> <img src="" id="image" width="610" height="229" /> </div> <div id="stylenav"> <ul> <li id="style1"><a href="#" onclick="togglePic(1); return false">style 1</a></li> <li id="style2"><a href="#" onclick="togglePic(2); return false">style 2</a></li> <li id="style3"><a href="#" onclick="togglePic(3); return false">style 3</a></li> <li id="style4"><a href="#" onclick="togglePic(4); return false">style 4</a></li> </ul> </div> </div> </body> </html> |