Использование JavaScript getBoundingClientRect для привязки элементов к сетке - PullRequest
0 голосов
/ 28 августа 2018

РЕДАКТИРОВАТЬ: я упростил код (ниже и в скрипте) до основной проблемы, которую необходимо решить в надежде на повышение читабельности.

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

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

→ Я пытаюсь создать функцию привязки для использования вместе с Сантехником , плагином 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'");

}

Вот скрипка.

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

Спасибо!

Ответы [ 3 ]

0 голосов
/ 28 августа 2018

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

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

Также заметил, что вы пытались выбрать тег "html" по id, но у него нет идентификатора. Изменил его на 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.

0 голосов
/ 15 сентября 2018

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

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

Все, что вам нужно сделать, это дать объекту, который измеряется для расстояния, атрибут id «мера», убедившись, что этот объект правильно выровнен с сеткой 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);
});
0 голосов
/ 28 августа 2018

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

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

jsfiddle.net / ztf64mwg / 82 /

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

...