Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Links in sliders aren't working - Error in the latest version of Chrome (73.0.3683.75) #1240

Open
isaiahlee opened this issue Mar 14, 2019 · 105 comments · May be fixed by #1255
Open

Links in sliders aren't working - Error in the latest version of Chrome (73.0.3683.75) #1240

isaiahlee opened this issue Mar 14, 2019 · 105 comments · May be fixed by #1255

Comments

@isaiahlee
Copy link

jquery.bxslider.js -> onTouchStart -> slider.viewport.get (0) .setPointerCapture (slider.pointerId);
Link (a tag) does not work due to source

@r10v
Copy link

r10v commented Mar 14, 2019

Same issue. Set touchEnabled: false for desktop clients as temp solution.

Update: check this #1240 (comment)

@haseebtirur
Copy link

Same issue.

@ghost
Copy link

ghost commented Mar 18, 2019

Replace this:

if (slider.settings.touchEnabled && !slider.settings.ticker) { initTouch(); }

With this:

if (navigator.maxTouchPoints > 0) { initTouch(); }

This should detect if the device viewing the slideshow has a touch screen before loading support for touch.

Note: setting touchEnabled to false didn't work for me and it also turns off all touch support.

@MarcinSzyszka
Copy link

Replace this:

if (slider.settings.touchEnabled && !slider.settings.ticker) { initTouch(); }

With this:

if (navigator.maxTouchPoints > 0) { initTouch(); }

This should detect if the device viewing the slideshow has a touch screen before loading support for touch.

Note: setting touchEnabled to false didn't work for me and it also turns off all touch support.

But now you can't swipe images by mouse. It seems we have to choose now - clicking or swiping in newest Chrome. Not both 😕

@itimurcom
Copy link

itimurcom commented Mar 24, 2019

Accorrding to information written above, a have added to initial options of all my sliders next code:

touchEnabled : (navigator.maxTouchPoints > 0) - that enable swipe functions on mobile devices and prevent using mouse swipe for desctop browser

@glo-www
Copy link

glo-www commented Mar 26, 2019

Accorrding to information written above, a have added to initial options of all my sliders next code:

touchEnabled : (navigator.maxTouchPoints > 0) - that enable swipe functions on mobile devices and prevent using mouse swipe for desctop browser

Still can't click on chrome mobile...

@cedricbdev
Copy link

Same here with Chrome 73.0.3683.86 (Official Build) (64 bits)

@larsschwarz
Copy link

Same here. touchEnabled: false seems to fix this on desktop though.

@minusthebear02
Copy link

minusthebear02 commented Mar 26, 2019

Getting the following 'Violation' from the console...

[Violation] Added non-passive event listener to a scroll-blocking 'touchmove' event. Consider marking event handler as 'passive' to make the page more responsive. See https://www.chromestatus.com/feature/5745543795965952

But if you try adding { passive: true } , like the message suggests, to any of the touch events the links will work but it'll break the slider since all of the functions used in touch events use preventDefault().

For more info

@smohadjer
Copy link

