Knockout滑动图像问题与自定义绑定 [英] Knockout sliding images issue with custom binding

查看:66
本文介绍了Knockout滑动图像问题与自定义绑定的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