1

I have some code that generally works, except on iPhone. When the window loads, this function is called. When I have the event as click, it works just fine on desktop, but not on mobile. I've tried looking around for solutions for mobile, and touchstart seems to be the recommended solution. But, though it works on emulators, it doesn't work on iPhone (tested on the latest OS version). Am I missing something?

function addXClassOnClick() {
  var els = document.getElementsByClassName('item');

  Array.prototype.forEach.call(els, function(el) {
    el.addEventListener('touchstart', function() {
      el.parentElement.classList.toggle('x');
    }, false);
  });
}

Thanks in advance!

Cassidy
  • 3,328
  • 5
  • 39
  • 76
  • Id include the mobile safari version you are on since it seems relevant. `getElementsByClassName` was introduced in ios safari 9.2 which was released in December for example. – omoman Aug 29 '16 at 02:59
  • @omoman added it! It's all on the latest stuff that I'm testing right now. – Cassidy Aug 29 '16 at 03:39

2 Answers2

1

Probably a duplicate of this SO question.

If you're using an <a> tag, everything will work as expected on iPhones and other touch devices. Otherwise, you should add CSS to whatever element with style cursor: pointer;.

Community
  • 1
  • 1
IMcD23
  • 445
  • 1
  • 7
  • 13
1

Given the document fragment:

<div class="x">
    <div class="item">Item</div>
</div>

The anonymous event handler function's default scope is bound to the clicked element, and not to the clicked element's parent, which is the scope that classList.toggle should operate on.

(edit: According to the documentation, forEach passes undefined in as the scope of the callback function when not specified. The DOM element reference el has no scope to operate in. It's like the DOM is there, but the scope chain isn't.)

To fix this, either call classList.toggle with the correct scope:

el.parentElement.classList.toggle.call(el.parentElement.classList, 'x');

or call forEach with the desired scope as a second argument:

Array.prototype.forEach.call(els, function(el) {
    // omit
}, els);
James Tikalsky
  • 3,856
  • 1
  • 21
  • 12