I have created a code pen with a link in the first slider that shows this problem (link can't be clicked in latest Chrome):

https://codepen.io/smohadjer/pen/VROdJE

@smohadjer
Copy link

Accorrding to information written above, a have added to initial options of all my sliders next code:

touchEnabled : (navigator.maxTouchPoints > 0) - that enable swipe functions on mobile devices and prevent using mouse swipe for desctop browser

Adding this disables touch support in iPhone too!

@vsindylek
Copy link

vsindylek commented Mar 27, 2019

What I have found is that if you put the link as a first child inside the slide and you have only one link there, then it works just fine with the original setting. Sometimes you have to click twice but both on desktop and phone the link works in the latest Chrome - see http://newhow.archi/ :-)

@smohadjer
Copy link

@vsindylek That's not going to help me, we have dynamic content inside slides coming from CMS.

@smohadjer
Copy link

smohadjer commented Mar 27, 2019

The problem in Chrome seems to be related to use of setPointerCapture() in bxslider. When I comment out the following snippet in jquery.bxslider.js links start working in Chrome and touch capabilities are also preserved both on desktop and mobile.

if (slider.viewport.get(0).setPointerCapture) {
	slider.pointerId = orig.pointerId;
	slider.viewport.get(0).setPointerCapture(slider.pointerId);
}

But this is not a perfect solution since if you drag slides with mouse on desktop Chrome and your mouse moves outside slider boundary you may end up seeing parts of two slides at the same time.

@haseebtirur
Copy link

haseebtirur commented Mar 27, 2019

Replace this:

if (slider.settings.touchEnabled && !slider.settings.ticker) { initTouch(); }

With this:

if (navigator.maxTouchPoints > 0) { initTouch(); }

This should detect if the device viewing the slideshow has a touch screen before loading support for touch.

Note: setting touchEnabled to false didn't work for me and it also turns off all touch support.

For me this seems to fix the issue.
Checkout thefastpark.com

@smohadjer
Copy link

@haseebtirur Be careful with that, you will loose touch functionality on iPhone since Safari doesn't support maxTouchPoints. See browser support for it here: https://developer.mozilla.org/en-US/docs/Web/API/Navigator/maxTouchPoints

@smohadjer
Copy link

I might have found a reliable fix for this. The problem happens in Chrome because it doesn't fire a click event after pointerup unlike other browsers such as Firefox. This is because bxslider in onTouchStart function sets slider viewport as target of all succeeding pointer events. Now if you have a link inside a slide when you click the link the target of pointerdown is not slider viewport, but the link content and since this target is different from pointerup target (which is slider viewport), then Chrome doesn't fire a click. The solution is to make sure pointerup fires on the same element as pointerdown so that Chrome fires a click. So we need to refactor this snippet:

        if (slider.viewport.get(0).setPointerCapture) {
          slider.pointerId = orig.pointerId;
          slider.viewport.get(0).setPointerCapture(slider.pointerId);
        }

to this:

        if (e.target.setPointerCapture) {
          slider.pointerId = orig.pointerId;
          e.target.setPointerCapture(slider.pointerId);
        }

This solved the problem for me in Chrome without loss of any functionality in any browser or mobile device.

@lorguzman
Copy link

I might have found a reliable fix for this. The problem happens in Chrome because it doesn't fire a click event after pointerup unlike other browsers such as Firefox. This is because bxslider in onTouchStart function sets slider viewport as target of all succeeding pointer events. Now if you have a link inside a slide when you click the link the target of pointerdown is not slider viewport, but the link content and since this target is different from pointerup target (which is slider viewport), then Chrome doesn't fire a click. The solution is to make sure pointerup fires on the same element as pointerdown so that Chrome fires a click. So we need to refactor this snippet:

        if (slider.viewport.get(0).setPointerCapture) {
          slider.pointerId = orig.pointerId;
          slider.viewport.get(0).setPointerCapture(slider.pointerId);
        }

to this:

        if (e.target.setPointerCapture) {
          slider.pointerId = orig.pointerId;
          e.target.setPointerCapture(slider.pointerId);
        }

This solved the problem for me in Chrome without loss of any functionality in any browser or mobile device.

I tried this solution and tested on mobile (iphone X with chrome) and I cannot slide left or right. On Desktop, when I slide right or left, the click event is fired automatically.

@smohadjer
Copy link

smohadjer commented Mar 27, 2019

@lorguzman I just installed Google Chrome on iOS 12.1.2 and sliding works, but I have noticed issues in Edge/IE11, so this solution is still not good enough.

@Pross
Copy link

Pross commented Mar 27, 2019

Just tested this on Chrome 74.0.3729.28 with the patch applied from above.
Mobile is draggable now but links are fired as soon as you attempt to drag on desktop.

@SpatialAnomaly
Copy link

SpatialAnomaly commented Mar 27, 2019

@smohadjer 's possible solution above didn't cover all the bases for me. Links were not clickable in Safari on iPhone X, iPad Pro, iPad Air... so on. Tested in BrowserStack. Although I appreciate his work so thank you for that suggestion.

Outside of doing a bunch of conditional checking for user agents which still isn't super reliable or checking for like modernizr.touch which also isn't great. I have decided to just disable touch for right now and try to buy some time to keep poking at this or hopefully someone smarter than me finds the solution.

@smohadjer
Copy link

@SpatialAnomaly I wouldn't rely on BrowserStack, I tested on actual devices (both iOS and Android phones) and links worked there, but as I said IE11/Edge have problem with this, so we need a better solution. For now I'm going to use my very first suggestion and simply comment out the line with setPointerCapture(). Did you try that or have any problem with it?

#1240 (comment)

@pijulius
Copy link

pijulius commented Mar 28, 2019

Hi Guys,

Here is the workaround I found:

First of all you need to move the "slider.hasMove = true;" to different location, so your code in the onTouchMove function needs to be something like this:

  // Remove this as we don't want to mark it a movement if it's not within the minimum range
  //slider.hasMove = true;

  // x axis swipe
  if ((xMovement * 3) > yMovement && slider.settings.preventDefaultSwipeX) {
    e.preventDefault();
    slider.hasMove = true;
  // y axis swipe
  } else if ((yMovement * 3) > xMovement && slider.settings.preventDefaultSwipeY) {
    e.preventDefault();
    slider.hasMove = true;
  }

And now the code is already there for the click to work just for some reason Chrome doesn't trigger the click element trough jQuery (didn't dig any further just for this) but it does work with the vanila click method in the onTouchEnd like this:

    try {
      slider.originalClickTarget.click();
    } catch(error) {
      $(slider.originalClickTarget).trigger({
        type: 'click',
        button: slider.originalClickButton,
        buttons: slider.originalClickButtons
      });
    }

