简体   繁体   English

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

[英]Using Javascript getBoundingClientRect to Snap Items to Grid

EDIT: I've simplified the code (below and in fiddle) down to the major problem needed to be solved in hope of creating more readability.编辑:我已经将代码(下面和小提琴)简化为需要解决的主要问题,希望能提高可读性。

I've implemented Bader's solution for correctly using getBoundingClientRect value and using document.querySelector for getting both the class name and the html tag needed for the function.我已经实现了 Bader 的解决方案,以正确使用getBoundingClientRect值并使用document.querySelector来获取函数所需的类名和html标记。 I'd now like to move on to the last five lines of the code beginning with var = style .我现在想转到以var = style开头的代码的最后五行。

I've now corrected the math for the final two variables.我现在已经更正了最后两个变量的数学。

→ I'm trying to achieve creating a snapping function for use alongside Plumber , a baseline-grid Sass plugin. → 我正在尝试创建一个与Plumber一起使用的捕捉功能,这是一个基线网格 Sass 插件。

Basically, I have a vertically centered flex item that needs to -- instead of being perfectly centered -- snap in an upward direction to the closest grid line.基本上,我有一个垂直居中的 flex 项目需要——而不是完全居中——向上对齐到最近的网格线。 This will allow me to have a consistent vertical rhythm between slides in a custom mobile-based experience.这将使我在基于移动的自定义体验中的幻灯片之间具有一致的垂直节奏。

I'm using getBoundingClientRect to calculate the distance between the bottom of an object, and the top of the window.我正在使用getBoundingClientRect来计算对象底部和窗口顶部之间的距离。

Then I use Math.floor to round down to the nearest multiple of my rem value.然后我使用Math.floor向下舍入到我的 rem 值的最接近的倍数。

Then I use this new value to create a CSS bottom margin on the flex-centered container for the alignment fix.然后我使用这个新值在以 flex 为中心的容器上创建一个 CSS 底部边距以进行对齐修复。

(Then to finish, I'd like to have this function load on $(document).ready and on window resize.) (然后完成,我想在$(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.这是小提琴。

I most likely have a syntax problem here, and would greatly appreciate help.我很可能在这里有语法问题,非常感谢帮助。

Thanks!谢谢!

Here are some errors / corrections.这里有一些错误/更正。

GetBoundingClientRect() is a JS function, not jQuery, so it must be used on a javascript element, not a jquery selector. GetBoundingClientRect() 是一个 JS 函数,而不是 jQuery,因此它必须用于 javascript 元素,而不是 jquery 选择器。 Using the [0] accessor on the jquery selector (if that's how you want to get it) will give you the JS element.在 jquery 选择器上使用 [0] 访问器(如果这是您想要的方式)将为您提供 JS 元素。

Also noticed that you were trying to select the "html" tag by id, but it doesn't have any Id.还注意到您试图通过 id 选择“html”标签,但它没有任何 Id。 Changed it to getElementsByTagName.将其更改为 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');

Edit: Regarding your edit, if you need to call the javascript to recompute on window resize, you may want to try something like this.编辑:关于你的编辑,如果你需要调用 javascript 来重新计算窗口大小,你可能想尝试这样的事情。 I'm not sure if it achieves what you want fully (I don't completely understand your 'snapping' requirements, but this will at least call the code again. You may still have to edit the code in the snapFunction if it doesn't suit your needs.我不确定它是否完全达到你想要的(我不完全理解你的“捕捉”要求,但这至少会再次调用代码。如果没有,你可能仍然需要在 snapFunction 中编辑代码“满足您的需求。

I added some console logs that might help you check your math as it seemed a bit problematic to me, though I was unsure how to fix it because I don't understand your goal.我添加了一些控制台日志,可以帮助你检查你的数学,因为它对我来说似乎有点问题,但我不确定如何解决它,因为我不明白你的目标。

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

I did notice that the value of your bottomNew variable was logging as "NaN" (Not a Number) so I think something is going wrong there.我确实注意到您的 bottomNew 变量的值记录为“NaN”(不是数字),所以我认为那里出了问题。

I think you're getting a font-size like "36px" instead of just "36".我认为你得到的字体大小是“36px”,而不仅仅是“36”。 Maybe you could try也许你可以试试

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

The 10 in that parseInt function is just specifying we want to use base 10 numbers. parseInt 函数中的 10 只是指定我们要使用基数为 10 的数字。

I hope this will help you我希望这能帮到您

Here's the edited fiddle这是编辑好的小提琴

jsfiddle.net/ztf64mwg/82/ jsfiddle.net/ztf64mwg/82/

I just edited some variables and fixed some of the errors我刚刚编辑了一些变量并修复了一些错误

I ended up jumping on HackHands and, with help, came up with a great working solution.我最终选择了 HackHands,并在帮助下提出了一个很好的工作解决方案。

This will snap any vertically flex-centered object to a grid with its size set as 1rem.这会将任何垂直 flex 居中的对象捕捉到一个网格,其大小设置为 1rem。

All you need to do is give the object that is being measured for distance the id attribute "measure", making sure that this object is aligned correctly with a 1rem grid from the top of its own container.您需要做的就是为正在测量距离的对象提供 id 属性“measure”,确保该对象与其自身容器顶部的 1rem 网格正确对齐。

Then give the parent container (or any container higher in the DOM tree) that you'd like to snap to the grid the class of "snap".然后为您想要捕捉到网格的父容器(或 DOM 树中更高的任何容器)指定“捕捉”类。

If anyone ever finds a use for this and needs further explanation, just let me know.如果有人发现它的用途并需要进一步解释,请告诉我。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM