bxslider-4
bxslider-4 copied to clipboard
Links in sliders aren't working - Error in the latest version of Chrome (73.0.3683.75)
jquery.bxslider.js -> onTouchStart -> slider.viewport.get (0) .setPointerCapture (slider.pointerId); Link (a tag) does not work due to source
Same issue. Set touchEnabled: false
for desktop clients as temp solution.
Update: check this https://github.com/stevenwanderski/bxslider-4/issues/1240#issuecomment-475947178
Same issue.
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.
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 😕
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
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...
Same here with Chrome 73.0.3683.86 (Official Build) (64 bits)
Same here. touchEnabled: false seems to fix this on desktop though.
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
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
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!
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/ :-)
@vsindylek That's not going to help me, we have dynamic content inside slides coming from CMS.
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.
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
@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
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 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.
@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.
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.
@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.
@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?
https://github.com/stevenwanderski/bxslider-4/issues/1240#issuecomment-477028547
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
Tried the fix as suggested Julius and now swiping on firefox desktop opens the link on swipe.
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.
@keiichi-takio Did you test this on any mobile platforms as well?
@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.
Also had to roll back to 4.1.2. Sadly, I hope soon we will find a better solution
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);
Tried every suggestion here. iOS still not working :(