jQuery snapPuzzle在最后一块上多次点击

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了jQuery snapPuzzle在最后一块上多次点击相关的知识,希望对你有一定的参考价值。

好的,所以我正在为我的大师们创建一个项目,以便在实验室设置中引起挫折,我正在使用这个插件来拼图:https://goodies.pixabay.com/jquery/snap-puzzle/demo.html

我想做的是让拼图在最后一块上“打破”以引起挫折,所以他们必须先点击它才能将它拖到它的插槽中5次。我对javascript并不是很棒,而且功能有点复杂,所以我对如何做到这一点感到有点失落,似乎有更多的帮助来摆脱多次点击而不是造成它们。

据我所知 - 最后在jquery.snap-puzzle.js文件中定义了最后一个插槽填充时的操作,我已经尝试了几次调整但是我一直在打破它...任何人都有关于如何在移动最后一块之前需要5次点击的任何想法?

如果它有很大的不同,我正在使用Angular作为我的前端......

**编辑:根据@Martieva的建议,我添加了一个点击增量器,如下所示:

(function($){
    $.fn.snapPuzzle = function(options){
        var o = $.extend({ pile: '', containment: 'document', rows: 5,   columns: 5, onComplete: function(){} }, options);

    // public methods
    if (typeof options == 'string') {
        this.each(function(){
            var that = $(this),
                o = that.data('options'),
                pieceWidth = that.width() / o.columns,
                pieceHeight = that.height() / o.rows,
                pile = $(o.pile),
                maxX = pile.width() - pieceWidth,
                maxY = pile.height() - pieceHeight,
                puzzle_offset = that.closest('span').offset(),
                pile_offset = pile.offset();

            if (options == 'destroy') {
                $('.'+o.puzzle_class).remove();
                that.unwrap().removeData('options');
                pile.removeClass('snappuzzle-pile');
            } else if (options == 'refresh') {
                $('.snappuzzle-slot.'+o.puzzle_class).each(function(){
                    var x_y = $(this).data('pos').split('_'), x = x_y[0], y = x_y[1];
                    $(this).css({
                        width: pieceWidth,
                        height: pieceHeight,
                        left: y*pieceWidth,
                        top: x*pieceHeight
                    });
                });
                $('.snappuzzle-piece.'+o.puzzle_class).each(function(){
                    if ($(this).data('slot')) {
                        // placed on slot
                        var x_y = $(this).data('slot').split('_'), slot_x = x_y[0], slot_y = x_y[1],
                            x_y = $(this).data('pos').split('_'), pos_x = x_y[0], pos_y = x_y[1];;
                        $(this).css({
                            width: pieceWidth,
                            height: pieceHeight,
                            left: slot_y*pieceWidth+puzzle_offset.left-pile_offset.left,
                            top: slot_x*pieceHeight+puzzle_offset.top-pile_offset.top,
                            backgroundPosition: (-pos_y*pieceWidth)+'px '+(-pos_x*pieceHeight)+'px',
                            backgroundSize: that.width()
                        });
                    } else {
                        // placed anywhere else
                        var x_y = $(this).data('pos').split('_'), x = x_y[0], y = x_y[1];
                        $(this).css({
                            width: pieceWidth,
                            height: pieceHeight,
                            left: Math.floor((Math.random()*(maxX+1))),
                            top: Math.floor((Math.random()*(maxY+1))),
                            backgroundPosition: (-y*pieceWidth)+'px '+(-x*pieceHeight)+'px',
                            backgroundSize: that.width()
                        });
                    }
                });
            }
        });
        return this;
    }

    function init(that){
        var puzzle_class = 'sp_'+new Date().getTime(),
            puzzle = that.wrap('<span class="snappuzzle-wrap"/>').closest('span'),
            src = that.attr('src'),
            pieceWidth = that.width() / o.columns,
            pieceHeight = that.height() / o.rows,
            pile = $(o.pile).addClass('snappuzzle-pile'),
            maxX = pile.width() - pieceWidth,
            maxY = pile.height() - pieceHeight;

        o.puzzle_class = puzzle_class;
        that.data('options', o);

        for (var x=0; x<o.rows; x++) {
            for (var y=0; y<o.columns; y++) {
                $('<div class="snappuzzle-piece '+puzzle_class+'"/>').data('pos', x+'_'+y).css({
                    width: pieceWidth,
                    height: pieceHeight,
                    position: 'absolute',
                    left: Math.floor((Math.random()*(maxX+1))),
                    top: Math.floor((Math.random()*(maxY+1))),
                    zIndex: Math.floor((Math.random()*10)+1),
                    backgroundImage: 'url('+src+')',
                    backgroundPosition: (-y*pieceWidth)+'px '+(-x*pieceHeight)+'px',
                    backgroundSize: that.width()
                }).draggable({
                    start: function(e, ui){ $(this).removeData('slot'); },
                    stack: '.snappuzzle-piece',
                    containment: o.containment
                }).appendTo(pile).data('lastSlot', pile);

                $('<div class="snappuzzle-slot '+puzzle_class+'"/>').data('pos', x+'_'+y).css({
                    width: pieceWidth,
                    height: pieceHeight,
                    left: y*pieceWidth,
                    top: x*pieceHeight
                }).appendTo(puzzle).droppable({
                    accept: '.'+puzzle_class,
                    hoverClass: 'snappuzzle-slot-hover',
                    drop: function(e, ui){
                        var slot_pos = $(this).data('pos');

                        // prevent dropping multiple pieces on one slot
                        $('.snappuzzle-piece.'+puzzle_class).each(function(){
                            if ($(this).data('slot') == slot_pos) slot_pos = false;
                        });
                        if (!slot_pos) return false;

                        ui.draggable.data('lastSlot', $(this)).data('slot', slot_pos);
                        ui.draggable.position({ of: $(this), my: 'left top', at: 'left top' });

//Here is the click increment code from @Martieva
                        var clicks = 0;
                        if(ui.draggable.data('pos')==slot_pos){
                            clicks++;
                            if(clicks<5){
                                return;
                            }
                        }
//back to original code
                        if (ui.draggable.data('pos')==slot_pos) {
                            ui.draggable.addClass('correct');
                            // fix piece
                            // $(this).droppable('disable').fadeIn().fadeOut();
                            $(this).droppable('disable').css('opacity', 1).fadeOut(1000);
                            ui.draggable.css({opacity: 0, cursor: 'default'}).draggable('disable');
                            if ($('.snappuzzle-piece.correct.'+puzzle_class).length == o.rows*o.columns) o.onComplete(that);
                        }
                    }
                });
            }
        }
    }

    return this.each(function(){
        if (this.complete) init($(this));
        else $(this).load(function(){ init($(this)); });
    });
};
}(jQuery));

