Проблема с обработчиком событий при подаче HTML-диаграммы через код wix

#javascript #charts #eventhandler #velo

#javascript #Диаграммы #eventhandler #velo

Вопрос:

Я загружаю HTML-элемент (круговую диаграмму) на страницу wix. Я извлекаю данные из локального хранилища для 7 переменных и передаю информацию HTML-элементу через Postmessage.

Мой код отлично работает, когда он является частью кнопки (функция экспорта). Однако я хотел бы запустить событие из функции onReady (т. Е. при загрузке страницы). Я использую точно такой же код, но он просто не работает с функцией onReady (т. Е. Я не могу запустить событие программно).

Код страницы Wix для функции экспорта с помощью кнопки (работает нормально):

 export function button1_click(event) {
var data = [introdeo, intcalypso, intbalthazar, intluna, intkiara, intmistral, intsaya];
console.log(data);
var labels = ["Rodeo", "Calypso", "Balthazar", "Luna", "Kiara", "Mistral", "Saya"];
let info = {data:data, labels:labels};
$w("#html1").postMessage(info);
}
  

Код страницы Wix для функции onReady (не работает):

 $w.onReady(function () {
var data = [introdeo, intcalypso, intbalthazar, intluna, intkiara, intmistral, intsaya];
var labels = ["Rodeo", "Calypso", "Balthazar", "Luna", "Kiara", "Mistral", "Saya"];
let info = {data:data, labels:labels};
$w("#html1").postMessage(info); 

} );
  

HTML-код (код диаграммы в HTML-элементе на странице wix):

 <!DOCTYPE html>
<html lang="en-US">
<body>


<canvas id="myChart"></canvas>

<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>

<script type="text/javascript">


var ctx = document.getElementById('myChart').getContext('2d');
var myPieChart = new Chart(ctx,{
    type: 'pie',
    data: {
        labels:[],
        datasets: [{
            data: [],
            backgroundColor: ["#f97a03", "#52aff0", "#35a11d", "#f052e4", "#853fc2", "#f0f712", "#092978"],
        }]
    },
    options: {}
});

window.onmessage = function(event){
    myPieChart.data.datasets[0].data = event.data.data;
    myPieChart.data.labels = event.data.labels;
    myPieChart.update();
};

</script>

</body>
</html>
  

С помощью функции экспорта кнопок я получаю обновленную круговую диаграмму на своей веб-странице. С помощью готового кода я получаю пустое место в HTML-элементе.

Ответ №1:

Похоже, что html-элемент, возможно, не готов к приему этого сообщения. Попробуйте обернуть $w("#html1").postMessage(info); в setTimeout.

 $w.onReady(function () {
  var data = [introdeo, intcalypso, intbalthazar, intluna, intkiara, intmistral, intsaya];
  var labels = ["Rodeo", "Calypso", "Balthazar", "Luna", "Kiara", "Mistral", "Saya"];
  let info = {data:data, labels:labels};
  setTimeout(function() {
    $w("#html1").postMessage(info);
  }, 1000) 
});
  

Комментарии:

1. Я попробовал это, и изначально это сработало. Затем я опубликовал изменение, и оно больше не работает. Когда я нажимаю «предварительный просмотр», я ненадолго вижу диаграмму, а затем она исчезает. Также существует разница между режимом предварительного просмотра и текущим веб-сайтом. На веб-сайте live моя функциональная кнопка заполняет диаграмму, но с неправильными значениями. Что-то не так либо с кодом моей страницы, либо с HTML-кодом, либо с обоими!

2. Мне сложно говорить, не зная всего кода, который у вас там есть … но для меня все, что я сделал, это взял ваш код, вставил его, перенес установленное время ожидания, и это сработало, как ожидалось. В режиме предварительного просмотра и после публикации

3. Я изменил на 2000 миллисекунд, и это работает! Однако… Я получаю Calypso 0, Balthazar 5, Luna 1, Kiara 4, Mistral 2, Rodeo 8 и Saya 4 в режиме предварительного просмотра (что правильно) и Calypso 3, Balthazar 4, Luna 3, Kiara 6, Mistral 4, Rodeo 3 и Saya 0 на веб-сайте live, что неверно! Как это возможно? Спасибо,

4. Вы получаете переменные из локального хранилища, они могут отличаться в двух средах … мне сложно понять, не зная, как они установлены и т.д. Когда вы использовали свой кнопочный подход, я предполагаю, что данные были такими, как ожидалось?

5. Также — в качестве дополнительного примечания — вы находитесь в состоянии гонки с подходом setTimeout … 2 секунды всегда могут сработать, но может быть время, когда этого не произойдет. в идеале onReady не запускался бы, пока ваш iFrame не был готов.

Ответ №2:

Я предложу использовать обещание и разрешу обещание, когда HTML-компонент будет готов к использованию

Итак, в этом коде мы отправляем данные каждые 500 мс, чтобы проверить, готов ли HTML, и если он готов, обновляя глобальную переменную и разрешая обещание

 $w.onReady(()=>{
let isHTMLready = false;

    async function sendHTMLData() {
        await isHTMLReady(); // this line will wait until the HTML component is ready
        // then your code here
    }

    $w('#htmlID').onmessage(e=>{
        let {data} = e;
        if(data.isReady) {
            // html is ready 
            isHTMLReady = true; //updating the gloable variable
        } else if(data.someOtherCondition) {
            // do something
        }
    });

    function isHTMLReady() {
        return new Promise((res,rej)=>{
            let i = 0;
            let intervalID = setInterval(()=>{
                $w('#html').postMessage({
                    isHTMLReady : true
                });
                if(isHTMLready) { // checking if the global variable is changed to true
                    // stop the time interval
                    clearInterval(intervalID);
                    // resolve the promise
                    res("ready");
                }
                i  ;
                if(i > 28) { // waiting until 14 second before rejecting the promise
                    // rejecting the promise
                    rej("no response from HTML");
                }
            },500);
        });
    }
    
});  

в HTML-компоненте добавьте следующий код, он проверит, являются ли отправленные данные «isHTMLReady», затем (если HTML-компонент готов) мы отправим его обратно на сайт wix, оттуда мы обновим переменную, остановим интервал и разрешим обещание

 window.onmessage = e => {
    let {data} = e;
    if(data.isHTMLReady) {
        messageWixSite({isHTMLReady: true});
    }
    else if(data.isGraphData) {
        // write your code here
    }
}

function messageWixSite(data) {
    let msg = {
        "isCropper" : true,
    }
    msg = {...msg, ...data};
    // console.log("message : " , msg);
    window.parent.postMessage(msg, "*");
}  

Таким образом, мы гарантируем, что и сайт wix, и HTML-элемент готовы к использованию перед отправкой данных