1

我有一个圆圈,其中有一个菜单,其中的对象位于圆圈内的圆圈中。当用户向任何方向拖动他们的手指时,圆圈会随着手指旋转,但是,当用户旋转轮子并碰巧触摸到其中的一个对象(用作链接)时,圆圈会“刹车”并停止旋转。我需要取消活动气泡。我知道我需要使用 event.stopPropagation 并处理事件处理程序中的捕获,但是我在使用我发现的 jQuery 插件(Touchy)实现它时遇到了问题。

*确保您在 Chrome 中查看设置为模拟触摸事件的覆盖,并且开发人员控制台已打开 Mac 上的 Command+Option+i !!!*

http://jsfiddle.net/ymtV3/

*确保您在 Chrome 中查看设置为模拟触摸事件的覆盖,并且开发人员控制台已打开 Mac 上的 Command+Option+i !!!*

<div id="wheelMenu">
    <div id="wheel">
        <ul class="items">
            <li class="flashOff"><span>Flash</span></li>
            <li class="sceneOff"><span>Scene</span></li>
            <li class="hdrOff"><span>Hdr</span></li>
            <li class="panoramaOff"><span>Pana</span></li>
            <li class="resolutionOff"><span>Resolu</span></li>
            <li class="reviewOff"><span>Review</span></li>
            <li class="continuousShootingOff"><span>Contin</span></li>
            <li class="dropBoxOff"><span>DropBox</span></li>
            <li class="timerOff"><span>Timer</span></li>
        </ul>
    </div>
</div>