I used try and catch as they say this click method is not that supported on android so in that case we fall back to the original jquery method.

I tested this on Chrome, Firefox, Android and seems to be working just fine without breaking anything.

Regards,
Julius

@Pross
Copy link

Pross commented Mar 28, 2019

Tried the fix as suggested Julius and now swiping on firefox desktop opens the link on swipe.

@keiichi-takio
Copy link

I know it's not a good solution, but BxSlider 4.2.1 works fine with the latest version of Chrome as far as I tested.

@ghost
Copy link

ghost commented Mar 29, 2019

@keiichi-takio Did you test this on any mobile platforms as well?

@ghost
Copy link

ghost commented Mar 29, 2019

@keiichi-takio Did you test this on any mobile platforms as well?

Actually I rolled back to v4.1.2 and it seems to be working for the most part. Not the greatest, and also not 100% sure why that would be ok versus a later version.

@formatiai
Copy link

Also had to roll back to 4.1.2. Sadly, I hope soon we will find a better solution

@Mosharush
Copy link

Mosharush commented Mar 31, 2019

In some cases, for example, when using a system like Wordpress or any plugin that does not have direct access to its code, the following code can be added as a temporary solution.
The code takes the address from the link and directs it directly parallel to the problem resulting from the touch event.

(function($){
  $(document).ready(function(){
	if(navigator.maxTouchPoints === 0) {
            $('.bx-viewport a').on("mousedown", function(e){
                var linkUrl = $(this).prop('href');
                window.location.href = linkUrl;
            });
        }
  });
})(jQuery);

@luiztonus
Copy link

I've been used "onclick" instead of href and It has worked for now.

For the navigation I did something like that:

$('#infoPrev').click(function(event) {
slideHome.goToPrevSlide();
event.preventDefault();
});
$('#infoNext').click(function(event) {
slideHome.goToNextSlide();
event.preventDefault();
});

@BenPav
Copy link

BenPav commented Oct 4, 2019

I've hated to do this, but for the sake of usability, for now, I've abandoned BXslider and have switched to Swiper.

@fago88
Copy link

fago88 commented Oct 9, 2019

Easy Solution (bxSlider v4.2.12)

PROBLEM:
'setPointerCapture' on 'Element': No active pointer with the given id is found.

SOLUTION
ADD: if (slider.pointerId === undefined){ return; }
at line 1095 in the "onTouchStart" FUNCTION in jquery.bxslider.js

DONE

@mcnolsen
Copy link

I might have found a reliable fix for this. The problem happens in Chrome because it doesn't fire a click event after pointerup unlike other browsers such as Firefox. This is because bxslider in onTouchStart function sets slider viewport as target of all succeeding pointer events. Now if you have a link inside a slide when you click the link the target of pointerdown is not slider viewport, but the link content and since this target is different from pointerup target (which is slider viewport), then Chrome doesn't fire a click. The solution is to make sure pointerup fires on the same element as pointerdown so that Chrome fires a click. So we need to refactor this snippet:

        if (slider.viewport.get(0).setPointerCapture) {
          slider.pointerId = orig.pointerId;
          slider.viewport.get(0).setPointerCapture(slider.pointerId);
        }

