Alex-D / Cookies-EU-banner

1kb vanilla JS script which manages cookies consent banner display like asked by GDPR
http://alex-d.github.io/Cookies-EU-banner/
MIT License
441 stars 57 forks source link

Respecting waitRemove on this.hasConsent() === false #51

Closed reinoldus closed 4 years ago

reinoldus commented 4 years ago

Hi, I am using your lib with nuxt and when consent was rejected the banner is removed immediately. Problem is that vue rerenders the entire page, because vnodes and html differ.

For me it would be even better to "just" leave the element there, if that would be configurable, would be awesome.

If you agree with these changes I could prepare a pull request

Alex-D commented 4 years ago

Did you mount your app on body? If yes, try to mount it to a specific div on the page.

What did you mean by "leave the element there"? Just a display none but keep it in DOM?

reinoldus commented 4 years ago

Hi, yes that is what I meant keep it in the DOM.

What do you mean mount your app on body? I am using nuxt, so I can't really decide where to mount the app.

reinoldus commented 4 years ago

Okay this conversation gave me an idea:

I wrapped the div in <client-only> Tag: https://nuxtjs.org/api/components-client-only/

import CookiesEuBanner from 'cookies-eu-banner'

function waitForElement(selector) {
// copied from here: https://paul.kinlan.me/waiting-for-an-element-to-be-created/
  return new Promise(function(resolve, reject) {
    const element = document.querySelector(selector)

    if (element) {
      resolve(element)
      return
    }

    var observer = new MutationObserver(function(mutations) {
      mutations.forEach(function(mutation) {
        const nodes = Array.from(mutation.addedNodes)
        for (const node of nodes) {
          if (node.matches && node.matches(selector)) {
            observer.disconnect()
            resolve(node)
            return
          }
        }
      })
    })

    observer.observe(document.documentElement, {
      childList: true,
      subtree: true
    })
  })
}
waitForElement('#cookies-eu-banner').then(function(element) {
  CookiesEuBanner(function() {
    // Your code to launch when user accept cookies

    const checkExist = setInterval(function() {
// wait for segment js to be loaded
      try {
        window.analytics.load('segment-write-key', {
          integrations: { All: true }
        })
        clearInterval(checkExist)
      } catch (e) {}
    }, 100)
  }, true)
})

Then I have to wait for the div to be rendered though using the function from here: https://paul.kinlan.me/waiting-for-an-element-to-be-created/

I can live with this solution. Just leaving this here for reference