-2

So, I have an array of tabs in an overflow auto container (the tabs const) and I want to filter them to get the last visible one. My idea is to take the x value of the container (overflowWrapperRight) and get the tab whose left side is less than that value and whose right side is greater than that value. The problem is that I get the message that my filter is not a function. Maybe it´s a silly mistake, but I'm stuck.

const overflowWrapperRight =
  wrapper.getBoundingClientRect().x + wrapper.getBoundingClientRect().width;
const current = wrapper.scrollLeft;

const tabs = document.querySelectorAll('#tablistPanel .singleTab');

const lastVisibleTab = tabs.filter(
  tab =>
  tab.getBoundingClientRect().left < overflowWrapperRight &&
  tab.getBoundingClientRect().right > overflowWrapperRight
);

I should get the single tab which matches that criteria.

Eddie
  • 26,593
  • 6
  • 36
  • 58
ElDuderino
  • 91
  • 1
  • 2
  • 11
  • `document.querySelectorAll` returns a NodeList, not an Array. –  Apr 23 '19 at 15:11
  • `querySelectorAll` returns a `NodeList`, not an array – Daniel A. White Apr 23 '19 at 15:11
  • see https://www.w3schools.com/jsref/met_document_queryselectorall.asp – Junius L Apr 23 '19 at 15:11
  • that means `tabs` has no `filter` prototype. `querySelectorAll` returns a NodeList. NodeLists are **iterable** but do **not** have a `filter` prototype, you need to use `[].filter.apply` or spread results to a regular array to work with it. https://developer.mozilla.org/en-US/docs/Web/API/NodeList – briosheje Apr 23 '19 at 15:11
  • 3
    @JuniusL. Please do not use, recommend or link to w3schools. –  Apr 23 '19 at 15:11
  • @ChrisG why do you say so? – Junius L Apr 23 '19 at 15:13
  • 1
    @JuniusL. https://meta.stackoverflow.com/questions/280478/why-not-w3schools-com (please remove the link as it will boost the site) –  Apr 23 '19 at 15:13
  • @ChrisG while w3schools may not be the best authority for documentation, their content can be helpful. Regardless, it's not your place to tell people what sources they can recommend. – Sterling Archer Apr 23 '19 at 15:14
  • 1
    @SterlingArcher That's why I said "please"... –  Apr 23 '19 at 15:14
  • @ChrisG please read the answer on that question. – Junius L Apr 23 '19 at 15:14
  • Please simply makes your request polite, but the message stays the same. – Sterling Archer Apr 23 '19 at 15:15
  • Regardless, it's not relevent to the question at all. The comments section of a question isn't the place to push an agenda. – Cereal Apr 23 '19 at 15:17

1 Answers1

-1

That's because Element#querySelectorAll returns a NodeList rather than an array.

You can easily convert a nodelist into an array using spreading, like so:

const overflowWrapperRight =
  wrapper.getBoundingClientRect().x + wrapper.getBoundingClientRect().width;
const current = wrapper.scrollLeft;

const tabs = document.querySelectorAll('#tablistPanel .singleTab');

const lastVisibleTab = [...tabs].filter(
  tab =>
  tab.getBoundingClientRect().left < overflowWrapperRight &&
  tab.getBoundingClientRect().right > overflowWrapperRight
);

You could also achieve the same using Array.from like so:

const lastVisibleTab = Array.from(tabs).filter(
  tab =>
  tab.getBoundingClientRect().left < overflowWrapperRight &&
  tab.getBoundingClientRect().right > overflowWrapperRight
);

Finally, there's is the ES5 compatible way using Array#slice , like so:

const lastVisibleTab = Array.prototype.slice.call(tabs).filter(
  tab =>
  tab.getBoundingClientRect().left < overflowWrapperRight &&
  tab.getBoundingClientRect().right > overflowWrapperRight
);
nick zoum
  • 7,216
  • 7
  • 36
  • 80