to this:

        if (e.target.setPointerCapture) {
          slider.pointerId = orig.pointerId;
          e.target.setPointerCapture(slider.pointerId);
        }

This solved the problem for me in Chrome without loss of any functionality in any browser or mobile device.

Omg, thank you. Couldn't for the life of me figure out what was going on and tried different solutions proposed all over the internet. This one seems to be working both on mobile and in chrome. Thanks a ton

@herrschuessler
Copy link

Another go at a fix – works for me:

Replace e.preventDefault(); in the function onTouchStart() with

if( ! e.target.href ) {
    e.preventDefault();
}

This enables tapping on links while keepint the touch behaviour.

@philsav
Copy link

philsav commented Jan 30, 2020

mcnolsen is very good answer, make it correct answer for this

@bbceg
Copy link

bbceg commented Jan 30, 2020

@philsav that solution - originally provided by @smohadjer - was later confirmed as not working in certain cases so I'd be careful with this. I've since abandoned bxSlider in favour of Slick in case anyone is looking for alternatives.

@BenPav
Copy link

BenPav commented Jan 30, 2020

Slick is nice, but I think swiper provides the robustness that bx had in the past. a little more bulk, but I foujnd that robustness has helped.

@bbceg
Copy link

bbceg commented Jan 31, 2020

