【问题标题】:How to get a element position (left or right) relative to the screen?如何获取相对于屏幕的元素位置(左或右)?
【发布时间】:2020-06-08 20:31:09
【问题描述】:

我在我的网页上使用了砖石类型的布局,我需要将出现在屏幕右侧的每个元素的样式设置为与其他元素不同的样式。这是我用于masonry 的参考。起初,我需要右侧元素向右浮动并具有不同的边距设置,并且由于我的项目中的高度变化很大,有时向左或向右移动的元素每次都不会以相同的方式交替。 我正在使用引导程序 3.3.7 和 JQuery 3.4.1。 这是我的代码:

function checkContainer() {
    if ($(window).width() > 1200) {
        return 585;
    }
    else if ($(window).width() > 992) {
        return 485;
    }
    return $('.container').width();
}

var minColWidth = checkContainer();
var roots;

function onLoad() {
    var rootElements = document.getElementsByClassName('masonry-root');
    roots = Array.prototype.map.call(rootElements, function (rootElement) {
        var cellElements = rootElement.getElementsByClassName('masonry-cell');
        var cells = Array.prototype.map.call(cellElements, function (cellElement) {
            var style = getComputedStyle(cellElement);
            return {
                'element': cellElement,
                'outerHeight': parseInt(style.marginTop) + cellElement.offsetHeight + parseInt(style.marginBottom)
            };
        });
        return {
            'element': rootElement,
            'noOfColumns': 0,
            'cells': cells
        };
    });

    // do the first layout
    onResize();
}

function onResize() {
    for (let root of roots) {

        // only layout when the number of columns has changed
        var newNoOfColumns = Math.floor(root.element.offsetWidth / minColWidth);
        if (newNoOfColumns != root.noOfColumns) {

            // initialize
            root.noOfColumns = newNoOfColumns;
            var columns = Array.from(new Array(root.noOfColumns)).map(function (column) {
                return {
                    'cells': new Array(),
                    'outerHeight': 0
                };
            });

            // divide...
            for (let cell of root.cells) {
                var minOuterHeight = Math.min(...columns.map(function (column) {
                    return column.outerHeight;
                }));
                var column = columns.find(function (column) {
                    return column.outerHeight == minOuterHeight;
                });
                column.cells.push(cell);
                column.outerHeight += cell.outerHeight;
            }

            // calculate masonry height
            var masonryHeight = Math.max(...columns.map(function (column) {
                return column.outerHeight;
            }));

            // ...and conquer
            var order = 0;
            for (let column of columns) {
                for (let cell of column.cells) {
                    cell.element.style.order = order++;
                    // set the cell's flex-basis to 0
                    cell.element.style.flexBasis = 0;
                }
                // set flex-basis of the last cell to fill the
                // leftover space at the bottom of the column
                // to prevent the first cell of the next column
                // to be rendered at the bottom of this column
                column.cells[column.cells.length - 1].element.style.flexBasis = column.cells[column.cells.length - 1].element.offsetHeight + masonryHeight - column.outerHeight - 1 + 'px';
            }

            // set the masonry height to trigger
            // re-rendering of all cells over columns
            // one pixel more than the tallest column
            root.element.style.maxHeight = masonryHeight + 1 + 'px';

            console.log(columns.map(function (column) {
                return column.outerHeight;
            }));
            console.log(root.element.style.maxHeight);
        }
    }
}

// subscribe to load and resize events
window.addEventListener('load', onLoad);
window.addEventListener('resize', onResize);
.masonry-root {
    display: flex;
    flex-direction: column;
    flex-wrap: wrap;
}
.masonry-root .masonry-cell {
    flex: 1;
    margin: 4px;
}
.masonry-root .masonry-cell .masonry-item {
    height: auto;
}
.feed-content {
    width: 450px;
    position: relative;
    height: auto;
}
<div class="masonry-root">
    <div class="masonry-cell">
        <div class="masonry-item">
            <div class="feed-content">
            <!-- html content like images and text -->
            </div>
        </div>
    </div>
    <div class="masonry-cell">
        <div class="masonry-item">
            <div class="feed-content">
            <!-- html content like images and text -->
            </div>
        </div>
    </div>
</div>

我尝试使用 CSS 获取元素的左侧位置,但没有成功。使用 jquery .position() 或 offsetLeft() 时也会发生同样的情况。

【问题讨论】:

    标签: html jquery css masonry


    【解决方案1】:

    我在这里尝试了一些东西,发现了一些有用的东西。

    // puting all the elements that I'm going to use in a list 
    var feeds = document.querySelectorAll('.feed-content');
    // since I know that, im a 2 columns grid the first element 
    // will alaways be on the right side off the screen I get
    // his x position
    var dir = feeds[0].getBoundingClientRect().x;
    
    for (var i = 0; i < feeds.length; i++) {
        feeds[i].classList.remove('right');
    
        if (feeds[i].getBoundingClientRect().x != dir) {
            // adding the cllas if the element doesn't 
            // have that x position
            feeds[i].classList.add('right');
        }
    }
    

    一些建议,当我使用用于该问题的插件时,有时此功能存在一个错误,该错误使页面上的所有元素都具有相同的 x 值,即使它们显然不一样。即使这部分代码放在布局的脚本功能之后,也会受到一些干扰。因此,只需延迟函数执行即可解决问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-14
      • 1970-01-01
      • 1970-01-01
      • 2015-04-08
      • 1970-01-01
      相关资源
      最近更新 更多