jquery事件听取位置的变化

时间:2013-09-11 13:52:42

标签: jquery css position

我需要倾听元素的相对位置。这对于动态布局问题特别有用。没有选项可以监听偶数position()或offset()属性的CSS样式。

为什么: 如果兄弟姐妹在对话框或表单中更改其维度(重新布局),则相对位置可能会发生变化。因此,对于交互式表单,这可以帮助使用,即父级的最大可用高度或宽度或类似的东西。

3 个答案:

答案 0 :(得分:10)

此自定义jquery扩展通过计时器轮询侦听对象位置。 I.m.o.没有计时器就没有办法解决这个问题,因为在没有调用jquery的情况下可以改变位置(即重新布局同级元素)。此解决方案监视元素.position()和.offset()值。可以很容易地改进它来观看.css()样式或jQuery事件未涵盖的其他内容。

jQuery扩展程序:

jQuery.fn.onPositionChanged = function (trigger, millis) {
    if (millis == null) millis = 100;
    var o = $(this[0]); // our jquery object
    if (o.length < 1) return o;

    var lastPos = null;
    var lastOff = null;
    setInterval(function () {
        if (o == null || o.length < 1) return o; // abort if element is non existend eny more
        if (lastPos == null) lastPos = o.position();
        if (lastOff == null) lastOff = o.offset();
        var newPos = o.position();
        var newOff = o.offset();
        if (lastPos.top != newPos.top || lastPos.left != newPos.left) {
            $(this).trigger('onPositionChanged', { lastPos: lastPos, newPos: newPos });
            if (typeof (trigger) == "function") trigger(lastPos, newPos);
            lastPos = o.position();
        }
        if (lastOff.top != newOff.top || lastOff.left != newOff.left) {
            $(this).trigger('onOffsetChanged', { lastOff: lastOff, newOff: newOff});
            if (typeof (trigger) == "function") trigger(lastOff, newOff);
            lastOff= o.offset();
        }
    }, millis);

    return o;
};

通过以下方式调用:

$("#<SOME_ID>").onPositionChanged(function(){alert("foobar")});

答案 1 :(得分:0)

这是我的解决方案,它基于willsteel解决方案。我必须监控widthoffsetWidth的更改。即使元素因任何原因变得不可见/可见,这也会触发该功能。

请参阅以下更新代码:

jQuery.fn.onPositionChanged = function (trigger, millis) {
    if (millis == null) millis = 100;
    var o = $(this[0]); // our jquery object
    if (o.length < 1) return o;
    var lastPos = null;
    var lastOff = null;
    var lastWidth = null;
    var lastOffWidth = null;
    setInterval(function () {
        if (o == null || o.length < 1) return o; // abort if element is non existend eny more
        if (lastPos == null) lastPos = o.position();
        if (lastOff == null) lastOff = o.offset();
        if (lastWidth == null) lastWidth = o.width();
        if (lastOffWidth == null) lastOffWidth = o[0].offsetWidth;
        var newPos = o.position();
        var newOff = o.offset();
        var newWidth = o.width();
        var newOffWidth = o[0].offsetWidth;
        if (lastPos.top != newPos.top || lastPos.left != newPos.left) {
            $(this).trigger('onPositionChanged', { lastPos: lastPos, newPos: newPos });
            if (typeof (trigger) == "function") trigger(lastPos, newPos);
            lastPos = o.position();
        }
        if (lastOff.top != newOff.top || lastOff.left != newOff.left) {
            $(this).trigger('onPositionChanged', { lastOff: lastOff, newOff: newOff});
            if (typeof (trigger) == "function") trigger(lastOff, newOff);
            lastOff= o.offset();
        }
        if (lastWidth != newWidth) {
            $(this).trigger('onPositionChanged', { lastWidth: lastWidth, newWidth: newWidth});
            if (typeof (trigger) == "function") trigger(lastWidth, newWidth);
            lastWidth= o.width();
        }
        if (lastOffWidth != newOffWidth) {
            $(this).trigger('onPositionChanged', { lastOffWidth: lastOffWidth, newOffWidth: newOffWidth});
            if (typeof (trigger) == "function") trigger(lastOffWidth, newOffWidth);
            lastWidth= o.width();
        }
    }, millis);
    return o;
};

答案 2 :(得分:0)

我上面的代码变体可以在多个对象上并且基于任何选择器运行,但不能与jQuery完全配合。

var onPositionChanged = function (selector,trigger, millis) {
if (millis == null) millis = 200;
setInterval(function(){
    var o_s = jQuery(selector); // our jquery object
    if (o_s.length < 1) return o_s;

    for(var i = 0; i<o_s.length; i++)
    {
        var o = o_s.eq(i);

        var lastPos = jQuery(o).attr("lastPos");
        var lastOff = jQuery(o).attr("lastOff");
        lastPos = ((lastPos == "" || lastPos == undefined) ? null : JSON.parse(lastPos));
        lastOff = ((lastOff == "" || lastOff == undefined) ? null : JSON.parse(lastOff));
        setTimeout(function (o) {
            if (o == null || o.length < 1) return o; // abort if element is non existend eny more
            if (lastPos == null) lastPos = o.position();
            if (lastOff == null) lastOff = o.offset();
            var newPos = o.position();
            var newOff = o.offset();
            if (lastPos.top != newPos.top || lastPos.left != newPos.left) {
                jQuery(this).trigger('onPositionChanged', { lastPos: lastPos, newPos: newPos });
                if (typeof (trigger) == "function") trigger(o,lastPos, newPos);
                lastPos = o.position();
                jQuery(o).attr("lastPos",JSON.stringify(lastPos));
            }
            if (lastOff.top != newOff.top || lastOff.left != newOff.left) {
                jQuery(this).trigger('onOffsetChanged', { lastOff: lastOff, newOff: newOff});
                if (typeof (trigger) == "function") trigger(o,lastOff, newOff);
                lastOff= o.offset();
                jQuery(o).attr("lastOff",JSON.stringify(lastOff));
            }
        }, millis,o);
    }
},millis);

};

用法示例:

jQuery(document).ready(function(){
onPositionChanged(".grid-item:not(.d-none)",function(object){

    var left_percentage = parseInt(jQuery(object).position().left / jQuery(object).parent().width() * 100);
    var parent_width = jQuery(object).parent().width();

    var percentage_of_parent = parseInt(jQuery(object).width() / parent_width * 100);

    if(left_percentage > 74 && percentage_of_parent >= 25
    || left_percentage > 66 && percentage_of_parent >= 33
    || left_percentage > 49 && percentage_of_parent >= 50)
    {
        jQuery(object).find(".card").css("margin-right","0px");
        jQuery(object).parent().masonry('layout');
    }
    if(left_percentage < 1)
    {
        jQuery(object).find(".card").css("margin-left","0px");
        jQuery(object).parent().masonry('layout');
    }
});

});

相关问题