以下是需要包含的拼图的另一个脚本:

 // jQuery UI Touch Punch 0.2.3 - must load after jQuery UI
// enables touch support for jQuery UI
!function(a){
function f(a,b){
    if(!(a.originalEvent.touches.length>1)){a.preventDefault();
        var c=a.originalEvent.changedTouches[0],
            d=document.createEvent("MouseEvents");
        d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),
            a.target.dispatchEvent(d)
    }
}
if(a.support.touch="ontouchend"in document,a.support.touch){
    var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;
    b._touchStart=function(a){
        var b=this;
        !e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,
            f(a,"mouseover"),
            f(a,"mousemove"),
            f(a,"mousedown"))
    },
        b._touchMove=function(a){
            e&&(this._touchMoved=!0,
                f(a,"mousemove"))
        },
        b._touchEnd=function(a){
            e&&(f(a,"mouseup"),
                f(a,"mouseout"),
        this._touchMoved||f(a,"click"),
            e=!1)
    },
        b._mouseInit=function(){
        var b=this;
            b.element.bind({
                touchstart:a.proxy(b,"_touchStart"),
                touchmove:a.proxy(b,"_touchMove"),
                touchend:a.proxy(b,"_touchEnd")}),
                c.call(b)},
        b._mouseDestroy=function(){
        var b=this;b.element.unbind({
            touchstart:a.proxy(b,"_touchStart"),
            touchmove:a.proxy(b,"_touchMove"),
            touchend:a.proxy(b,"_touchEnd")}),
            d.call(b)
    }
}
}(jQuery);

function start_puzzle(x){
$('#puzzle_solved').hide();
$('#source_image').snapPuzzle({
    rows: x, columns: x,
    pile: '#pile',
    containment: '#puzzle-containment',
    onComplete: function(){
        $('#source_image').fadeOut(150).fadeIn();
        $('#puzzle_solved').show();
    }
});
}

$(function(){
$('#pile').height($('#source_image').height());
start_puzzle(5);

$('.restart-puzzle').click(function(){
    $('#source_image').snapPuzzle('destroy');
    start_puzzle($(this).data('grid'));
});

$(window).resize(function(){
    $('#pile').height($('#source_image').height());
    $('#source_image').snapPuzzle('refresh');
});
});

它不会在很大程度上打破这个难题,但它不会增加最终作品的点击次数。

答案

一种基本方法可能是这样的

var clicks = 0;//Needs to be of a scope that the count isn't reset between clicks.
//...The rest of your code...
if(isLastTile){//If we are dealing with the final tile.
   clicks++;
  if(clicks < 5){
   return; //Do nothing
  }
}
normalProcess();

以上是关于jQuery snapPuzzle在最后一块上多次点击的主要内容,如果未能解决你的问题,请参考以下文章

jQuery单击事件多次触发

jquery datepicker onselect 事件处理程序多次

input是否checked与使用jquery的attr或prop方法无关

后摩尔定律时代的最后一块拼图?

jQuery click - 防止移动设备中的多次点击

Rails 5:如何防止来自 jQuery 的多次提交