akiran / react-slick

React carousel component
http://react-slick.neostack.com/
MIT License
11.72k stars 2.1k forks source link

Events do not occur when linking images to iOS. #1190

Open ryoma2na opened 6 years ago

ryoma2na commented 6 years ago

When marking up img tag with anchor link, hyperlink event is canceled only on iOS, is this in the specifications?

// Example
<Slider>
  <div><a href=""><img src=""></a></div>
  <div><a href=""><img src=""></a></div>
</Slider>

The following if statement is seemed to be the cause of the problem.

https://github.com/akiran/react-slick/blob/90bc26c52ca8cb879f26214b9a9a9cd6621b10d7/src/utils/innerSliderUtils.js#L307

In the current situation, not only image links but also onClick events can not be used, so we want at least a click event to be allowed.

marzelin commented 6 years ago

Have you tried setting pointer-events: none on the images? It might help.

jeremiah-s-eldridge commented 6 years ago

@marzelin unfortunately if you want to assign a click handler directly to the img then this is still an issue

LiamKenneth commented 6 years ago

I ran into this issue.

It seems this line: https://github.com/akiran/react-slick/blob/90bc26c52ca8cb879f26214b9a9a9cd6621b10d7/src/utils/innerSliderUtils.js#L307

Stops the user from clicking a link that wraps an image. I originally removed the line as pointer-events: none made no difference.

By taking that line out you loose the ability to scroll the slider using the mouse pointer.

So my next solution which seems to have worked is to detect if it's not a mobile device to run this line e.target.tagName === 'IMG' && e.preventDefault()

const isMobileDevice = () => {
  return (typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
};

if (!isMobileDevice()) {
    e.target.tagName === 'IMG' && e.preventDefault()
  }
pmgmendes commented 6 years ago

Had the same issue. Instead of dealing with react-slick code I replaced my img elements with div elements with a background-image. There's a need to have specific styling in order to make the div emulate the img behavior in terms of sizing.

<div
  className="slick-slider__img"
  style={{
    backgroundImage: "url(" + imageUrl + ")"
  }}
/>

.slick-slider__img {
  width: 95%;
  height: 0;
  padding-top: 95%;
  background-size: contain;
  background-position: center;
  background-repeat: no-repeat;
}

Thanks everyone by having the time to debug and identify the root cause!

chrisslater commented 6 years ago

I have encountered this issue with the images but didn't want to drastically change the markup that @pmgmendes recommends.

Instead I created an extra element and added the onclick to that, and then used css to overlay the image

<div className="container">
  <img />
  <div className="hitbox" onClick={...} />
</div>

.container {
  position: relative;
}

.hitbox {
  position: absolute;
  top: 0;
  bottom: 0;
  right: 0;
  left: 0;
}
CodeDeFury commented 6 years ago

I change the code by removing e.target.tagName === "IMG" && e.preventDefault(); on swipeStart function and change swipeMove to always call e.preventDefault(). This will make sure that the click event will pass through if we are not swiping and desktop image drag default behavior will still be prevented.

Diff of my code change here: https://github.com/CodeDeFury/react-slick/commit/fdd3f9ee84bd4eab69bdc5359bfe5da777e2952c

rostyslavP commented 6 years ago

Any updates in library?

aorsten commented 5 years ago

Have you tried setting pointer-events: none on the images? It might help.

I used this to fix the iOS-issue. However, this has the exact opposite effect on Internet Explorer 11, unfortunately.