javascript - 将函数/样式应用于每个 each() 迭代

标签 javascript jquery html css

所以我得到了一个 for each 循环,循环遍历每个 '.related__item' 并检查它是否包含图像(使用 '.related__item-image')。如果为 true,则使用正确的函数计算每个“.related__item”的文本高度并触发 dotdodot 函数。

我的问题是,它正确地循环遍历每个“.related__item”并根据图像在 console.logs 中记录正确的 true 或 false。但出于某种原因,它为 ALL 相关元素提供了相同的高度。所以我相信 if 语句中的某处出了问题,但我无法弄清楚到底是什么。

我怎样才能做到在每次迭代时,循环给出真或假,为所有元素设置正确的高度然后继续下一步并做同样的事情。我是否正在考虑制作一个 each in 和 each?

Jfiddle:https://jsfiddle.net/bwbeLbnv/

JS:

  var self = this;
  var textBlock = $('.text', self);
  var titleHeight = $('.related__item-title', self).outerHeight(true);
  var containerHeight = $('.related__item', self).outerHeight();
  var imageHeight = $('.related__item-image', self).outerHeight();
  var relatedItems = $(".related-magazines .related__item");

  var calculate_with_image = function() {
    var totalHeight = titleHeight + imageHeight;
    textBlock.css({height: containerHeight - totalHeight});
    textBlock.trigger("update.dot");
  };

  var calculate_without_image = function() {
    textBlock.css({height: containerHeight - titleHeight});
    textBlock.trigger("update.dot");
  };


  var related_resize = function() {
    for ( var i = 0; i < relatedItems.length; i++ ) {
      var element =  relatedItems.eq(i);
      var hasImage = element.find('.related__item-image', self).length === 1;
      console.log($(element).text());
      console.log(hasImage);

      if (hasImage === true) {
        calculate_with_image();
        console.log('IMAGE');

      } else if (hasImage === false) {
        calculate_without_image();
        console.log('TEXT');
      }
    }
  };

  related_resize();

HTML:(剥离)

<div class="related-magazines"> <!-- container -->   
 <div class="content"> <!-- inner container -->

    <div>
      <h3>Related pages</h3>
    </div>

    <!-- first column group -->
    <div class="field-name-sections first"> 

    <!-- related item w/ image -->
      <div class="related__item hni-grid first">
          <div class="related__item-section">
            <a href="link/url">
              <div class="related__item-image">
                <img class="item" src="img/url">
              </div>
              <div class="body">
                <div class="related__item-title">
                  <h4>
                    This is a title
                  </h4>
                  <h5 class="related-magazine-title">
                    This is a subtitle
                  </h5>
                </div>
                <div class="text">
                  This is a long description. etc etc etc.
                </div>
              </div>
            </a>
          </div>
        </div>

        <!-- related item w/o image -->
        <div class="related__item last">
          <div class="related__item-section">
            <a href="link/url">
              <div class="body">
                <div class="related__item-title">
                  <h4>
                    This is a title
                  </h4>
                  <h5 class="related-magazine-title">
                    This is a subtitle
                  </h5>
                </div>
                <div class="text" data-padding-bottom="1">
                  This is a long description. etc etc etc.
                </div>
              </div>
            </a>
          </div>
        </div> 

    </div>

    <!-- second column group -->
    <div class="field-name-sections last">

      <!-- related item w/ image -->
      <div class="related__item">
        <div class="related__item-section">
          <a href="link/url">
            <div class="related__item-image">
              <img class="item" src="image/url">
            </div>
            <div class="body">
              <div class="related__item-title">
                <h4>
                  This is a title
                </h4>
                <h5 class="related-magazine-title">
                  This is a subtitle 
                </h5>
              </div>
              <div class="text">
                This is a long description. etc etc etc.
              </div>
            </div>
          </a>
        </div>
      </div>

      <!-- related item w/ image -->
      <div class="related__item">
        <div class="related__item-section">
          <a href="link/url">
            <div class="related__item-image">
              <img class="item" src="image/url">
            </div>
            <div class="body">
              <div class="related__item-title">
                <h4>
                  This is a title
                </h4>
                <h5 class="related-magazine-title">
                  This is a subtitle
                </h5>
              </div>
              <div class="text">
                This is a long description. etc etc etc.
              </div>
            </div>
          </a>
        </div>
      </div>

    </div>

  </div> <!-- end content --> </div> <!-- end related magazines -->

