Knockout滑动图像问题与自定义绑定

时间:2018-06-05 15:32:30

标签: javascript jquery knockout.js

当用户将鼠标悬停在产品图块上时,我想在我的产品列表页面上实现滚动图像。最初将显示第一张图像,当悬停时,幻灯片放映将开始。每个产品图块都有不同数量的图像用于幻灯片放映。

问题:当悬停在阵列中有五个图像的图像上时,幻灯片放映开始并显示第二个图像。但是再次显示第一个图像而不是第三个图像。以下是顺序: Number表示图像的索引 1,2 1,2,3 1,2,3,4 1,2,3,4,5 预计:1,2,3,4,5

还观察到鼠标悬停事件未注册。

以下是代码:

#define red 9
#define yellow 8
void setup() {
    // put your setup code here, to run once:
    Serial.begin(9600);
    pinMode(red, OUTPUT);
    pinMode(yellow, OUTPUT);
}
void LightON() {
    digitalWrite(red, HIGH);
    delay(1000);
    digitalWrite(yellow, HIGH);
    delay(1000);
    digitalWrite(red, LOW);
    delay(1000);
}
void LightOff() {
    digitalWrite(red, LOW);
    digitalWrite(yellow, LOW);
}
void loop() {
    // put your main code here, to run repeatedly:
    LightON();
    if (Serial.available())
    {
        LightOff();
    }
}

KO代码

<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>

要求是在悬停时逐个加载图像。无法先装入所有图像。

当开发工具时,代码适用于chrome。

小提琴https://jsfiddle.net/harpreetsjs/cvzrnaLy/

1 个答案:

答案 0 :(得分:2)

问题是mouseovermouseout事件。他们也被元素的孩子和泡沫所解雇。因此,当孩子们四处走动时,你“随机”地获取这些事件。相反,您希望使用mouseentermouseleave

我已将此更改以及一些常规清理纳入其中:

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>