简体   繁体   中英

Modifying div by returning a function from a function in JavaScript

So, my assignment is to pass a div to a function then return a function that will create a new div, assign a class (defined in CSS) and add to the div that was originally passed into the function.

More specifically, the addDivTo() function receives a div id and returns a function. The function being returned receives a class as a parameter, in this function the new div should be created, the class applied and create random location to place in the original div.

It took me some time to wrap my head around this, I think I have the addDivTo() built correctly as I am receiving the function back into the variable, but nothing is happening when trying to pass the class into the return function.

I apologize, I have a bunch of comments in my code to try and keep straight what I'm attempting to do but I'm obviously not doing something right since nothing is happening! If anyone could point me in the right direction or explain what I'm doing wrong I would appreciate it.

<!doctype html>
<html>
<head>
 <title> Functions: Returning a function from a function </title>
 <meta charset="utf-8">
 <style>
    html, body, div#container {
      width: 100%;
      height: 100%;
      margin: 0px;
      padding: 0px;
    }
    div#container1, div#container2 {
      position: relative;
      height: 300px;
      border: 1px solid black;
    }
    .red {
      position: absolute;
      width: 150px;
      height: 150px;
      background-color: red;
    }
    .blue {
      position: absolute;
      width: 175px;
      height: 175px;
      background-color: lightblue;
    }
    .circle {
      width:100px;
      height:100px;
      border-radius:50px;
      font-size:20px;
      color:#fff;
      line-height:100px;
      text-align:center;
      background:#000
     }
     .squared {
       border: 2x solid black;
     }
 </style>
   <script>
      window.onload = init;
       function init() {    
       //Pass value for div container into addDivTo()
       //addDivTo() will return a function to the variable passed to it
       //when calling function returned from addDivTo pass in name of 
       //class the div should have

      var containerOne = document.getElementById("container1");
      var containerTwo = document.getElementById("container2");
      var colorOne = getComputedStyle(document.body, "red");
      var colorTwo = getComputedStyle(document.body, "blue");
      var shapeSquare = getComputedStyle(document.body, "square");
      var shapeCircle = getComputedStyle(document.body, "circle");

      //call addDivTo() calling containers
     //return function will be contained in the variables

     var newDiv1 = addDivTo(containerOne);   
     var newDiv2 = addDivTo(containerTwo);

     //pass class to function which should return the new div and class 
     //and append to original container passed to addDivTo 

     var addColor = newDiv1(colorOne);
     containerOne.appendChild(addColor);
     var addShape = newDiv1(shapeSquare);
     containerOne.appendChild(addShape);
     var addColor2 = newDiv2(colorTwo);
     containerTwo.appendChild(addColor2);
     var addShape2 = newDiv2(shapeCircle);
     container2.appendChild(addShape2);         
 } 

 function addDivTo (containerIn) {
 //Takes container id and returns a function when called

//Return function takes class, create new div element and add to div 
//passed in the call addDivTo                     
     return function(classToAdd) {
      var divIn = containerIn;   
      var classIn = classToAdd;                  
      var newDiv = document.createElement('div');
      newDiv.id = "funcDiv";
      newDiv.style.left = Math.floor(Math.random() * (newDiv.offsetWidth 
                      = 175)) + "px";
      newDiv.style.right = Math.floor(Math.random() *
                      (newDiv.offsetHeight = 175)) + "px"; 
      newDiv.className = classIn;             
      return newDiv;   
     };

 }  

  </script>
</head>
<body>
  <div id="container1"></div>
  <div id="container2"></div>
</body>
</html>

First off, getComputedStyle doesn't work like that at all. It returns a style object and doesn't take a class for a second argument. Read the docs on MDN.

Second, there's a p missing for px in your .squared css.

Next, you've got a lot of useless variables that get created only to be passed immediately after, such as divIn and classIn.

Finally, ids have to be unique in a document, but your function always creates divs with the same id.

And why do you have to return a function in the first place? Couldn't you just make one function called addDivTo(parent, class) which would take care of appending as well as everything else?

Start by fixing that and look at the JS console for debug messages.

If you use .className property you must only pass the classname. Take a look here: http://www.w3schools.com/jsref/prop_html_classname.asp

You just need to change:

var colorOne = getComputedStyle(document.body, "red");
var colorTwo = getComputedStyle(document.body, "blue");

To:

var colorOne = "red";
var colorTwo = "blue";

Here is a working sample: http://codepen.io/anon/pen/KwYYMp

You're returning a function (that we'll call later) not a new div.

the addDivTo() function receives a div id and returns a function

So instead of

var newDiv1 = addDivTo(containerOne);

Think of this

var funcAddToContainerOne = addDivTo(containerOneId);

The function being returned receives a class as a parameter, in this function the new div should be created, the class applied

Now you're on the right track with

function addDivTo (containerId) {                
    // this is an anonymous function you will assign to a variable
    return function(classToAdd) {
        // 1. create new div
        // 2. add class
        // 3. find containerId
        // 4. append new div to found element
    }
}

And you can call your new anonymous function with the variable you set up earlier:

var funcAddToContainerOne = addDivTo(containerOneId);
funcAddToContainerOne(className);

Now all of your DOM manipulations are removed from the main init() function and embedded in your anonymous function.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM