Chcę obliczyć całkowitą "wysokość" elementu DIV, biorąc pod uwagę wpływ upadł marginesy z powodu elementów dziecka, to znaczy całkowitą przestrzeń, którą zajmuje element DIV w dokumencie. Ciężko mam trudności z najlepszym algorytmem / podejściem do tego.

Rozważmy na przykład element div z margin-top 10px i height 50px. Ten element DIV ma element <h2>, który ma margin-top 20px. div 's margin zostanie zapadnie i rzeczywista "height" tego {{x10}} będzie {{x11}}. Jednak przy użyciu metod jquery, jesteśmy w stanie tylko uzyskać {{x12}} {{x13}} bez rozważania jego {{x14}} lub rozważa jego {{x15}} piksel {{x16}}, który byłby Daj nam niewłaściwą wartość:

$(elem).outerHeight() // 50
$(elem).outerHeight(true) // 60

Aby zilustrować mój punkt, Oto jest JSFiddle stworzyłem z dwoma przykładami.

Moim najlepszym odgada w tej chwili, musimy w jakiś sposób iterować wszystkie dzieci w Div w jakiś sposób i obliczyć najwyższy górny i dolny margines. Według tego, co rozumiem z specyfikacji W3C, możemy pominąć tę iterację dla górnej {x0}} Jeśli docelowy div ma top-border-width lub top-padding. Ditto dla dna {x3}}.

Każda pomoc byłaby bardzo mile widziana. Dzięki!

EDYTUJ:

Jedno (brzydkie) rozwiązanie, które pomyślałem o owijaniu docelowego elementu div w innym div. Następnie szybko dodamy i usuwamy przezroczysty bordertop i BorderBottom do owijania DIV, pomiaru wysokości pomiędzy. Granice zmusi marginesu zawijającego Div, aby nie zapalić się z marginesami dzieci. Coś takiego:

var collapsedHeight = function( target ) {
   var $wrapper = $('<div />'),
     $target = $(target);

   $wrapper.insertAfter($target);
   $target.appendTo($wrapper);
   $wrapper.css({
       borderTop: '1px solid transparent',
       borderBottom: '1px solid transparent'
   });
   var result = $wrapper.outerHeight() - 2;
   $target.insertAfter($wrapper);
   $wrapper.remove();

   return result;
};

Wykonałem JSFiddle dla tego Oto.

4
vitorbal 27 październik 2011, 03:05

3 odpowiedzi

Najlepsza odpowiedź

Rozważ ten hack:

$( elem ).wrap( '<div style="border:1px solid transparent;"></div>' ).parent().height()

Powyższe wyrażenie zwraca 70, co chcesz, prawda?

Chodzi więc o to, aby owinąć element w Div, który ma przezroczysty zestaw granicy. Granica ta zapobiega marginesowi twojego elementu, aby zakłócać marginesy poprzedniego i następnego rodzeństwa.

Po uzyskaniu wartości wysokości można odwijać swój element ...

5
Šime Vidas 12 październik 2014, 20:46

W przypadku rozwiązania, które nie obejmuje manipulacji DOM, można osiągnąć ten sam efekt, dodając wyściółkę do elementu, który jest mierzony, a następnie wyjmując go później.

function getRealHeight(elementP) {
  var
    element = (elementP instanceof jQuery)? elementP : $(element),
    padTop = parseInt(element.css('paddingTop')),
    padBottom = parseInt(element.css('paddingBottom')),
    offset,
    height;

  if (padTop == 0 || padBottom == 0) {
    offset = 0;

    if (padTop == 0) {
      element.css('paddingTop', 1);
      offset += 1;
    }
    if (padBottom == 0) {
      element.css('paddingBottom', 1);
      offset += 1;
    }

    height = (element.outerHeight(true) - offset);

    if (padTop == 0) {
      element.css('paddingTop', '');
    }
    if (padBottom == 0) {
      element.css('paddingBottom', '');
    }
  } else {
    height = element.outerHeight(true);
  }
  return height;
}

Bonus tego rozwiązania; Możesz przesuwać nad głową owinięcia / rozpakowanie.

0
Robert Steward 26 czerwiec 2012, 15:39

Możesz zrobić go wtyczkę jQuery:

(function ($) {
    $.fn.extend({
        //plugin name - realHeight
        realHeight: function (options) {

            //Settings list and the default values
            var defaults = {};

            var options = $.extend(defaults, options);

            function getRealHeight(elementP) {
                var
                  element = (elementP instanceof jQuery) ? elementP : $(element),
                  padTop = parseInt(element.css('paddingTop')),
                  padBottom = parseInt(element.css('paddingBottom')),
                  offset,
                  height;

                if (padTop == 0 || padBottom == 0) {
                    offset = 0;

                    if (padTop == 0) {
                        element.css('paddingTop', 1);
                        offset += 1;
                    }
                    if (padBottom == 0) {
                        element.css('paddingBottom', 1);
                        offset += 1;
                    }

                    height = (element.outerHeight(true) - offset);

                    if (padTop == 0) {
                        element.css('paddingTop', '');
                    }
                    if (padBottom == 0) {
                        element.css('paddingBottom', '');
                    }
                } else {
                    height = element.outerHeight(true);
                }
                return height;
            }

            return getRealHeight($(this));
        }
    });
})(jQuery);
0
KurtJ 20 grudzień 2013, 23:59