ShoppingList i wprowadzanie produktów głosem błedy

0

Witam. Tworzę shoppingList w czystym JS i aktualnie koduje wprowadzanie produktów głosem(SpeechRecognition) . Udało mi się jako tako zaimplementować kod i to działa, ale jest kilka błedów z którymi nie potrafię sobie poradzić. Mianowicie: gdy wprowadzę kilka produktów głosem (trzeba po prostu robić sekundowe przerwy po każdym produkcie) i chcę zatrzymać wprowadzanie głosem(przycisk stop speak) to wprowadzanie głosem zatrzymuje się owszem, ale dopiero po usłyszeniu i wprowadzeniu jeszcze jednego produktu, a nie od razu po naciśnięciu klawisza. Druga sprawa. Gdy wprowadzę produkty głosem , później je zastopuje i znowu będę chcieć coś wprowadzić głosem to ten produkt pojawi się podwójnie, a jak jeszcze raz zatrzymam i uruchomię to następny wprowadzi się potrójnie itd. Poniżej umieszczam kod js odpowiadający za tą funkcjonalność i live demo aplikacji do przeklikania. z góry dzięki za pomoc, bo dłuższy czas nie mogę dojść jak to naprawić : live demo: https://jakubsoldek.github.io/ShoppingList/

window.SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;

const recognition = new SpeechRecognition();
recognition.interimResults = true;
recognition.lang = 'pl-PL';

let click = false;

speechBtn.addEventListener('click', addProductViaSpeech);
stopSpeechBtn.addEventListener('click', function () {

    click = !click;
    console.log(click);
    console.log(recognition);
})

recognition.addEventListener('end', () => click ? recognition.stop() : recognition.start());


function addProductViaSpeech(event) {
    event.preventDefault();
    console.log("dziala chwile");
    // recognition.stop();
    recognition.start();
    recognition.addEventListener('result', e => {
        const transcript = Array.from(e.results).map(result => result[0]).map(result => result.transcript).join('');
        console.log(transcript);
        if (e.results[0].isFinal) {
            const productDiv = document.createElement("div");
            productDiv.classList.add("product");

            const newProduct = document.createElement('li');
            newProduct.innerText = transcript;
            newProduct.classList.add('product-text');

            productDiv.appendChild(newProduct);
            //local storage
            console.log(newProduct.innerText);
            saveLocalTodos(newProduct.innerText);

            const productPrice = document.createElement("li");
            productPrice.classList.add("product-price");
            const priceProductInput = document.createElement("input");
            priceProductInput.classList.add("price-product-input");
            // console.log(priceProductInput);
            priceProductInput.placeholder = "$";
            productDiv.appendChild(productPrice);
            productPrice.appendChild(priceProductInput);

            const trashButton = document.createElement("button");
            trashButton.innerHTML = '<i class="fas fa-times"></i>';
            trashButton.classList.add("trash-btn");
            productDiv.appendChild(trashButton);
            productList.appendChild(productDiv);

            productInput.value = "";

            quantityJs++;
            quantity.innerText = quantityJs;

            productInput.classList.add("warning");
            productInput.placeholder = "can't be empty";

            for (let i = 0; i < arr.length; i++) {
                // console.log(arr[i]);
                arr[i].addEventListener('change', findTotal);
            }
        }
    });
}
1

Ja tu widzę:

  • dodawanie event listenera, którego nigdy nie usuwasz. Za to dodajesz go za każdym uruchomieniem rozpoznawania od nowa. Stąd biorą się duplikaty:
  • brak wywołania "recognition.stop()" zaraz po kliknięciu przycisku zatrzymującego - stąd bierze się to, że po kliknięciu nadal przez chwilę można mówić
  • przycisk stop odwraca zmienną click (btw: bardzo zła nazwa, nazwij to "keepRecognitionEnabled" czy coś w tym stylu) - jego wielokrotne wciskanie poniekąd włącza/wyłącza rozpoznawanie - wciśnij go dwa razy i rozpoznawanie będzie działać nadal. Przycisk start powinien przypisywać true, przycisk stop powinien przypisywać false. Żadnego odwracania.
0

@dzek69: Dziękuje za opdowiedź. Poprawiłem 2 i 3 podpunkt z twojej odpowiedzi, ale ciągle borykam się z pierwszym(duplikacja wprowadzonych produktów głosem po zastopowaniu i ponownej próbie dodania nowych. Mógłbyś wskazać o który listener chodzi albo jakoś mnie nakierować? Próbowałem już ze wszystkimi za pomocą np: removeEventListener, ale ciągle nie mogę rozwiązać problemu :/

0

Pamiętaj, że jeżeli chcesz usunąć event listener musisz wskazać który, tj. musisz przekazać TĘ SAMĄ funkcję co przekazałeś w addEventListener - dlatego musisz ją wyciągnąć do zmiennej.

Jeżeli powyższe Ci nie pomaga to wrzuć zaktualizowany kod z próbą użycia removeEventListener

1 użytkowników online, w tym zalogowanych: 0, gości: 1