【问题标题】:jquery event listen on position changedjquery事件监听位置改变
【发布时间】:2013-09-15 14:14:02
【问题描述】:

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

原因: 如果同级在对话框或表单中更改其尺寸(重新布局),则相对位置可能会更改。因此,对于交互式表单,这可以帮助使用,即父级的最大可用高度或宽度或类似的东西。

【问题讨论】:

  • 什么可以让你的元素位置改变?调整窗口大小?这个有一个事件
  • 不是你的插件不正确,但我只是想知道你会在什么情况下使用它?你会在事件处理程序中做什么?

标签: jquery css position


【解决方案1】:

我上面的代码变体将适用于多个对象并基于任何选择器,但它不适用于 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');
    }
});

});

【讨论】:

    【解决方案2】:

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

    查看下面的更新代码:

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

    【讨论】:

      【解决方案3】:

      此自定义 jquery 扩展通过计时器轮询侦听对象位置。我。没有计时器就无法解决这个问题,因为可以在根本不调用 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")});
      

      【讨论】:

      • 这真是矫枉过正
      • 顺便说一句:$(this[0]) 与 this 相同,指的是匹配的元素集。 this 已经是 jq 对象了
      • 是的,但你不能执行this.position(),所以我保持原样。
      • 这救了我。我已将其链接为我的问题的答案,在这里:stackoverflow.com/questions/33096188/…
      • 我使用&lt;script&gt; 标记将扩展的脚本添加到一个通用JS 代码中,当我使用onPositionChanged() 时没有任何反应。 .onPositionChanged() 显示为 undefined。请帮忙。
      猜你喜欢
      • 2015-12-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-07
      • 1970-01-01
      • 2010-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多