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

时间:2018-08-28 19:01:43

标签: javascript window-resize gridlines getboundingclientrect snapping

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

我已经实现了Bader解决方案,可以正确使用getBoundingClientRect值,并使用document.querySelector获取类名和该功能所需的html标记。我现在想进入以var = style开头的代码的最后五行。

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

→我正试图创建一个与基线网格Sass插件Plumber一起使用的捕捉功能。

基本上,我有一个垂直居中的flex项目,它需要-而不是完美居中-向上对齐到最近的网格线。这将使我能够在基于移动的自定义体验中在幻灯片之间保持一致的垂直节奏。

我正在使用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'");

}

Here's the fiddle.

我很可能在这里遇到语法问题,将不胜感激。

谢谢!

3 个答案:

答案 0 :(得分:1)

这是一些错误/更正。

GetBoundingClientRect()是JS函数,而不是jQuery函数,因此必须在javascript元素而不是jquery选择器上使用。在jquery选择器上使用[0]访问器(如果您要这样做)将为您提供JS元素。

还注意到您试图通过ID选择“ 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);

parseInt函数中的10仅表示我们要使用以10为底的数字。

答案 1 :(得分:0)

希望这对您有帮助

这是编辑过的小提琴

jsfiddle.net/ztf64mwg/82 /

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

答案 2 :(得分:0)

我最终跳上了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);
});