【问题标题】:jQuery / Javascript - Run function only oncejQuery / Javascript - 只运行一次函数
【发布时间】:2010-12-19 11:52:06
【问题描述】:

更新:

标签悬停的缩略图会调用一个名为 displayImage() 的函数:

    function displayImage(index, parent){
    var images = document.getElementById(parent).getElementsByClassName("mainProductImage");

    for(var i = 0; i < images.length; i++) {
      var image = images[i];
      if (image.className != 'mainProductImage')  { continue }
      if(i == index-1) {
            // display main image
        image.style.display="block";
            // change selectedIndex of select list 
        jQuery("#mySelect").attr('selectedIndex', index-1);
        jQuery('#mySelect').trigger('change', [ i ]);           
      }
      else {
        image.style.display="none";
      }     
   }
}

我意识到我没有很好地解释这一点:) 我有 n 个图像缩略图,当悬停时会更改页面上的主要产品图像。缩略图悬停事件将 trigger() 发送到同一页面上的选择列表(带有 n 个产品的下拉列表,如果有 3 张图像,则选择列表上有 3 个对应的产品项)。

根据 Patrick 的建议,我在鼠标悬停时首先将其添加到循环中:

jQuery('#mySelect').trigger('change', [ i ]); // now passing the i variable

然后我补充说:

$('#mySelect').change( function( event, idx ) {
if( idx === 0 ) {
   $('#fade').fadeOut('fast');
   $('#fade').fadeIn('slow');
}

当我将鼠标悬停在缩略图上时,此代码现在限制了图像淡出的次数,但由于某种原因仍会淡出两次,而不仅仅是一次。

我还希望在更改选择列表中的产品项目时出现图像淡入淡出效果,但由于 .change() 函数无法识别循环数组中的 [i],因此现在无法正常工作。所以我需要一种解决方案,当一个人悬停在缩略图上或当一个人更改产品选择列表项时会触发淡入淡出。

我希望这有点道理!


有没有办法在常规的 javascript 函数中只运行一次 jQuery 代码?

我有一个fadeImage() 函数,根据页面上的不同事件调用该函数用于图像转换。这些事件之一是从 for 循环触发的。该循环导致该函数被多次调用,因此图像的淡入和淡出循环直到循环完成。我需要从循环内部触发淡入淡出效果,但只需要一次,所以我希望不要更改循环区域中的任何内容,而是让淡入淡出功能无论如何只运行一次。

我尝试了.one(),但没有运气。

function fadeImage()
{
    // is there a way to run these two lines only once? 
    $('#fade').fadeOut('fast');
    $('#fade').fadeIn('slow');
}

非常感谢任何建议。或者任何其他想法,也许我根本不需要一个函数来包装 jQuery 代码?

【问题讨论】:

  • 因此,悬停缩略图会更新主产品图像,并更改 &lt;select&gt; 中的选定项目以匹配缩略图。那正确吗?如果是这样,for 循环在哪里发挥作用?
  • 在缩略图悬停时调用函数 displayImage()。主帖上的代码:)
  • 首先,题外话,但你知道getElementsByClassName 在IE 中不受支持吗?无论如何,我看到你现在在做什么,额外参数解决方案不会那样工作。问题似乎与for 循环无关,因为.change() 事件仅在循环中发生一次。相反(如果我理解的话)问题是用户可能会在动画有机会完成之前从一个缩略图快速移动到另一个缩略图。如果这听起来不错,请尝试在您的 fadeIn/Out 调用中使用 .stop()stop(true,true)

标签: jquery jquery-ui javascript-events


【解决方案1】:

根据下面的评论,听起来在for 循环中,您多次触发.change() 事件。

如果您使用.trigger() 而不是.change(),您可以将“额外参数”发送到数组中的处理程序。

所以你的for 循环会是这样的:

var myselect = $('#mySelect');

for( var i = 0; i < something.length; i++ ) {
    myselect.trigger( 'change', [ i ] );
    // ...and so on
}

然后您的处理程序将设置一个参数以接受该i 参数。

$('#mySelect').change( function( event, idx ) {
    if( idx === 0 ) {
       $('#fade').fadeOut('fast');
       $('#fade').fadeIn('slow');
    }
});

在您的for 循环中,您可以设置一个变量作为标志,表明它已被调用。

var alreadyCalled = false;

for( /* whatever */ ) {
    if( !alreadyCalled ) {
        fadeImage();
        alreadyCalled = true;
    }
    // ...and so on
}

另一种选择是让您的函数接受for 循环中的索引参数,用于确定代码是否应该运行。

function fadeImage( idx ) {
    if( idx === 0 ) {
       $('#fade').fadeOut('fast');
       $('#fade').fadeIn('slow');
    }
}

for( var i = 0; i < something.length; i++ ) {
    fadeImage( i );
    // ...and so on
}

好处是杂乱无章。缺点是不必要的函数调用。

【讨论】:

  • 谢谢帕特里克这应该可以工作,但我应该在我的帖子中更好地解释我的情况...... for 循环将更改事件发送到一个选择列表,该列表又调用了 fadeImage() 函数。循环将更改事件发送到选择列表 n 次。因此,选择列表调用了 fadeImage() n 次。所以我需要让它运行一次,但在循环之后......希望这是有道理的
  • 当您说“发送更改事件”时,您的意思是您在选择时调用.change()?如果是这样,如果您使用.trigger(),则可以通过将“额外参数”传递给事件处理程序来使用我的第二个示例。 select.trigger('change', [i]) 也是如此(注意 i 在数组中)。然后让事件处理程序接受该参数。 (请记住,event 对象始终是第一个参数。)我会在一分钟内更新我的答案。
  • 帕特里克,非常感谢!这看起来不错,但仍然不适合我。用更多信息更新我的帖子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-28
  • 1970-01-01
  • 1970-01-01
  • 2021-12-24
相关资源
最近更新 更多