Использование Javascript getBoundingClientRect для привязки элементов к сетке

EDIT: я упростил код (ниже и в скрипке) до основной проблемы, которую необходимо было решить, в надежде сделать его более читабельным.

Я реализовал решение Бадера для правильного использования значения getBoundingClientRect и использования document.querySelector для получения имени класса и тега html, необходимых для функции. Теперь я хотел бы перейти к последним пяти строкам кода, начинающимся с var = style.

Теперь я исправил математику для последних двух переменных.

→ Я пытаюсь создать функцию привязки для использования вместе с Plumber, Sass-плагин сетки.

По сути, у меня есть вертикально центрированный гибкий элемент, который должен - вместо идеального центрирования - привязываться вверх к ближайшей линии сетки. Это позволит мне иметь постоянный вертикальный ритм между слайдами в пользовательском мобильном интерфейсе.

Я использую getBoundingClientRect для расчета расстояния между нижней частью объекта и верхней частью окна.

Затем я использую Math.floor для округления до ближайшего кратного моего значения rem.

Затем я использую это новое значение, чтобы создать нижнее поле CSS для контейнера с гибким центром для исправления выравнивания.

(Затем, чтобы закончить, я бы хотел, чтобы эта функция загружалась на $(document).ready и при изменении размера окна.)

function() {

  var box = document.querySelector('.box-1');
  var rect = box.getBoundingClientRect();
  var bottomOrig = rect.bottom;

  var htmlRoot = document.querySelector('html');
  var style = getComputedStyle(htmlRoot);
  var remValue = style.getPropertyValue('font-size');

  var bottomNew = Math.floor(bottomOrig / remValue) * remValue;
  var fix = bottomOrig - bottomNew;

  $('.container-2').css("margin-bottom", "fix + 'px'");

}

Вот скрипка.

У меня, скорее всего, проблема с синтаксисом, и я был бы очень признателен за помощь.

Спасибо!


person Brendan    schedule 28.08.2018    source источник
comment
Я обновил свой ответ некоторыми дополнительными советами, которые могут вам помочь. Если вам нужна дополнительная помощь, мне, возможно, придется попросить вас уточнить, что вы имеете в виду под действием привязки, которое вы описываете.   -  person Neely    schedule 10.09.2018


Ответы (3)


Вот некоторые ошибки/исправления.

GetBoundingClientRect() — это функция JS, а не jQuery, поэтому ее следует использовать для элемента javascript, а не для селектора jquery. Использование средства доступа [0] в селекторе jquery (если вы хотите его получить) даст вам элемент JS.

Также заметил, что вы пытались выбрать тег «html» по идентификатору, но у него нет никакого идентификатора. Изменил его на getElementsByTagName.

var offsetYOrig = $('.box-1')[0].getBoundingClientRect().bottom;
// or, without jQuery:
// var offsetYOrig = document.getElementsByClassName('box-1')[0].getBoundingClientRect().bottom;

var html = document.getElementsByTagName("html")[0];
var style = window.getComputedStyle(html);
var remValue = style.getPropertyValue('font-size');

Изменить: что касается вашего редактирования, если вам нужно вызвать javascript для пересчета при изменении размера окна, вы можете попробовать что-то вроде этого. Я не уверен, что он полностью достигает того, что вы хотите (я не совсем понимаю ваши требования к «привязке», но это, по крайней мере, снова вызовет код. Возможно, вам все равно придется отредактировать код в snapFunction, если это не так) соответствует вашим потребностям.

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

function snapFunction ()
{
    var box = document.querySelector('.box-1');
    var rect = box.getBoundingClientRect();
    var bottomOrig = rect.bottom;

    var htmlRoot = document.querySelector('html');
    var style = getComputedStyle(htmlRoot);
    var remValue = style.getPropertyValue('font-size');

    var bottomNew = Math.floor(bottomOrig / remValue) * remValue;
    var fix = bottomOrig - bottomNew;

    // open your browser console and check the value of these to check your math and what values you're getting
    console.log("bottomOrig: " + bottomOrig )
    console.log("remValue: " + remValue)
    console.log("bottomNew: " + bottomNew )

    // note: no quotes around your variable name fix here
    $('.container-2').css("margin-bottom", fix + "px");
};

// call on load
(function() {
    snapFunction();
})();

// call on resize
$( window ).resize(function() {
    snapFunction();
});

Я заметил, что значение вашей переменной bottomNew регистрируется как «NaN» (не число), поэтому я думаю, что здесь что-то идет не так.

Я думаю, вы получаете размер шрифта, например, «36px», а не просто «36». Может быть, вы могли бы попробовать

var remValue = parseInt(style.getPropertyValue('font-size'), 10);

10 в этой функции parseInt просто указывает, что мы хотим использовать числа с основанием 10.

person Neely    schedule 28.08.2018

Я надеюсь, что это поможет вам

Вот отредактированная скрипка

jsfiddle.net/ztf64mwg/82/

Я только что отредактировал некоторые переменные и исправил некоторые ошибки

person Bader H.    schedule 28.08.2018
comment
Я внес изменения в скрипку и код выше с помощью предложенных вами правок, но мне все еще не удалось создать желаемое изменение стиля CSS для .container-2. Я также попытался удалить вторую часть кода с помощью прослушивателя событий и изменил значение «При загрузке» для типа загрузки Fiddle, но безуспешно. Все равно хотелось бы помощи! Это будет прорывом для меня, если это будет достигнуто. - person Brendan; 29.08.2018

В итоге я ухватился за HackHands и с моей помощью нашел отличное рабочее решение.

Это привяжет любой объект с вертикальным гибким центром к сетке с размером, установленным как 1rem.

Все, что вам нужно сделать, это присвоить объекту, расстояние которого измеряется, атрибут id «measure», убедившись, что этот объект правильно выровнен с сеткой 1rem от верхней части своего собственного контейнера.

Затем присвойте родительскому контейнеру (или любому контейнеру выше в дереве DOM), который вы хотите привязать к сетке, класс «привязка».

Если кто-нибудь когда-нибудь найдет для этого применение и нуждается в дополнительных пояснениях, просто дайте мне знать.

function snap(object){  

    var rect = object.getBoundingClientRect();
    var bottomOrig = rect.bottom;

    var htmlRoot = document.querySelector('html');
    var style = getComputedStyle(htmlRoot);
    var remValue = parseInt(style.getPropertyValue('font-size'));

    var bottomNew = Math.floor(bottomOrig / remValue) * remValue;

    var topFixPositive = bottomNew - bottomOrig;
    var topFixNegative = -Math.abs(topFixPositive);

    $(object).closest('.snap').css("margin-top", topFixNegative);

}


function snapClear(object){  

    $(object).closest('.snap').css("margin-top", "0");

}


var measureHome = document.querySelector('#measure');

snap(measureHome);

$(window).on('resize', function() {
    snapClear(measureHome);
    snap(measureHome);
});
person Brendan    schedule 15.09.2018