更改图像属性更改的不透明度?

时间:2022-03-06 04:53:45

I am changing image source on click (prev/next buttons), and I would like to fade out image, then change source and fade it in, but I cannot get smooth transition. I tried adding .delay() in between fading and changing the source but still the src change happens before fading ends. I tried adding .stop() but that only stops the currently running animation, and attribute change doesn't count as animation.

我正在点击(上一个/下一个按钮)更改图像源,我想淡出图像,然后更改源并淡入它,但我无法顺利过渡。我尝试在淡入淡出和更改源之间添加.delay()但仍然在淡入淡出结束之前发生src更改。我尝试添加.stop(),但只停止当前正在运行的动画,属性更改不算作动画。

var images = ['http://i.imgur.com/U82gG8H.jpg', 'http://i.imgur.com/kVy4G4R.jpg', 'http://i.imgur.com/BtMikrd.jpg'];

var count = 0;

$('.next').on('click', function() {
  if (count !== images.length-1) {
    count++;
    $('.product_image img').fadeTo(300, 0).delay(600).attr('src', '').attr('src', images[count]).fadeTo(300, 1);
  }
});

$('.previous').on('click', function() {
  if (count !== 0) {
    count--;
    $('.product_image img').fadeTo(300, 0).delay(400).attr('src', '').attr('src', images[count]).fadeTo(300, 1);
  }
});
.navigation {
  display: block;
}
.navigation .previous,
.navigation .next {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background: #ddd;
  color: #fff;
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}
.navigation .next {
  margin-right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="product_image">
  <img src="http://i.imgur.com/U82gG8H.jpg" />
</div>
<div class="navigation">
  <div class="previous">&lt;</div>
  <div class="next">&gt;</div>
</div>

Any help is appreciated.

任何帮助表示赞赏。

6 个解决方案

#1


2  

You need to use a callback function of the first fadeTo, otherwise the images are faded out, changed and faded back in again all at the same time. Try this:

您需要使用第一个fadeTo的回调函数,否则图像会同时淡出,更改并再次淡入。尝试这个:

var images = ['http://i.imgur.com/U82gG8H.jpg', 'http://i.imgur.com/kVy4G4R.jpg', 'http://i.imgur.com/BtMikrd.jpg'];
var count = 0;

$('.next').on('click', function() {
  if (count !== images.length - 1) {
    count++;
    $('.product_image img').fadeTo(300, 0, function() {
      $(this).attr('src', images[count]).fadeTo(300, 1);
    });
  }
});
$('.previous').on('click', function() {
  if (count !== 0) {
    count--;
    $('.product_image img').fadeTo(300, 0, function() {
      $(this).attr('src', images[count]).fadeTo(300, 1);
    });
  }
});
.navigation {
  display: block;
}
.navigation .previous,
.navigation .next {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background: #ddd;
  color: #fff;
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}
.navigation .next {
  margin-right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="product_image">
  <img src="http://i.imgur.com/U82gG8H.jpg" />
</div>
<div class="navigation">
  <div class="previous">&lt;</div>
  <div class="next">&gt;</div>
</div>

#2


2  

The .attr() function is not a queue based method, so the delay will not have any effect on it. You can use .delay() to add a method to the animation queue.

.attr()函数不是基于队列的方法,因此延迟不会对它产生任何影响。您可以使用.delay()将方法添加到动画队列中。

Also preloading the images can improve the transition.

预加载图像也可以改善过渡。

var images = ['http://i.imgur.com/U82gG8H.jpg', 'http://i.imgur.com/kVy4G4R.jpg', 'http://i.imgur.com/BtMikrd.jpg'];

//image preloading
images.forEach(function(src) {
  var img = new Image();
  img.src = src;
})

var count = 0;

$('.next').on('click', function() {
  count++;
  count = count >= images.length ? 0 : count;
  $('.product_image img').fadeTo(300, 0).delay(600).queue(function(next) {
    $(this).attr('src', images[count]);
    next();
  }).fadeTo(300, 1);
});

$('.previous').on('click', function() {
  count--;
  count = count < 0 ? images.length - 1 : count;

  $('.product_image img').fadeTo(300, 0).delay(400).queue(function(next) {
    $(this).attr('src', images[count]);
    next();
  }).fadeTo(300, 1);
});
.navigation {
  display: block;
}
.navigation .previous,
.navigation .next {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background: #ddd;
  color: #fff;
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}
.navigation .next {
  margin-right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="product_image">
  <img src="http://i.imgur.com/U82gG8H.jpg" />
</div>
<div class="navigation">
  <div class="previous">&lt;</div>
  <div class="next">&gt;</div>
</div>

#3


2  

Use a callback function

I would suggest using the complete callback which is documented here.

我建议使用此处记录的完整回调。

The callback is defined as a function and is added after the opacity value like this:

回调被定义为一个函数,并在不透明度值之后添加,如下所示:

.fadeTo( duration, opacity [, complete ] )

The callback function will then fire after the animation has completed allowing us to change the src attribute while the image is "hidden" and then fading it back in.

然后回调函数将在动画完成后触发,允许我们在图像被“隐藏”时更改src属性,然后将其淡入。

An Example

var images = ['http://i.imgur.com/U82gG8H.jpg', 'http://i.imgur.com/kVy4G4R.jpg', 'http://i.imgur.com/BtMikrd.jpg'];

var count = 0,
    productImage = $('.product_image').children('img');

$('.next').on('click', function() {
  
  if (count !== images.length - 1) {
    
    count++;
    
    productImage.fadeTo(300, 0, function() {

      productImage.attr('src', images[count]).fadeTo(300, 1);

    });
  }
});

$('.previous').on('click', function() {
  
  if (count !== 0) {
    
    count--;
    
    productImage.fadeTo(300, 0, function() {

      productImage.attr('src', images[count]).fadeTo(300, 1);

    });
  }
});
.navigation {
  display: block;
}
.navigation .previous,
.navigation .next {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background: #ddd;
  color: #fff;
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}
.navigation .next {
  margin-right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="product_image">
  <img src="http://i.imgur.com/U82gG8H.jpg" />
</div>
<div class="navigation">
  <div class="previous">&lt;</div>
  <div class="next">&gt;</div>
</div>

#4


1  

Try this approach

试试这种方法

$(img).fadeTo(200,0.70, function() {
        $(img).attr("src", new_img_src);
   }).fadeTo(300,1); 

#5


1  

According to this answer: currently ongoing animation is finished immediately, and the current is started.

根据这个答案:目前正在进行的动画立即完成,并开始当前动画。

var images = ['http://i.imgur.com/U82gG8H.jpg', 'http://i.imgur.com/kVy4G4R.jpg', 'http://i.imgur.com/BtMikrd.jpg'];

var count = 0;

$('.next').on('click', function() {
  if (count !== images.length-1) {
    count++;
    $('.product_image img').fadeTo(300, 0).delay(600).attr('src', '').attr('src', images[count]).finish().fadeTo(300, 1);
  }
});

$('.previous').on('click', function() {
  if (count !== 0) {
    count--;
    $('.product_image img').fadeTo(300, 0).delay(400).attr('src', '').attr('src', images[count]).finish().fadeTo(300, 1);
  }
});
.navigation {
  display: block;
}
.navigation .previous,
.navigation .next {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background: #ddd;
  color: #fff;
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}
.navigation .next {
  margin-right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="product_image">
  <img src="http://i.imgur.com/U82gG8H.jpg" />
</div>
<div class="navigation">
  <div class="previous">&lt;</div>
  <div class="next">&gt;</div>
</div>

#6


1  

You can use .fadeOut() with callback function when complete like:

完成后,您可以使用带有回调函数的.fadeOut():

var images = ['http://i.imgur.com/U82gG8H.jpg', 'http://i.imgur.com/kVy4G4R.jpg', 'http://i.imgur.com/BtMikrd.jpg'];

var count = 0;

$('.next').on('click', function() {
  if (count !== images.length - 1) {
    count++;
    $('.product_image img').fadeOut(300, function() {
      $(this).attr('src', '').attr('src', images[count]).fadeTo(300, 1);
    });
  }
});

$('.previous').on('click', function() {
  if (count !== 0) {
    count--;
    $('.product_image img').fadeOut(300, function() {
      $(this).attr('src', '').attr('src', images[count]).fadeTo(300, 1);
    });
  }
});
.navigation {
  display: block;
}
.navigation .previous,
.navigation .next {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background: #ddd;
  color: #fff;
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}
.navigation .next {
  margin-right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="product_image">
  <img src="http://i.imgur.com/U82gG8H.jpg" />
</div>
<div class="navigation">
  <div class="previous">&lt;</div>
  <div class="next">&gt;</div>
</div>

#1


2  

You need to use a callback function of the first fadeTo, otherwise the images are faded out, changed and faded back in again all at the same time. Try this:

您需要使用第一个fadeTo的回调函数,否则图像会同时淡出,更改并再次淡入。尝试这个:

var images = ['http://i.imgur.com/U82gG8H.jpg', 'http://i.imgur.com/kVy4G4R.jpg', 'http://i.imgur.com/BtMikrd.jpg'];
var count = 0;

$('.next').on('click', function() {
  if (count !== images.length - 1) {
    count++;
    $('.product_image img').fadeTo(300, 0, function() {
      $(this).attr('src', images[count]).fadeTo(300, 1);
    });
  }
});
$('.previous').on('click', function() {
  if (count !== 0) {
    count--;
    $('.product_image img').fadeTo(300, 0, function() {
      $(this).attr('src', images[count]).fadeTo(300, 1);
    });
  }
});
.navigation {
  display: block;
}
.navigation .previous,
.navigation .next {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background: #ddd;
  color: #fff;
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}
.navigation .next {
  margin-right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="product_image">
  <img src="http://i.imgur.com/U82gG8H.jpg" />
</div>
<div class="navigation">
  <div class="previous">&lt;</div>
  <div class="next">&gt;</div>
</div>

#2


2  

The .attr() function is not a queue based method, so the delay will not have any effect on it. You can use .delay() to add a method to the animation queue.

.attr()函数不是基于队列的方法,因此延迟不会对它产生任何影响。您可以使用.delay()将方法添加到动画队列中。

Also preloading the images can improve the transition.

预加载图像也可以改善过渡。

var images = ['http://i.imgur.com/U82gG8H.jpg', 'http://i.imgur.com/kVy4G4R.jpg', 'http://i.imgur.com/BtMikrd.jpg'];

//image preloading
images.forEach(function(src) {
  var img = new Image();
  img.src = src;
})

var count = 0;

$('.next').on('click', function() {
  count++;
  count = count >= images.length ? 0 : count;
  $('.product_image img').fadeTo(300, 0).delay(600).queue(function(next) {
    $(this).attr('src', images[count]);
    next();
  }).fadeTo(300, 1);
});

$('.previous').on('click', function() {
  count--;
  count = count < 0 ? images.length - 1 : count;

  $('.product_image img').fadeTo(300, 0).delay(400).queue(function(next) {
    $(this).attr('src', images[count]);
    next();
  }).fadeTo(300, 1);
});
.navigation {
  display: block;
}
.navigation .previous,
.navigation .next {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background: #ddd;
  color: #fff;
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}
.navigation .next {
  margin-right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="product_image">
  <img src="http://i.imgur.com/U82gG8H.jpg" />
</div>
<div class="navigation">
  <div class="previous">&lt;</div>
  <div class="next">&gt;</div>
</div>

#3


2  

Use a callback function

I would suggest using the complete callback which is documented here.

我建议使用此处记录的完整回调。

The callback is defined as a function and is added after the opacity value like this:

回调被定义为一个函数,并在不透明度值之后添加,如下所示:

.fadeTo( duration, opacity [, complete ] )

The callback function will then fire after the animation has completed allowing us to change the src attribute while the image is "hidden" and then fading it back in.

然后回调函数将在动画完成后触发,允许我们在图像被“隐藏”时更改src属性,然后将其淡入。

An Example

var images = ['http://i.imgur.com/U82gG8H.jpg', 'http://i.imgur.com/kVy4G4R.jpg', 'http://i.imgur.com/BtMikrd.jpg'];

var count = 0,
    productImage = $('.product_image').children('img');

$('.next').on('click', function() {
  
  if (count !== images.length - 1) {
    
    count++;
    
    productImage.fadeTo(300, 0, function() {

      productImage.attr('src', images[count]).fadeTo(300, 1);

    });
  }
});

$('.previous').on('click', function() {
  
  if (count !== 0) {
    
    count--;
    
    productImage.fadeTo(300, 0, function() {

      productImage.attr('src', images[count]).fadeTo(300, 1);

    });
  }
});
.navigation {
  display: block;
}
.navigation .previous,
.navigation .next {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background: #ddd;
  color: #fff;
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}
.navigation .next {
  margin-right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="product_image">
  <img src="http://i.imgur.com/U82gG8H.jpg" />
</div>
<div class="navigation">
  <div class="previous">&lt;</div>
  <div class="next">&gt;</div>
</div>

#4


1  

Try this approach

试试这种方法

$(img).fadeTo(200,0.70, function() {
        $(img).attr("src", new_img_src);
   }).fadeTo(300,1); 

#5


1  

According to this answer: currently ongoing animation is finished immediately, and the current is started.

根据这个答案:目前正在进行的动画立即完成,并开始当前动画。

var images = ['http://i.imgur.com/U82gG8H.jpg', 'http://i.imgur.com/kVy4G4R.jpg', 'http://i.imgur.com/BtMikrd.jpg'];

var count = 0;

$('.next').on('click', function() {
  if (count !== images.length-1) {
    count++;
    $('.product_image img').fadeTo(300, 0).delay(600).attr('src', '').attr('src', images[count]).finish().fadeTo(300, 1);
  }
});

$('.previous').on('click', function() {
  if (count !== 0) {
    count--;
    $('.product_image img').fadeTo(300, 0).delay(400).attr('src', '').attr('src', images[count]).finish().fadeTo(300, 1);
  }
});
.navigation {
  display: block;
}
.navigation .previous,
.navigation .next {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background: #ddd;
  color: #fff;
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}
.navigation .next {
  margin-right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="product_image">
  <img src="http://i.imgur.com/U82gG8H.jpg" />
</div>
<div class="navigation">
  <div class="previous">&lt;</div>
  <div class="next">&gt;</div>
</div>

#6


1  

You can use .fadeOut() with callback function when complete like:

完成后,您可以使用带有回调函数的.fadeOut():

var images = ['http://i.imgur.com/U82gG8H.jpg', 'http://i.imgur.com/kVy4G4R.jpg', 'http://i.imgur.com/BtMikrd.jpg'];

var count = 0;

$('.next').on('click', function() {
  if (count !== images.length - 1) {
    count++;
    $('.product_image img').fadeOut(300, function() {
      $(this).attr('src', '').attr('src', images[count]).fadeTo(300, 1);
    });
  }
});

$('.previous').on('click', function() {
  if (count !== 0) {
    count--;
    $('.product_image img').fadeOut(300, function() {
      $(this).attr('src', '').attr('src', images[count]).fadeTo(300, 1);
    });
  }
});
.navigation {
  display: block;
}
.navigation .previous,
.navigation .next {
  width: 30px;
  height: 30px;
  line-height: 30px;
  text-align: center;
  background: #ddd;
  color: #fff;
  display: inline-block;
  margin-right: 20px;
  cursor: pointer;
}
.navigation .next {
  margin-right: 0;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="product_image">
  <img src="http://i.imgur.com/U82gG8H.jpg" />
</div>
<div class="navigation">
  <div class="previous">&lt;</div>
  <div class="next">&gt;</div>
</div>