2

I have a search-filter div offcanvas, like the location, property type etc on this page: https://finder.createx.studio/real-estate-catalog-rent.html

On desktop devices (=>lg) , it displays the "offcanvas" permanently, on mobile (<lg) it is hidden "off canvas" and can be toggled using a button. That all works great.

When the page loads, IF the offcanvas element is actually offcanvas (ie <lg), I want to run some javascript to display it (after another business logic check, out of scope for this post).

How can I do that?

Something like this:

var myOffcanvas = document.getElementById('filters-sidebar');
var bsOffcanvas = new bootstrap.Offcanvas(myOffcanvas);
var myCustomBusinessLogicCheck = true;
var isTheOffcanvasActuallyOffCanvasRightNow = ?? //detect if offcanvas element is currently actually off-canvas

if (isTheOffcanvasActuallyOffCanvasRightNow  & myCustomBusinessLogicCheck) {
    bsOffcanvas.show();
}

What I tried:

  • I tried looking for the *.bs.offcanvas events - but they do not fire when the page first loads (and the offcanvas initially "hides"), only on subsequent interactions.
  • Looked at the _isShown property of bsOffcanvas - but it returns "false" on desktop, so it seems I can't use that.
  • Poked around other properties on bsOffcanvas but didn't find anything obvious
  • I could maybe track if an element with d-lg-none is visible or not, but it feels hacky. However, it will be my fallback if I do not find a cleaner way.
Kjensen
  • 12,447
  • 36
  • 109
  • 171
  • 1
    Checking if an element is off canvas seems equivalent to [Check if element is visible in DOM](https://stackoverflow.com/questions/19669786/check-if-element-is-visible-in-dom). So you could use `var isTheOffcanvasActuallyOffCanvasRightNow = myOffcanvas.offsetParent === null;` – Tom Dec 17 '21 at 09:58
  • Boom, that worked. Create a repsonse, and I will give you the bounty. :) – Kjensen Dec 17 '21 at 11:06

2 Answers2

2

Checking if an element is off canvas seems equivalent to Check if element is visible in DOM.

So you could use :

var isTheOffcanvasActuallyOffCanvasRightNow = myOffcanvas.offsetParent === null;
Tom
  • 4,972
  • 3
  • 10
  • 28
1

You can monitor media change using Window.matchMedia() :

var lgBreakpoint, content;

document.addEventListener('DOMContentLoaded', init);

function init() {
  content = document.getElementById('content');

  lgBreakpoint = window.matchMedia("(min-width: 992px)");
  handleChange(lgBreakpoint)
  lgBreakpoint.addListener(handleChange)
}

function handleChange(bp) {
  if (bp.matches) {
    content.innerText = "visible";
    content.style.backgroundColor = 'pink';
  } else {
    content.innerText = "collapsed";
    content.style.backgroundColor = 'lightgreen';
  }
}
@media (min-width: 992px) {
  .offcanvas-collapse {
    display: block;
    position: static;
    top: auto !important;
    right: auto !important;
    bottom: auto !important;
    left: auto !important;
    width: 100% !important;
    max-width: 100% !important;
    /*height: auto !important;*/
    transform: none !important;
    background-color: transparent;
  }
}

.offcanvas-start {
  top: 0;
  left: 0;
  width: 21rem !important;
  border-right: 0 solid transparent;
  transform: translateX(-100%);
}

.offcanvas {
  will-change: transform, box-shadow;
  transition: transform .4s cubic-bezier(0.165, 0.84, 0.44, 1), box-shadow .3s ease;
  box-shadow: none;
  visibility: visible !important;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">

<div class="container-fluid mt-5 pt-5 p-0 vh-100">
  <div class="row g-0 mt-n3">
    <!-- Filters sidebar (Offcanvas on mobile)-->
    <aside class="col-lg-4 col-xl-3 border-top-lg border-end-lg shadow-sm px-3 px-xl-4 px-xxl-5 pt-lg-2">
      <div class="offcanvas offcanvas-start offcanvas-collapse bg-info vh-100" id="filters-sidebar">
        Filters
      </div>
    </aside>
    <!-- Page content-->
    <div id=content class="col-lg-8 col-xl-9 position-relative overflow-hidden pb-5 pt-4 px-3 px-xl-4 px-xxl-5 vh-100">
      Main content
    </div>
  </div>
</div>

View output in full-page mode and resize the browser window.

the Hutt
  • 16,980
  • 2
  • 14
  • 44