Knockout滑动图像问题与自定义绑定 [英] Knockout sliding images issue with custom binding
问题描述
当用户将鼠标悬停在产品图块上时,我想在我的产品列表页面上实现滚动图像。最初将显示第一张图像,当悬停时,幻灯片放映将开始。每个产品图块将有不同数量的图像用于幻灯片放映。
I want to implement scrolling images on my product listing page when a user hovers on the product tile. Initially the first image will be displayed and when hovered the slide show shall begin. Each product tile will have different number of images for slide show.
问题:当悬停在阵列中有五个图像的图像上时,幻灯片放映开始,第二个图像是显示。而不是第三个图像再次显示第一个图像。以下是序列:
数字表示图像索引
1,2
1,2,3
1,2,3,4
1,2, 3,4,5
预计:1,2,3,4,5
Issue: When hovered on an image with five images in an array, the slide show starts and second image is shown.But the instead of third image again first image is getting displayed. Below is the sequence: Number denotes the index of images 1,2 1,2,3 1,2,3,4 1,2,3,4,5 Expected: 1,2,3,4,5
还观察到鼠标悬停事件未注册。
Also Observed that the mouse hover event gets unregistered.
以下是代码:
<div class="customized-slider-wrapper" data-bind="PLPTileSizeOnHover: $data">
<div class="customized-slider" data-bind="foreach: fullImageURLs">
<div class="individual-tile">
<img data-bind="attr: { src: $index() === 0? $data : '../file/general/show_loader_showcase.gif' }" class="product-images" />
</div>
</div>
</div>
KO代码
ko.bindingHandlers.PLPTileSizeOnHover = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
var data = ko.unwrap(valueAccessor());
// Intiallizing variables for product image animation
var _index = 0;
var imgArray = data.fullImageURLs();
var toBeScrolledBy = 0;
var scroller = $(element).find('.customized-slider').eq(0);
var StopAnimation;
element.onmouseover = function () {
//Start Animation
StopAnimation = setInterval(function () {
var totalSlides = $(element).find('.customized-slider').eq(0).children();
var slideWidth = totalSlides[0] && totalSlides[0].clientWidth;
_index++;
$($(element).find('.product-images')[_index]).attr('src', imgArray[_index]);
if (_index >= imgArray.length) {
_index = 0;
}
toBeScrolledBy = slideWidth * _index;
$(scroller).css({
'transform': 'translateX(-' + toBeScrolledBy + 'px)'
});
}, 1500);
}
element.onmouseout = function () {
//End of animation and reseting the index and div postion
clearInterval(StopAnimation);
_index = 0;
$(scroller).css({
'transform': 'translateX(0)'
});
}
}
}
要求加载图片一徘徊时的一个人无法首先加载所有图像。
Requirement is to load images one by one when hovered. cannot load all images first.
代码在开启工具时使用chrome。
Code works on chrome when dev tool is kept on.
小提琴 https://jsfiddle.net/harpreetsjs/cvzrnaLy/
推荐答案
问题是鼠标悬停
和 mouseout
事件。他们也被元素的孩子和泡沫所解雇。因此,当孩子们四处走动时,你随机地获取这些事件。相反,你想使用 mouseenter
和 mouseleave
。
The problem is the mouseover
and mouseout
events. They are fired also for the element's children and bubble up. Therefore you "randomly" get these events as the children move around. Instead you want to use mouseenter
and mouseleave
.
我已将此更改以及一些常规清理合并:
I've incorporated this change as well as some general cleanup:
ko.bindingHandlers.PLPTileSizeOnHover = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
var data = ko.unwrap(valueAccessor());
console.log(data);
// Intiallizing variables for product image animation
var _index = 0;
var imgArray = data;
var toBeScrolledBy = 0;
var scroller = $(element).find('.customized-slider').eq(0);
var StopAnimation;
element.onmouseenter = function() {
//Start Animation
console.log("start");
StopAnimation = setInterval(function() {
console.log("Started " + _index);
var totalSlides = scroller.children();
console.log("totalSlides " + totalSlides.length);
var slideWidth = totalSlides[0] && totalSlides[0].clientWidth;
console.log('slideWidth', slideWidth);
_index++;
scroller.find('.product-images').eq(_index).attr('src', imgArray[_index]);
if (_index >= imgArray.length) {
_index = 0;
}
toBeScrolledBy = slideWidth * _index;
scroller.css({
'transform': 'translateX(-' + toBeScrolledBy + 'px)'
});
}, 1500);
}
element.onmouseleave = function() {
//End of animation and reseting the index and div postion
console.log("clear");
clearInterval(StopAnimation);
_index = 0;
scroller.css({
'transform': 'translateX(0)'
});
}
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
console.log("Update cakked");
}
}
var fullImageURLs = ko.observableArray([
'https://product-images.barneys.com/is/image/Barneys/505670716_1_ShoeSide?$oc_grid_fixed$',
'https://product-images.barneys.com/is/image/Barneys/505670733_1_ShoeSide?$oc_grid_fixed$',
'https://product-images.barneys.com/is/image/Barneys/505670750_1_ShoeSide?$oc_grid_fixed$ '
]);
console.log(fullImageURLs());
ko.applyBindings(fullImageURLs);
.customized-slider-wrapper {
height: 370px;
position: relative;
overflow: hidden;
width: 100%;
width: 231px;
}
.customized-slider {
position: absolute;
left: 0;
width: 1800px;
height: 100%;
transition: transform .5s ease 0s;
display: block;
}
.individual-tile {
float: left;
}
.customized-slider-wrapper .customized-slider>div img {
height: 252px;
float: none;
display: block;
width: auto;
height: auto;
max-width: 100%;
max-height: 100%;
margin: 0 auto;
vertical-align: middle;
border: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<a class="search-products-images">
<div class="customized-slider-wrapper" data-bind="PLPTileSizeOnHover: $data">
<div class="customized-slider" data-bind="foreach: $data">
<div class="individual-tile">
<img data-bind="attr: { src: $index() === 0? $data : 'http://placehold.it/106&text=1' }" class="product-images" />
</div>
</div>
</div>
</a>
这篇关于Knockout滑动图像问题与自定义绑定的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!