Коснитесь перемещать огонь только один раз при реализации «меньше», как прокрутка на мобильном - PullRequest
7 голосов
/ 26 февраля 2020

Я пытаюсь реализовать сенсорную прокрутку в меньшем расширении до jQuery Терминал. Она работает аналогично команде unix.

У меня есть этот код:

self.touch_scroll(function(event) {
    // how much difference changed since last touch move
    var delta = event.current.clientY - event.previous.clientY;
    var ret;
    var interpreter = interpreters.top();
    if (is_function(interpreter.touchscroll)) {
        ret = interpreter.touchscroll(event, delta, self);
    } else if (is_function(settings.touchscroll)) {
        ret = settings.touchscroll(event, delta, self);
    }
    if (ret === true) {
        return;
    }
    return false;
});
// make_callback_plugin is helper that use $.Callbacks and make sure that there is only
// one handler on the element
$.fn.touch_scroll = make_callback_plugin({
    name: 'touch',
    init: function(handler) {
        var origin;
        var previous;
        $(this).on('touchstart.scroll', function(e) {
            e = e.originalEvent;
            if (e.touches.length === 1) {
                previous = origin = e.touches[0];
            }
        }).on('touchmove.scroll', function(e) {
            e = e.originalEvent;
            console.log(!!origin + ' && ' + (e.touches.length) + ' === 1');
            if (origin && e.touches.length === 1) {
                var current = e.touches[0];
                var ret = handler({
                    origin: origin,
                    previous: previous,
                    current: current
                });
                if (ret === false) {
                    // this don't change anything
                    e.preventDefault();
                }
                previous = current;
            }
        }).on('touchend.scroll', function() {
            if (origin || previous) {
                origin = previous = null;
            }
        });
    },
    destroy: function() {
        $(this).off('touchstart.scroll touchmove.scroll touchend.scroll');
    }
});

, а внутри меньше у меня:

    function scroll(delta, scroll_by) {
        if (delta > 0) {
            pos -= scroll_by;
            if (pos < 0) {
                pos = 0;
            }
        } else {
            pos += scroll_by;
            if (pos - 1 > lines.length - rows) {
                pos = lines.length - rows + 1;
            }
        }
        print();
        return true;
    }
    term.push($.noop, {
        onResize: refresh_view,
        touchscroll: function(event, delta) {
            console.log({delta});
            var offset = Math.abs(delta);
            // 14 is default height of single line in pixels
            scroll(delta, Math.ceil(offset / 14));
            return false;
        },
        mousewheel: function(event, delta) {
            return scroll(delta, scroll_by);
        }, 

У меня также есть это css:

.terminal-less {
    touch-action: none;
    overscroll-behavior-y: contain;
}

при прокрутке колесика мыши хорошо работает, она прокручивается с тем же количеством scroll_by, которое по умолчанию равно 3 (кажется, справа). (pos - смещение строк, поэтому, если я использую pos ++, он перемещается / прокручивается на одну строку, дельта в сенсорной прокрутке является положительной или отрицательной величиной примерно от -20 до 20 пикселей.

Проблема у меня возникла, и вопрос в том, как можно Я заставляю его прокручивать пальцем - он не чувствует себя хорошо. Кроме того, он прокручивается только после того, как он не двигается пальцем. Сенсорный ход срабатывает только один раз, не должен ли он срабатывать, пока я двигаю пальцем, касаясь телефона?

Кто-нибудь имел опыт работы с этим типом сенсорной прокрутки?

Я искал похожую проблему и не нашел решения. Знаете ли вы, почему сенсорное движение может срабатывать один раз? Единственное, о чем я могу думать of был textarea, который используется в качестве буфера обмена (на мобильном телефоне он также используется для включения виртуальной клавиатуры), но я установил фон на красный, и он не перемещается на Android. Я тестировал другой код из этой демонстрационной версии чертежа:

https://zipso.net/a-simple-touchscreen-sketchpad-using-javascript-and-html5/

и все работает нормально, сенсорное движение продолжает срабатывать, пока вы двигаете пальцем.

Есть идеи? Будет трудно воспроизвести но если somone заинтересован в расследовании, я могу поместить весь свой код на github в jQuery Terminal repo (в какой-то ветке).

Что странно, что touchend не срабатывает после touchmove, он срабатывает только один раз, когда я щелкните на терминале, чтобы включить клавиатуру.

Я пытался включить / выключить jQuery и регистрировать каждый раз, когда он запускается, но у меня не было никаких других событий (которые могут помешать поведению по умолчанию) также в соответствии с события мыши документируются после касания, а те не запускаются.

1 Ответ

4 голосов
/ 05 марта 2020

То, что вам нужно, это просто .terminal-wrapper { pointer-events: none; } (на основе ветви devel) . Но с этим правилом вы не можете выбрать текст, поэтому вам нужно использовать его только для мобильных устройств.

Я не уверен, что это заблокирует выбор текста на мобильном телефоне, но если это так, вы можете попробовать добавить это на touchstart (или даже на touchmove в качестве первой инструкции) и удалить его на touchend.

Также, Мне пришлось добавить код JS, потому что без него interpreter.touchScroll - это undefined. Но это не главная причина проблемы.

interpreters = new Stack($.extend({}, settings.extra, {
    name: settings.name,
    prompt: prompt,
    keypress: settings.keypress,
    keydown: settings.keydown,
    resize: settings.onResize,
    greetings: settings.greetings,
    mousewheel: settings.mousewheel,
    touchScroll: settings.touchScroll, // NEW LINE
    history: settings.history,
    keymap: new_keymap
}, interpreter));
self.touch_scroll(function(event) {
    var delta = event.current.clientY - event.previous.clientY;
    var ret;
    var interpreter = interpreters.top(); // NEW LINE
    if (is_function(interpreter.touchScroll)) {
        ret = interpreter.touchScroll(event, delta, self);
    } else if (is_function(settings.touchScroll)) {
        ret = settings.touchScroll(event, delta, self);
    }
    if (ret === true) {
        return;
    }
});

Без pointer-events: none;

enter image description here

С pointer-events: none;

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...