#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-элемент готовы к использованию перед отправкой данных