javascript picking wrong time from div

Asked

Viewed 76 times

-2

I’m developing a script in js (vanilla), to make it easier to put Whatsapp, and other forms of chat on the site. It is still under development and will have some more features, but I’m stuck at a point.

When I try to get the height of the div document.querySelector('.chatsPopUpUl').clientHeight, the return height is much lower than the real one, if I run the same command after the site is loaded the return height is higher.clientHeight

You can see in the gif above which returns document.querySelector('.').clientHeight, but when I search for the same command after the site is loaded, the return value is 100.
This is the class:

class chatsPopUp
{
    MainClass;
    elClass;
    elC = []
    elChats = [];
    duration;

    setElChats(...el)
    {
        for(let i = 0; i < el.length; i++) {
            this._setElChat = el[i];
        }
    }

    // Cria os elementos na tela, seta a largura e alinha verticalmente
    _createEl()
    {
        this.getElClass.insertAdjacentHTML('beforeend', '<ul class="chatsPopUpUl"></ul>');
        let ul = document.querySelector('.chatsPopUpUl');

        for(let i = 0; i < this.getElChats.length; i++) {
            ul.insertAdjacentHTML('beforeend', `<li><i class="icofont-${this.getElChats[i]} SMElPopUp SMElPopUp-${this.getElChats[i]}"></i></li>`); 
            this.elC.push(document.querySelector(`.SMElPopUp-${this.getElChats[i]}`));
        }

        // Definindo a largura total do slider
        ul.style.width = (this.getElChats.length) * 100 + '%';
        // Centralizando verticalmente elementos na div
        console.log(ul)
        document.querySelector('.chatsPopUpUl')
        console.log(document.querySelector('.chatsPopUpUl').clientHeight)

        console.log(this.elClass)
        console.log(this.elClass.clientHeight)
        ul.style.marginTop = -ul.offsetHeight/2 + 'px';

        //Chamando para deslizar
        this._slideEl();
    }