(function ($) {
    $.touchyOptions = {
        useDelegation: false,

        rotate: {
            preventDefault: {
                start: true,
                move: true,
                end: true
            },
            stopPropagation: {
                start: true,
                move: true,
                end: true
            },
            requiredTouches: 1,
            data: {},
            proxyEvents: ["TouchStart", "TouchMove", "GestureChange", "TouchEnd"]
        }
    };

    var proxyHandlers = {

        handleTouchStart: function (e) {

            var eventType = this.context,
                $target = getTarget(e, eventType);

            if ($target) {
                var event = e.originalEvent,
                    touches = event.targetTouches,
                    camelDataName = 'touchy' + eventType.charAt(0).toUpperCase() + eventType.slice(1),
                    data = $target.data(camelDataName),
                    settings = data.settings;

                if (settings.preventDefault.start) {
                    event.preventDefault();
                }

                if (settings.stopPropagation.start) {
                    event.stopPropagation();
                }

                if (touches.length === settings.requiredTouches) {
                    switch (eventType) {
                        case 'rotate':
                            if (touches.length === 1) {
                                ensureSingularStartData(data, touches, e.timeStamp);
                                console.log(eventType);
                                console.log(touches);
                                console.log(data);
                            } else {
                                var points = getTwoTouchPointData(e);
                                data.startPoint = {
                                    "x": points.centerX,
                                        "y": points.centerY
                                };
                                data.startDate = e.timeStamp;
                            }
                            var startPoint = data.startPoint;
                            $target.trigger('touchy-rotate', ['start', $target, {
                                "startPoint": startPoint,
                                    "movePoint": startPoint,
                                    "lastMovePoint": startPoint,
                                    "velocity": 0,
                                    "degrees": 0
                            }]);
                            break;
                    }
                }
            }
        },

        handleTouchMove: function (e) {
            var eventType = this.context,
                $target = getTarget(e, eventType);

            if ($target) {
                var event = e.originalEvent,
                    touches = event.targetTouches,
                    camelDataName = 'touchy' + eventType.charAt(0).toUpperCase() + eventType.slice(1),
                    data = $target.data(camelDataName),
                    settings = data.settings;

                if (settings.preventDefault.move) {
                    event.preventDefault();
                }

                if (settings.stopPropagation.move) {
                    event.stopPropagation();
                }

                if (touches.length === settings.requiredTouches) {
                    switch (eventType) {
                        case 'rotate':
                            var lastMovePoint,
                            lastMoveDate,
                            movePoint,
                            moveDate,
                            lastMoveDate,
                            distance,
                            ms,
                            velocity,
                            targetPageCoords,
                            centerCoords,
                            radians,
                            degrees,
                            lastDegrees,
                            degreeDelta;

                            lastMovePoint = data.lastMovePoint = data.movePoint || data.startPoint;
                            lastMoveDate = data.lastMoveDate = data.moveDate || data.startDate;
                            movePoint = data.movePoint = {
                                "x": touches[0].pageX,
                                    "y": touches[0].pageY
                            };
                            moveDate = data.moveDate = e.timeStamp;

                            if (touches.length === 1) {
                                targetPageCoords = data.targetPageCoords = data.targetPageCoords || getViewOffset(e.target);
                                centerCoords = data.centerCoords = data.centerCoords || {
                                    "x": targetPageCoords.x + ($target.width() * 0.5),
                                        "y": targetPageCoords.y + ($target.height() * 0.5)
                                };
                            } else {
                                var points = getTwoTouchPointData(e);
                                centerCoords = data.centerCoords = {
                                    "x": points.centerX,
                                        "y": points.centerY
                                };
                                if (hasGestureChange()) {
                                    break;
                                }

                            }
                            radians = Math.atan2(movePoint.y - centerCoords.y, movePoint.x - centerCoords.x);
                            lastDegrees = data.lastDegrees = data.degrees;
                            degrees = data.degrees = radians * (180 / Math.PI);
                            degreeDelta = lastDegrees ? degrees - lastDegrees : 0;
                            ms = moveDate - lastMoveDate;
                            velocity = data.velocity = ms === 0 ? 0 : degreeDelta / ms;

                            $target.trigger('touchy-rotate', ['move', $target, {
                                "startPoint": data.startPoint,
                                    "startDate": data.startDate,
                                    "movePoint": movePoint,
                                    "lastMovePoint": lastMovePoint,
                                    "centerCoords": centerCoords,
                                    "degrees": degrees,
                                    "degreeDelta": degreeDelta,
                                    "velocity": velocity
                            }]);
                            break;
                    }
                }
            }
        },

        handleGestureChange: function (e) {
            var eventType = this.context,
                $target = getTarget(e, eventType);

            if ($target) {
                var $target = $(e.target),
                    event = e.originalEvent,
                    touches = event.touches,
                    camelDataName = 'touchy' + eventType.charAt(0).toUpperCase() + eventType.slice(1),
                    data = $target.data(camelDataName);

                if (data.preventDefault.move) {
                    event.preventDefault();
                }

                if (settings.stopPropagation.move) {
                    event.stopPropagation();
                }

                switch (eventType) {
                    case 'rotate':
                        var lastDegrees = data.lastDegrees = data.degrees,
                            degrees = data.degrees = event.rotation,
                            degreeDelta = lastDegrees ? degrees - lastDegrees : 0,
                            ms = data.moveDate - data.lastMoveDate,
                            velocity = data.velocity = ms === 0 ? 0 : degreeDelta / ms;
                        $target.trigger('touchy-rotate', ['move', $target, {
                            "startPoint": data.startPoint,
                                "startDate": data.startDate,
                                "movePoint": data.movePoint,
                                "lastMovePoint": data.lastMovePoint,
                                "centerCoords": data.centerCoords,
                                "degrees": degrees,
                                "degreeDelta": degreeDelta,
                                "velocity": velocity
                        }]);
                        break;
                }
            }
        },

        handleTouchEnd: function (e) {
            var eventType = this.context,
                $target = getTarget(e, eventType);

            if ($target) {
                var event = e.originalEvent,
                    camelDataName = 'touchy' + eventType.charAt(0).toUpperCase() + eventType.slice(1),
                    data = $target.data(camelDataName),
                    settings = data.settings;

                if (settings.preventDefault.end) {
                    event.preventDefault();
                }
                if (settings.stopPropagation.end) {
                    event.stopPropagation();
                }

                switch (eventType) {
                    case 'rotate':
                        var degreeDelta = data.lastDegrees ? data.degrees - data.lastDegrees : 0;
                        $target.trigger('touchy-rotate', ['end', $target, {
                            "startPoint": data.startPoint,
                                "startDate": data.startDate,
                                "movePoint": data.movePoint,
                                "lastMovePoint": data.lastMovePoint,
                                "degrees": data.degrees,
                                "degreeDelta": degreeDelta,
                                "velocity": data.velocity
                        }]);
                        $.extend(data, {
                            "startPoint": null,
                                "startDate": null,
                                "movePoint": null,
                                "moveDate": null,
                                "lastMovePoint": null,
                                "lastMoveDate": null,
                                "targetPageCoords": null,
                                "centerCoords": null,
                                "degrees": null,
                                "lastDegrees": null,
                                "velocity": null
                        });
                        break;
                }
            }
        }

    },
    ensureSingularStartData = function (data, touches, timeStamp) {
        if (!data.startPoint) {
            data.startPoint = {
                "x": touches[0].pageX,
                    "y": touches[0].pageY
            }
        }
        if (!data.startDate) {
            data.startDate = timeStamp;
        }
    },

    hasGestureChange = function () {
        return (typeof window.ongesturechange == "object");
    },

    getTarget = function (e, eventType) {
        var $delegate,
        $target = false,
            i = 0,
            len = boundElems[eventType].length
        if ($.touchyOptions.useDelegation) {
            for (; i < len; i += 1) {
                $delegate = $(boundElems[eventType][i]).has(e.target);
                if ($delegate.length > 0) {
                    $target = $delegate;
                    break;
                }
            }
        } else if (boundElems[eventType] && boundElems[eventType].index(e.target) != -1) {
            $target = $(e.target)
        }
        return $target;
    },

    getViewOffset = function (node, singleFrame) {

        function addOffset(node, coords, view) {
            var p = node.offsetParent;
            coords.x += node.offsetLeft - (p ? p.scrollLeft : 0);
            coords.y += node.offsetTop - (p ? p.scrollTop : 0);

            if (p) {
                if (p.nodeType == 1) {
                    var parentStyle = view.getComputedStyle(p, '');
                    if (parentStyle.position != 'static') {
                        coords.x += parseInt(parentStyle.borderLeftWidth);
                        coords.y += parseInt(parentStyle.borderTopWidth);

                        if (p.localName == 'TABLE') {
                            coords.x += parseInt(parentStyle.paddingLeft);
                            coords.y += parseInt(parentStyle.paddingTop);
                        } else if (p.localName == 'BODY') {
                            var style = view.getComputedStyle(node, '');
                            coords.x += parseInt(style.marginLeft);
                            coords.y += parseInt(style.marginTop);
                        }
                    } else if (p.localName == 'BODY') {
                        coords.x += parseInt(parentStyle.borderLeftWidth);
                        coords.y += parseInt(parentStyle.borderTopWidth);
                    }

                    var parent = node.parentNode;
                    while (p != parent) {
                        coords.x -= parent.scrollLeft;
                        coords.y -= parent.scrollTop;
                        parent = parent.parentNode;
                    }
                    addOffset(p, coords, view);
                }
            } else {
                if (node.localName == 'BODY') {
                    var style = view.getComputedStyle(node, '');
                    coords.x += parseInt(style.borderLeftWidth);
                    coords.y += parseInt(style.borderTopWidth);

                    var htmlStyle = view.getComputedStyle(node.parentNode, '');
                    coords.x -= parseInt(htmlStyle.paddingLeft);
                    coords.y -= parseInt(htmlStyle.paddingTop);
                }

                if (node.scrollLeft) coords.x += node.scrollLeft;
                if (node.scrollTop) coords.y += node.scrollTop;

                var win = node.ownerDocument.defaultView;
                if (win && (!singleFrame && win.frameElement)) addOffset(win.frameElement, coords, win);
            }
        }

......请参阅 JS Fiddle 上的其余内容

4

0 回答 0