jQuery dynamically change element height

2020-03-01 17:05发布

问题:

I'm working on a fluid layout project. I have some fixed height DIVs in my document, and the heights are different for all of them. I need to proportionally change these DIVs height on browser resize. Here is the markup.

<body>
<div id="a" class="target"></div>
<div id="b" class="target"></div>
<div id="c" class="target"></div>
</body> 

And css:

<style>
    body { width: 90%; margin: 0 auto;} 
    .target { width:30%; float:left; margin:1.6%; cursor:pointer; }
    #a { height: 200px; background-color: yellow;}
    #b { height: 400px; background-color: green;}
    #c { height: 600px; background-color: grey;}
</style>

Sounds easy! The main condition is that i don't know the precize amount of target DIVs and their IDs, that's why i'm using .each(function()). Here is script i wrote:

$(document).ready(function(){
//set the initial body width
var originalWidth = 1000; 
/*I need to go through all target divs because i don't know 
how many divs are here and what are their initial height*/
$(".target").each(function() 
{
    //get the initial height of every div
    var originalHeight = $(this).height(); 
    //get the new body width
    var bodyWidth = $("body").width(); 
    //get the difference in width, needed for hight calculation 
    var widthDiff = bodyWidth - originalWidth; 
    //new hight based on initial div height
    var newHeight = originalHeight + (widthDiff / 10); 
    //sets the different height for every needed div
    $(this).css("height", newHeight); 
});

});

This script perfectly works when user reload the page. How can i get the same results dinamically, when user resizes browser without reloading? I know i should apply $(window).resize event listener. But the problem is that DIV's initial height will be calculated inside the event and the result will be almoust like endless loop- that is the final height will increase or decrease in huge progression. I don't need that! How can i make each DIV initial height calculation outside event function and then use these heights inside event function? Or may be there is another aproach to get the same result?

回答1:

You need to store the original height of each div. There are different ways to do it, here's one hack, store it in the DOM node itself (there are better ways, but this is quick and dirty).

$(document).ready(function(){
  //set the initial body width
  var originalWidth = 1000; 
  /*I need to go through all target divs because i don't know
  how many divs are here and what are their initial height*/


  function resize() {
    //This will only set this._originalHeight once
    this._originalHeight = this._originalHeight || $(this).height();
    //get the new body width
    var bodyWidth = $("body").width(); 
    //get the difference in width, needed for hight calculation 
    var widthDiff = bodyWidth - originalWidth; 
    //new hight based on initial div height
    var newHeight = this._originalHeight + (widthDiff / 10); 
    //sets the different height for every needed div
    $(this).css("height", newHeight); 

  }

  $(".target").each(resize);
  $(document).resize(function(){
      $(".target").each(resize);
  });
});


回答2:

Wrap up your resize functionality and subscribe to the window resize event.

$(document).ready(function(){
   //set the initial body width
   var originalWidth = 1000; 
   resizeTargets();
   $(window).resize(resizeTargets);

});

function resizeTargets()
{
   $(".target").each(function() 
   {
       //get the initial height of every div
       var originalHeight = $(this).height(); 
       //get the new body width
       var bodyWidth = $("body").width(); 
       //get the difference in width, needed for hight calculation 
       var widthDiff = bodyWidth - originalWidth; 
       //new hight based on initial div height
       var newHeight = originalHeight + (widthDiff / 10); 
       //sets the different height for every needed div
       $(this).css("height", newHeight); 
   });
}


回答3:

take a look at the resize event that you can bind with jquery

http://api.jquery.com/resize/



回答4:

use .data to store the initial size of the div inside your $.each function

$(this).data('height', $(this).height());
$(this).data('width', $(this).width());

you can later retrieve the old sizes within the resize callback

var old_height = $(this).data('height');
var old_width = $(this).data('width');

Hope this helps