I started with Swiper (at least in part due to your recommendation back in October) but had problems getting the carousel to work so I switched to Slick. But.... since you posted again (and Slick's touch support seemed a little flaky) I've switched back to Swiper and all is now working. So thanks for making me reconsider!

@sdomox
Copy link

sdomox commented Feb 28, 2020

Another go at a fix – works for me:

Replace e.preventDefault(); in the function onTouchStart() with

if( ! e.target.href ) {
    e.preventDefault();
}

This enables tapping on links while keepint the touch behaviour.

This worked for me. Thanks.

@Jaxel
Copy link

Jaxel commented Mar 1, 2020

Can someone share a JS file that works? With all the fixes? I don't want to edit the code myself.

@Pross
Copy link

Pross commented Mar 3, 2020

Can someone share a JS file that works? With all the fixes? I don't want to edit the code myself.

Try this version, we modded it last Oct and have had no complaints yet, thats about 1M users of our WP plugin.
https://gist.github.com/Pross/0b3acb59ce3e27ce71fcbbaa29a6cc76

@Jaxel
Copy link

Jaxel commented Mar 4, 2020

Can someone share a JS file that works? With all the fixes? I don't want to edit the code myself.

Try this version, we modded it last Oct and have had no complaints yet, thats about 1M users of our WP plugin.
https://gist.github.com/Pross/0b3acb59ce3e27ce71fcbbaa29a6cc76

I dont think that has the function for onSliderLoad or onAutoChange... two essential functions for me.

@sdomox
Copy link

sdomox commented Mar 5, 2020

Can someone share a JS file that works? With all the fixes? I don't want to edit the code myself.

This is the version that is working for me. Thanks.
https://gist.github.com/sdomox/7dffa10c3ee9fb745b40acd33295f657

@herrschuessler
Copy link

herrschuessler commented Mar 11, 2020

Another go at a fix – works for me:

Replace e.preventDefault(); in the function onTouchStart() with

if( ! e.target.href ) {
    e.preventDefault();
}

This enables tapping on links while keepint the touch behaviour.

Since my last solution stopped working in Chrome 80, I need to expand it a little:

if( ! e.target.href ) {
    e.preventDefault();
} else {
    e.target.trigger( 'click' );
}

@modenero
Copy link

This is the version that is working for me. Thanks.
https://gist.github.com/sdomox/7dffa10c3ee9fb745b40acd33295f657

can confirm that this has solved my problem (for now anyway)

@charr88
Copy link

charr88 commented Jul 8, 2020

Links in Chrome featured slider posts not working although ok with other browsers.
Not sure where this fix goes - in the theme I am using I have
jquery.bxslider.min.js
or where do I find the place to change it?

@SpatialAnomaly
Copy link

@charr88 We'd need to know more about your environment to answer that. Sounds like it's probably a CMS of some kind, Wordpress, Concrete5, Joomla... etc. Which theme package?

@charr88
Copy link

charr88 commented Jul 8, 2020

I am using Wordpress 5.4.2 with Theme Junkie's Postboard - and have check that the Chrome version (on Windows 10) is the latest.

@DanielFloeter
Copy link

DanielFloeter commented Aug 15, 2020

I wrap my link text minimum with an <span> element. <a href="">link</a> is prevented or something else. <a href=""><span>link</span></a> or also <a href=""><img src=""></a> works well for me.

But not on touche devices. Additional I add touchEnabled: 'ontouchstart' in window || navigator.msMaxTouchPoints ? false : true,

@sergeykurilov
Copy link

If someone also has a problem that the slider on the last slide jumps sharply from the first to the last, then please use this example to fix this problem, and this also solves the problem of non-clickability.

if( ! e.target.href ) {
e.preventDefault();
}


if (e.type !== 'touchstart' && e.button !== 0) {
return;
}

@redemption
Copy link

Just wanted to leave a note that in Dec 2020 we had this problem come back despite applying other fixes that worked in the past. The symptoms were on desktop as follows:

You can swipe the carousel left or right with a mouse, but clicking on any carousel item would ignore the click.

We applied the fix here:

https://github.com/stevenwanderski/bxslider-4/pull/1255/files

And can confirm it restored the ability to left click on carousel items.

I tested the fix on Chrome Version 87.0.4280.88.

It also works fine in Edge Version 87.0.664.66 and Firefox 84.0, although in Desktop Firefox the swipe functionality does not work.

All tests were done in Desktop.

I hope the same fix helps others.

@danishzahur
Copy link

Just replace following line:
if (e.type !== 'touchstart' && e.button !== 0) {

With this code:
if ((e.type !== 'touchstart' && e.button !== 0) || e.target.nodeName === 'A') {

@sergipib
Copy link

sergipib commented Feb 25, 2022

Another solution I've found is to change line 1096 - 1100 from this:

if (slider.working) { etc

to this:

if (slider.working || e.target.localName == 'a') { if (e.target.localName != 'a') { e.preventDefault(); slider.controls.el.removeClass('disabled'); } }

@webmasterpf
Copy link

Hello,
I'm facing the same issue. I done an update from 4.2.12 to 4-4.2.15, and loose all the slider :) . But the point is, do this update fix the issue or do I need to apply a patch after ?

Thanks

@kimsungkab
Copy link

예를 들어 Wordpress와 같은 시스템이나 해당 코드에 직접 액세스할 수 없는 플러그인을 사용하는 일시적인 경우에는 다음 코드를 추가할 수 있습니다. 이 코드는 링크에서 주소를 긴급한 사건으로 인해 발생하는 문제와 직접적으로 통화로 연결합니다.

(function($){
  $(document).ready(function(){
	if(navigator.maxTouchPoints === 0) {
            $('.bx-viewport a').on("mousedown", function(e){
                var linkUrl = $(this).prop('href');
                window.location.href = linkUrl;
            });
        }
  });
})(jQuery);

thanks

@platodesigner
Copy link

platodesigner commented Oct 10, 2023

For version v4.2.1d just add this in your jquery.bxslider.js:
if (slider.viewport.get(0).setPointerCapture) {
slider.pointerId = orig.pointerId;
slider.viewport.get(0).setPointerCapture(slider.pointerId);
}
after (line 1130-1133)
if (e.target.setPointerCapture) {
slider.pointerId = orig.pointerId;
e.target.setPointerCapture(slider.pointerId);
}
And this is crossbrowser solution. Works fine in Chrome, Opera, Firefox, Edge.
Thanks men who commented there earlier. This solution is based on their variant.

martin-tuma added a commit to martin-tuma/bxslider-4 that referenced this issue Mar 21, 2024
stevenwanderski#1109 remove e.preventDefault();
to fix click on link in slider + mobile + chrome
solution for
stevenwanderski#1240
@byroncorrales
Copy link

This works for me, is force the link event after touch.

$('.bxslider').on('touchend', function(event) {
var targetElement = event.target;
if (targetElement.tagName.toLowerCase() === 'a') {
window.location.href = targetElement.href;
}
});

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.