Использование .outerWidth() и .outerHeight() с событием 'resize' для центрирования дочернего элемента в родительском

Я пытаюсь написать некоторый код JavaScript, который позволит мне центрировать дочерний элемент внутри его родителя, используя отступы. Затем с помощью той же функции пересчитать расстояние с помощью события «изменить размер». Прежде чем вы начнете спрашивать меня, почему я не делаю этого с помощью CSS, скажу, что этот код — лишь небольшая часть более крупного проекта. Я упростил код, так как остальная часть кода работает, и это только запутает тему.

Вычисление пространства. Это функция, которая вычисляет объем пространства, которое будет использоваться по обе стороны от дочернего элемента.

($outer.outerWidth() - $inner.outerWidth()) / 2;
($outer.outerHeight() - $inner.outerHeight()) / 2;

Проблема

Хотя мне удалось добиться желаемых результатов с запасом. Прокладка вызывает у меня проблемы.

  1. Кажется, что ширина внешнего элемента увеличивается при изменении размера
  2. Он не центрирует дочерний элемент идеально (похоже, есть смещение)
  3. Внутренний элемент схлопывается при изменении размера и становится невидимым.

Я понимаю, что могут быть некоторые основы относительно заполнения, которые вызывают мои проблемы, однако после многочисленных журналов консоли и наблюдения за возвращаемыми данными я все еще не могу понять проблему. Любое предложение будет очень приветствоваться. Может оказаться, что это вообще невыполнимо.

HTML

 <div id="demo" class="outer">
  <div class="inner">

  </div>
</div>

CSS

html {
  box-sizing: border-box;
}
*, *:before, *:after {
  box-sizing: inherit;
}

.outer {
  width:97%;
  height:400px;
  border:1px solid black;
  margin:20px;
}

.inner {
  width:40%;
  height:100px;
  background-color:grey;
}

JAVASCRIPT

var $outer = $(".outer");
var $inner = $(".inner");

var getSpace = function(axis)  {

  if (axis.toLowerCase() == "x") {

    return ($outer.outerWidth() - $inner.outerWidth()) / 2;

  } else if (axis.toLowerCase() == "y") {

    return ($outer.outerHeight() - $inner.outerHeight()) / 2;

  }  

}

var renderStyle = function(spacingType) {

  var lateralSpace = getSpace("x");  
  var verticalSpace = getSpace("y");

  var $element;

  if (spacingType == "padding") {
      $element = $outer;
  } else if (spacingType == "margin") {
      $element = $inner;
    }

  $.each(["top", "right", "bottom", "left"], function(index, direction) {
    if (direction == "top" || direction == "bottom") {
      $element.css(spacingType + "-" + direction, verticalSpace);
    }
    else if (direction == "right" || direction == "left") {
      $element.css(spacingType + "-" + direction, lateralSpace);
    }                                     
  });                
}; 

var renderInit = function() {

  $(document).ready(function() {

    renderStyle("padding");

  });

  $(window).on("resize", function() {

    renderStyle("padding");

  });

}

renderInit();

ПРИМЕР — ссылка


person Frederick M. Rogers    schedule 20.01.2017    source источник
comment
Объедините с ним .innerHeight и .innerWidth(), и все должно быть в порядке.   -  person eric.dummy    schedule 20.01.2017
comment
Извините, я не совсем понимаю, что вы имеете в виду, куда я должен включить это?   -  person Frederick M. Rogers    schedule 20.01.2017


Ответы (2)


Хотя я полностью не согласен с этим подходом к горизонтальному центрированию элемента, надеюсь, это поможет вам в вашем пути.

Скрипт: https://jsfiddle.net/0uxx2ujg/

JavaScript:

var outer = $('.outer'), inner = $('.inner');
function centreThatDiv(){ 
    var requiredPadding = outer.outerWidth() / 2 - (inner.outerWidth() / 2);
    console.log(requiredPadding);
    outer.css('padding', '0 ' + requiredPadding + 'px').css('width','auto');
}

$(document).ready(function(){
    // fire on page load
    centreThatDiv();
});

$(window).resize(function(){
    // fire on window resize
    centreThatDiv();
});

HTML:

<div class="outer">
    <div class="inner">Centre me!</div>
</div>

CSS:

.outer{ width:80%; height:300px; margin:10%; background: tomato; }
.inner{ width:60px; height:60px; background:white; }

В дополнение к тому, почему я не согласен с этим подходом - JavaScript не следует использовать для изложения вещей. Конечно, может быть, если это действительно нужно использовать; но для чего-то такого простого, как центрирование элемента, в этом нет необходимости. Браузеры сами обрабатывают изменение размера элементов CSS, поэтому, используя JS, вы создаете себе больше головной боли в дальнейшем.

Вот несколько примеров того, как вы можете добиться этого только в CSS:

выравнивание текста: центр и отображение: встроенный блок https://jsfiddle.net/0uxx2ujg/1/

позиция: абсолютная и левая: 50% https://jsfiddle.net/0uxx2ujg/2/ ( это можно использовать и для вертикального центрирования, что сложнее, чем горизонтальное)

person rorymorris89    schedule 20.01.2017
comment
Спасибо, я протестировал ваш код, и это продвинуло меня на один шаг вперед, но, как вы сказали (и как я понимаю), это оказывается большей головной болью, чем требуется для конечного результата. Моим первоначальным намерением было создать скрипт, который бы реагировал на изменение абсолютно позиционированных элементов. В какой-то момент я решил включить поля и отступы, и тут что-то пошло не так. - person Frederick M. Rogers; 20.01.2017

Вы можете создать новый класс CSS для настройки размера элементов в $window.onresize = function () { // добавьте свой код };

person Ranjeet KRISHNA Bhargava    schedule 20.01.2017
comment
Вы имеете в виду, что внутренний элемент рушится при изменении размера? - person Frederick M. Rogers; 20.01.2017
comment
Не давайте отступы, тогда он станет автоматически реагирующим - person Ranjeet KRISHNA Bhargava; 20.01.2017
comment
Ах я вижу. Спасибо. - person Frederick M. Rogers; 20.01.2017
comment
если есть разрешение, пожалуйста, оцените мой ответ :) - person Ranjeet KRISHNA Bhargava; 20.01.2017