I am using noUiSlider in a Foundation 6 off-canvas menu, and the slider handles will not drag on touch devices. It works if the noUiSlider is nested outside of the off-canvas menu, and it even works fine in the off-canvas menu when using a mouse to drag the handles. However when I emulate touch events, or actually attempt to drag the sliders handles on a touch device the slider handles do not move and stay fixed in place.
HTML:
<div class="off-canvas position-right" id="offCanvasNestedPush" data-content-scroll="false" data-off-canvas>
<div class="row align-middle" id="fr_wrapper_price_slider" data-initial-start="0" data-initial-end="10000000">
<div class="columns small-12">
<!-- noUiSlider -->
<div id="fr_price_slider"></div>
</div>
</div>
</div>
JS:
var fr_price_slider_wrapper = document.getElementById('fr_wrapper_price_slider');
var fr_price_slider = document.getElementById('fr_price_slider');
noUiSlider.create(fr_price_slider, {
/* Slider Positions on DOM Load */
start: [
fr_price_slider_wrapper.getAttribute('data-initial-start'),
fr_price_slider_wrapper.getAttribute('data-initial-end')
],
behaviour: 'drag',
connect: true,
range: {
'min': [ 0, 5000 ],
'50%': [ 1000000, 50000 ],
'max': [ 10000000 ]
}
});
The reason i'm answering this question myself is because I was not able to find any questions on StackOverflow that asked about this issue, and it's a really simple fix. Foundation 6's documentation for the off-canvas menu does not mention that setting data-content-scroll="false" can block touch events for third-party scripts nested in the off-canvas menu. I spent far more time than I should have debugging this issue, and I'm hoping it will save someone some time in the future.
Bugfix:
Remove the data-content-scroll="false" attribute from the off-canvas menu element, and noUiSlider will work as expected.
As you've already found out the contentScroll option is responsible for this because it prevents touch events if enabled. Your 'bugfix' is not a real solution because this option has a right to exist!
There are use cases (for example in my projects) where you need it.
However a solution would be an additional option for the noUiSlider which provides the possibility to change the slider's scope.
I've submitted a PR for this last year which has not been merged yet
https://github.com/leongersen/noUiSlider/pull/821
Related
I'm using TouchSwipe jQuery plugin for mobile version of my site. I need to fire multiple click-events on one swipe, something like - on every 15px of swipe - one click. I've googled, but found no solution.
Thing is - I'm using carousel plugin for Joomla (sigplus), that, unfortunately, doesn't support finger swipe. I'm trying to emulate swiping function by making TouchSwipe pressing carousel buttons for user on swipe. At the moment I have such code:
jQuery(function($) {
$(".s2").swipe({
excludedElements: "button, input, select, textarea, .noSwipe",
swipeLeft:function(event, direction, distance, duration, fingerCount) {
$( '.boxplus-next' ).click();
},
swipeRight:function(event, direction, distance, duration, fingerCount) {
$('.boxplus-prev').click();
},
triggerOnTouchEnd:false,
threshold:15
});
});
It works fine, but scrolls only one image in carousel per touch. Maybe it's possible to restart function after triggering?
Thanks
P.S. Sorry for my English
To trigger continuous events, you should use the swipeStatus event instead: http://labs.rampinteractive.co.uk/touchSwipe/demos/Swipe_status.html
You can then trigger next or back, based on the distance.
See this answer for more info: Multiple swipe events on an element with TouchSwipe
I am trying to create a full page interface using the excellent jQuery UI Layout plugin.
I want the central pane to hold multiple dialogs and allow them to be contained within that pane. So far so good. However, I also want to be able to drag the dialogs "out of the way", and move them to the right or bottom so that the central pane develops scroll bars and allows the central pane to act as a scrollable desktop for dialog boxes. I want the other pane(s) to be always there for other UI purposes.
HTML:
<div class="ui-layout-center">
<div id="dialog1">dialog 1</div>
<div id="dialog2">dialog 2</div>
</div>
<div class="ui-layout-north">North</div>
<div class="ui-layout-south">South</div>
<div class="ui-layout-west">West</div>
jQuery:
$('body').layout(
{
applyDemoStyles: true,
livePaneResizing : true
});
var dialog1 = $("#dialog1")
.dialog({})
.parent().appendTo( $(".ui-layout-center") );
dialog1.draggable( "option", "containment", $(".ui-layout-center") );
$("#dialog2")
.dialog({})
.parent().appendTo( $(".ui-layout-center") );
As you can see, it almost works, but the scrolling doesn't work horizontally. I've experimented with containing dialog1 but this makes things worse! Perhaps it's just a CSS issue or that combined with a setting. Any ideas?
jsFiddle
The solution turned out to me a case of manipulating the underlying draggable of the dialog box:
$("#dialog2").dialog("widget").draggable(
{
containment : [ 0, 0, 10000, 10000 ],
scroll: true,
scrollSensitivity : 100
});
Obviously, these values can be played with to achieve different results. I hope this helps anyone else in the same position!
jsFiddle
I looked over the documentation and apparently you are able to achieve this with using CSS and changing the overflow value.
http://jsfiddle.net/vnVhE/1/embedded/result/
As you can see the CSS applied is:
// disable scrolling in the other panes
.ui-layout-pane-north ,
.ui-layout-pane-west,
.ui-layout-pane-south {
overflow: hidden !important;
}
.ui-layout-layout-center {
overflow: auto
}
NOTE: Please keep in mind while this allows horizontal scrolling it is a bit tricky and hackish at best in my opinion. Under Chrome I could scroll just fine if I held the mouse near the edge of the vertical scroll bar and it moved properly.
I'm doing an HTML5 app, and I want to configure a swipe/drag function to open/close the offcanvas menu.
The function works great but I want to have more precise horizontal swipe or drag to prevent triggering vertical scroll and activating the menu.
By default swipe doesn't seem to works well because must be really fast (even changing the speed), drag works ok, but just pressing and move a bit activates the event.
I tried changing the variable drag_lock_min_distance, but unfortunately doesn't work at all, I cannot feel the difference even for the huge value that follows.
I tried checking real time the internal variables X speed and distance but they show the values taking as a reference the very first event, and not the dragstart and dragend.
I'm using raw hammer.js with twitter bootstrap, hammerjs version 1.0.6 from a CDN (last stable version). I'm testing on Android stock browser 4.1.2, and 4.4 (two different phones) as well as Google Chrome for Android.
Here you have the code:
var element = document.getElementById('contenido');
Hammer(element,{drag: true,
prevent_default: false,
drag_block_horizontal: true,
drag_lock_min_distance: 250,
hold: true,
release: true}).on("dragleft", function(event) {
// function
});
Hammer(element,{drag: true,
prevent_default: false,
drag_block_horizontal: true,
drag_lock_min_distance: 250,
hold: true,
release: true}).on("dragright", function(event) {
//function
});
Do you know any way to control the distance, to make firing of the event less sensible?
For someone coming across this in future, from Hammer > 2.0,
You can specify a threshold option to set the minimal distance required before recognizing, as shown below:
var hammertime = new Hammer(myElement, myOptions);
hammertime.get('swipe').set({ threshold: 100 });
hammertime.on('swipe', function(ev) {
console.log(ev);
});
I have got browser carousel component based on ng-repeat. The carousel can load partial html file and slice it over <li> elements.
I would like to be able to swipe carousel using protractor/webdriverjs in browser.
I have tried mouseDown(), mouseMove(), mouseUp() actions:
ptor.actions()
.mouseDown({x: 500, y: 250})
.mouseMove({x: 50, y: 250})
.mouseUp()
.perform();
or
ptor.actions()
.mouseDown(ptor.findElement(protractor.By.id('ra-slice-1')))
.mouseMove({x: 500, y: 250})
.mouseUp()
.perform();
I have also tried dragAndDrop but I have no container to drop into.
From the code perspective everything is ok (no errors), but the carousel won't swipe.
Please advise.
Sadly, not supported by webdriver in browsers. See stackoverflow.com/questions/15479143/. You may be able to get around it by triggering a javascript event, as described in the answers there. [Moved from comment]
I've implemented drag and drop using the jQuery UI draggable widget.
I'm now implementing auto scroll during drag operations. I set it up so that when you start to drag, gray overlays appear at the top and bottom of the browser window. When you drag into one of these overlays, the browser window starts to auto scroll.
You can see my test page at http://www.softcircuits.com/Client/scrolltest.html. Drag an item by dragging one of the crosshair icons on the left side.
But there's a problem: if you scroll to the bottom of the page, and then drag an item to the top overlay, it will scroll up as expected. However, for me, I get about half way up the page and the draggable helper won't go any higher. There's no way for me to drag all the way to the top of the page.
This most likely seems related to the Draggable widget. Is anyone able to see why this is happening? I'm using Google Chrome on Windows 7.
To be cross-browser compatible and to avoid wird behavior, I would recommend to use all JQueryUI draggable callbacks.
I read some days ago that the last version of Chrome has some really tricky problems with natives HTML5 draggable events.
For example, I have just checked your web page source code and you are using $('.drag-handle').on('drag', function(){...}); => You should use the drag callback.
I would also recommend to not use window as the scrollable container in your case. You should create a div to wrap all the tables contents and use it as a scroll container. I have already done this implementation in the past and it is working.
Don't forget to set the wrapper ID in the containment option durring the draggable widget creation.
If it always not working, you could also try to overwrite the helper position in the drag callback :
//Save the mouse position in global variables
$(document).mousemove(function(e){
window.mouseXPos = e.pageX;
window.mouseYPos = e.pageY;
});
$('[id^="drag-"]').each(function() {
$(this).draggable({
opacity: 0.7,
cursorAt: { top: 15, left: 50 },
scroll: true,
stop: function(){},
drag : function(e,ui){
//Force the helper position
ui.position.left = window.mouseXPos - $(this).draggable('option','cursorAt').left;
ui.position.top = window.mouseYPos- $(this).draggable('option','cursorAt').top;
});
});
Changing the draggable containment option from window to document worked for me.
$('.drag-handle').draggable({
...
containment: "document",
...
});
See: http://docs.jquery.com/UI/Draggable#option-containment