最佳答案

Alright, I've stripped the whole HTML structure to give you an idea to how it looks like.

谢谢,这真的很有帮助。您的代码中的问题是 calculate_with_image()calculate_without_image() 根本不考虑当前的 .related__item。这些函数中使用的所有值都是在循环之前计算的。这就是它们每次迭代返回相同值的原因。

评论: 大多数 jQuery 方法计算/返回一个值并且不将某些东西应用到 jQuery 选择中的节点,从第一个 DOM 节点计算这个值选择。因此 $('.related__item-image').outerHeight() 首先从文档中获取所有 .related__item-image 节点,但只返回 outerHeight( ) 第一个。

这是您的代码中出错的一件事。

我不确定这是否是您的意图,但我认为您尝试先获取所有相关节点,然后遍历这些列表(我的意思是这部分:var textBlock = $('.text' ) 和以下几行)。如果这些列表之间存在 1:1 的关系,则很好(不好,但还可以)。否则,你会一团糟;因此,如果可能的话,通常会避免使用这种方法。很容易出现问题。或者可能会改变然后出错。
如果我在这里误解了你的意图,没关系。

我无法测试以下代码是否会产生预期的结果,因为它取决于您的 CSS,但我认为它应该可以完成工作:(否则,您会告诉我哪里出了问题)

$(".related-magazines .related__item").each(function(){
    //comment: jQuery iterators provide the current Element as `this`
    var $this = $(this);    //the current item wrapped in a jQuery-object.
    var containerHeight = $this.outerHeight();  //the height of this particular item

    //fetch the related image, and get it's outerHeight
    //returns `null` if no image is found, wich then will be replaced with a 0
    var imageHeight = $this.find('.related__item-image').outerHeight() || 0;
    //same for the related title:
    var titleHeight = $this.find('.related__item-title').outerHeight(true) || 0;    
    //btw, this would also work:
    //var imageHeight = $('.related__item-image', this).outerHeight() || 0;
    //and I mean `this` and not your cached `self`, but not your combination of find and self.

    console.log($this.text());
    console.log(imageHeight > 0);

    //inlined `calculate_with_image()` and `calculate_without_image()` because they are short, 
    //and almost identical, and need access to the same Nodes that are used 
    //comment: jQuery allows method-chaining
    $this.find('.text') //get the textBlock
        .height( containerHeight - (titleHeight + imageHeight) )    //set it's height
        .trigger("update.dot");     //and trigger

    console.log(imageHeight > 0? "IMAGE": "TEXT");
});

在测试是否有图像时,有人可能会争辩说 imageHeight > 0 是不准确的。因为可能有一张图像,但高度为 0。嗯,是的,但对于这个计算来说,这不会有任何区别。

Image 可能有问题,导致高度为 0。可能它尚未加载,或者它的父项之一是 display:none,但处理该问题将是不同 SO-Question 的主题。

关于javascript - 将函数/样式应用于每个 each() 迭代,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38402610/

相关文章:

javascript - 如何使用ajax加载文本框

javascript - jQuery向文本添加数字

html - 背景覆盖背景大小

javascript - 在表单验证上显示模态

javascript - 使用 MultiDatesPicker 禁用除特定日期列表之外的所有日期

javascript - 如何在悬停到任何链接时显示/隐藏 div

javascript - 如何传递 id 属性而不是值

html - 如何使用CSS设置拉伸(stretch)背景图片

javascript - 如何使用 d3.js 创建像 StackOverflow 信誉图这样的图表?

javascript - 使用多个参数将数据从 javascript 传递到 MVC Controller