    // Faz os elementos ficarem em slide
    _slideEl()
    {

        let slide = 0;
        let arr = [
        { transform: `translateX(${slide}%)` },
        { transform: `translateX(${slide}%)`, easing: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)' }
        ];
        let slidePercentage = 100/this.getElChats.length
        for(let i = 0; i < this.getElChats.length-1; i++) {
            slide -= slidePercentage;
            arr.push({ transform: `translateX(${slide}%)`, easing: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)'});
            arr.push({ transform: `translateX(${slide}%)`, easing: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)'});
        }
        arr.push({ transform: 'translateX(0%)', easing: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)'});

        document.querySelector('.chatsPopUp ul').animate(arr,{    
            duration: 3000,
            iterations: Infinity,
        });
    }


    // Métodos Especiais
    constructor(classe, duration, ...chats) 
    {
       this.setMainClasse = classe;
       this.setElClasse = classe;
       this.setElChats(...chats);
       this._createEl();
       this.setDuration = duration;
    }

    get getElClass() 
    {
        return this.elClass;
    }

    get getElC() 
    {
        return this.elC;
    }

    set setElClasse(classe) 
    {
        return this.elClass = document.querySelector(`.${classe}`);
    }        

    get getMainClass() 
    {
        return this.MainClass;
    }

    set setMainClasse(classe) 
    {
        return this.MainClass = classe;
    }

    get getElChats()
    {
        return this.elChats;
    }

    set _setElChat(elChats)
    {
        return this.elChats.push(elChats);
    }

    get getDuration() 
    {
        return this.duration;
    }

    set setDuration(duration) 
    {
        return this.duration = duration;
    }
}

The call in js is this:

let slide = new chatsPopUp('chatsPopUp',
                                1000,
                               'whatsapp','instagram','facebook-messenger'/*,'twitter',*/
                               );

And this is what html looks like

<div class="chatsPopUp"></div>

And the css is like this

body{
    background-color: #eee;
}
.chatsPopUp{
    background-color: white;
    width: 200px;
    height: 200px;
    border-radius: 100%;
    position: absolute;
    overflow: hidden;
}

/* Posicionamento */

.chatsPopUp.topLeft {
    left: 0px;
    top: 0px;
}

.chatsPopUp.topRight {
    right: 0px;
    top: 0px;
}


.chatsPopUp.bottomRight {
    right: 0px;
    bottom: 0px;
}

.chatsPopUp.bottomLeft {
    left: 0px;
    bottom: 0px;
}

.chatsPopUpUl {
    display: -webkit-flex; 
    display: flex; 
    padding: 0px;
    position: absolute;
    margin: 0px;
    top: 50%;
}


.chatsPopUpUl li{
    width: 100%;
    list-style: none;
    text-align: center;
}

.chatsPopUpUl li i{
    font-size: 100px;
}

2 answers

0

I was able to fix it, I don’t know if it was the best way I could, but it worked. I did the following, the problem occurred because the element was not entirely created even when the code pulled the size of it, and there was no way to use addeventlistener("Domcontentloaded",() ->{}), because the gift was already loaded, and whoever created the element was the code itself :

_createEl()
{
    this.getElClass.insertAdjacentHTML('beforeend', '<ul class="chatsPopUpUl"></ul>');
    let ul = document.querySelector('.chatsPopUpUl');

So the solution I found was, create a method that checks if the element is already created, and I keep checking every 100 milliseconds if the element really exists, and then when it exists it returns the Promisse resolve()

    checkExist(element)
{
    return new Promise((resolve, reject) => {
        let interval = setInterval(function() {
            if (element) {
                clearInterval(interval);
                return resolve();
            }else{
                console.log('elemento ainda não existe');
            }
        }, 100);
    });
}

and then before I get the height of the element, I call this function

this.checkExist(ul).then( e => {});

For those who want to see how the whole code turned out, it was like this:

    class chatsPopUp
{
    MainClass;
    elClass;
    elC = []
    elChats = [];
    duration;

    setElChats(...el)
    {
        for(let i = 0; i < el.length; i++) {
            this._setElChat = el[i];
        }
        console.log(this.duration)
    }

    checkExist(element)
    {
        return new Promise((resolve, reject) => {
            let interval = setInterval(function() {
                if (element) {
                    clearInterval(interval);
                    return resolve();
                }else{
                    console.log('elemento ainda não existe');
                }
            }, 100);
        });
    }

    // Cria os elementos na tela, seta a largura e alinha verticalmente
    _createEl()
    {
        this.getElClass.insertAdjacentHTML('beforeend', '<ul class="chatsPopUpUl"></ul>');
        let ul = document.querySelector('.chatsPopUpUl');

        for(let i = 0; i < this.getElChats.length; i++) {
            ul.insertAdjacentHTML('beforeend', `<li><i class="icofont-${this.getElChats[i]} SMElPopUp SMElPopUp-${this.getElChats[i]}"></i></li>`); 
            this.elC.push(document.querySelector(`.SMElPopUp-${this.getElChats[i]}`));
        }

        // Definindo a largura total do slider
        ul.style.width = (this.getElChats.length) * 100 + '%';
        // Centralizando verticalmente elementos na div
        this.checkExist(ul).then( e => {
            ul.style.marginTop = -ul.offsetHeight/2 + 'px';
        });

        //Chamando para deslizar
        this._slideEl();
    }


    // Faz os elementos ficarem em slide
    _slideEl()
    {

        let slide = 0;
        let arr = [
        { transform: `translateX(${slide}%)` },
        { transform: `translateX(${slide}%)`, easing: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)' }
        ];
        let slidePercentage = 100/this.getElChats.length;
        for(let i = 0; i < this.getElChats.length-1; i++) {
            slide -= slidePercentage;
            arr.push({ transform: `translateX(${slide}%)`, easing: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)'});
            arr.push({ transform: `translateX(${slide}%)`, easing: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)'});
        }
        arr.push({ transform: 'translateX(0%)', easing: 'cubic-bezier(0.680, -0.550, 0.265, 1.550)'});

        document.querySelector('.chatsPopUpUl').animate(arr,{    
            duration: this.duration,
            iterations: Infinity,
        });
    }


    // Métodos Especiais
    constructor(classe, duration, ...chats) 
    {
       this.setMainClasse = classe;
       this.setElClasse = classe;
       this.setDuration = duration;
       this.setElChats(...chats);
       this._createEl();
    }

    get getElClass() 
    {
        return this.elClass;
    }

    get getElC() 
    {
        return this.elC;
    }

    set setElClasse(classe) 
    {
        return this.elClass = document.querySelector(`.${classe}`);
    }        

    get getMainClass() 
    {
        return this.MainClass;
    }

    set setMainClasse(classe) 
    {
        return this.MainClass = classe;
    }

    get getElChats()
    {
        return this.elChats;
    }

    set _setElChat(elChats)
    {
        return this.elChats.push(elChats);
    }

    get getDuration() 
    {
        return this.duration;
    }

    set setDuration(duration) 
    {
        return this.duration = duration;
    }
}

0

document.querySelector('.chatsPopUpUl').getBoundingClientRect().height

If you try to rescue the dimensions of the element before the page is loaded it is very likely that the returned value will be incorrect, I suggest you run this code inside the window load event, but I realized that inside the container there is what seems to be an img element, then I suggest you assign a width/height to it as well.

  • I ran inside the load element of the window, and even then the error occurred, and it was due to the code itself creating the element and not the html, so running inside the load did not help. but I found a solution, thanks for the help.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.