为什么我的JavaScript代码仅在第二次点击时执行?

时间:2019-06-27 03:01:01

标签: javascript jquery

我一直在玩这个。我似乎无法找出为什么只有在单击两次后才执行灯箱。第一次单击,它只是将图像弹出到新标签中。

我已经尝试过使用e.preventDefault(除了在第一次单击后不使图像在新选项卡中弹出之外,什么都没有做。)

$(document).ready(function() {

    $('a[class^="fomod-"]').on('click', function() {
        var fomodClass = $(this).attr('class');
        var fomodGallery = $('.' + fomodClass).simpleLightbox({
            loop: false
        });
    });

});

我最终要做的是监视DOM,以查看是否有具有“ fomod- *”类的链接,如果单击,则将获得所单击元素的确切类。这样,灯箱就会弹出,并且只显示与图库具有相同类别的其他图像。

1 个答案:

答案 0 :(得分:7)

问题

.simpleLightbox() 初始化灯箱。这意味着您的第一次点击会在页面上添加simpleLightbox,从而允许随后的所有点击真正触发

页面加载时,您需要进行初始化。现在您可以做类似...

$('a[class^="fomod-"]').each(function() { ... })

但是有一些缺点。

  1. 它将找不到fomod不是第一类的元素,即class="other-class fomod-one"
  2. 如果您有class="fomod-one other-class",则内部选择器将不起作用,因为串联将导致$(".fomod-one other-class")
  3. 您将不断在相同的元素上不断地重新初始化simpleLightbox,我不确定插件是否设置为可以处理。

解决方案1-数据属性

data属性使我们在选择元素时更具灵活性。另外,香草JS(使用dataset)和jQuery(使用.data())都支持在JavaScript中获取data属性。

<a data-fomod="Gallery1"></a>
<a data-fomod="Gallery1"></a>
<a data-fomod="Gallery2"></a>
$(document).ready(function() {

  const galleries = $("[data-fomod]")
    //Get array from elements
    .get()
    //Attach lightbox to each unique gallery on the page
    .reduce((output, {dataset}) => {
      let galleryName = dataset.fomod;
      return output[galleryName] 
        ? output 
        : {...output, [galleryName]: $(`[data-fomod="${galleryName}"]`).simpleLightbox({loop: false})}
    }, {});

});

与最初的方法相比,这种方法为我们提供了三件事:

  1. 它不限制类的使用。
  2. 它仅将simpleLightbox附加到每个图库一次
  3. 它将名称分别存储在galleries对象中。例如,如果您想告诉Gallery1转到下一张幻灯片,则可以执行galleries["Gallery1"].next()

解决方案2-更适当地使用类

正如您在评论中提到的那样,您的环境没有为data-属性提供强大的支持。相反,我们可以使用类,我们只需要更加体贴即可。在这里,我将使用两个类-一个将其标记为灯箱元素("fomod"),另一个将其关联到图库("fomod-GalleryName")。

您可能想知道为什么必须使用“标志” fomod类。为什么不只使用fomod-并使用^=选择器呢?如上所述,如果fomod-my-other-class之后的 second 类怎么办?选择器找不到元素。

(有很多方法可以解决,但这会打开一罐蠕虫。)

这种方法虽然涉及的程度略微多一些,但可以实现与 data attribute 解决方案相同的所有优点。

<a class="fomod fomod-Gallery1"></a>
<a class="fomod fomod-Gallery1"></a>
<a class="fomod fomod-Gallery2"></a>

没有评论

$(document).ready(function() {
  const galleries = $(".fomod")
    .get()
    .reduce((output, elem) => {
      let galleryName = [...elem.classList].find(c => c.startsWith('fomod-'));
      if (!galleryName) return;
      galleryName = galleryName.split("-")[1];

      return output[galleryName] 
        ? output 
        : { ...output, [galleryName]: $(`.fomod-${galleryName}`).simpleLightbox({loop: false})}
    }, {});
});

有评论

   $(document).ready(function() {

      const galleries = $(".fomod")

        //Get array from elements
        .get()

        //For each fomod element...
        .reduce((output, elem) => {

          //Get the classes on this element, and find one that starts with "fomod-"
          let galleryName = [...elem.classList].find(c => c.startsWith('fomod-'));

          //Didn't find one. Skip this element
          if (!galleryName) return;

          //Remove the "fomod-" part so we're left with just the gallery name
          galleryName = galleryName.split("-")[1];

          //Have we already initialized this gallery?
          return output[galleryName]  

            //Yup. Do nothing.
            ? output              
    
            //Nope. Initialize it now.
            : { ...output, [galleryName]:  $(`.fomod-${galleryName}`).simpleLightbox({loop: false})}

        }, {});

    });