使用 Javascript getBoundingClientRect 将项目对齐到网格

Using Javascript getBoundingClientRect to Snap Items to Grid

编辑:我已将代码(在 fiddle 下方和 fiddle 中)简化为需要解决的主要问题,以期提高可读性。

我已经实现了正确使用 getBoundingClientRect 值并使用 document.querySelector 获取 class 名称和 html 标签的 Bader 解决方案功能所需。我现在想转到以 var = style.

开头的代码的最后五行

我现在已经更正了最后两个变量的数学。

→ 我正在尝试实现创建一个捕捉功能以与 Plumber 一起使用,这是一个基线网格 Sass 插件。

基本上,我有一个垂直居中的弹性项目需要——而不是完全居中——向上捕捉到最近的网格线。这将使我能够在基于移动设备的自定义体验中在幻灯片之间保持一致的垂直节奏。

我正在使用 getBoundingClientRect 计算物体底部与 window 顶部之间的距离。

然后我使用 Math.floor 向下舍入到最接近我的 rem 值的倍数。

然后我使用这个新值在 flex-centered 容器上创建一个 CSS 底部边距以进行对齐修复。

(最后,我想在 $(document).ready 上 window 调整大小时加载此函数。)

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'");

}

Here's the fiddle.

我很可能在这里遇到语法问题,非常感谢帮助。

谢谢!

希望对您有所帮助

这是编辑后的 ​​fiddle

jsfiddle.net/ztf64mwg/82/

我刚刚编辑了一些变量并修复了一些错误

这里有一些错误/更正。

GetBoundingClientRect() 是一个 JS 函数,不是 jQuery,所以它必须用在 javascript 元素上,而不是 jquery select 或者。在 jquery select 上使用 [0] 访问器或(如果您希望这样获得)将为您提供 JS 元素。

还注意到您试图通过 ID select "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 重新计算 window 调整大小,您可能想尝试这样的事情。我不确定它是否完全实现了你想要的(我不完全理解你的 'snapping' 要求,但这至少会再次调用代码。如果它,你可能仍然需要在 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);

parseInt 函数中的 10 只是指定我们要使用以 10 为基数的数字。

我最终跳上了 HackHands,并在帮助下提出了一个很好的工作解决方案。

这会将任何垂直弯曲居中的对象对齐到一个网格,其大小设置为 1rem。

您需要做的就是为正在测量距离的对象提供 id 属性 "measure",确保该对象与其容器顶部的 1rem 网格正确对齐。

然后将您想要捕捉到网格的父容器(或 DOM 树中更高层的任何容器)赋予 "snap" 的 class。

如果有人发现它的用途并需要进一步解释,请告诉我。

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);
});