I am creating a browser-based desktop application with a text view. The text view may contain long horizontal lines. In Chrome, doing a left swipe on a track pad will sometimes activate the history.back action and sometimes activate the scroll left action. This is more than a little annoying for our users.
How do I disable the history swipe actions so that swiping will only scroll?
Note that I already supply a custom pushstate event handler. And also that moving forward/backward in history has appropriate meaning in the app, so I can't just disable history.
From what I've seen, there is no officially-sanctioned way to fix this. Toggling swipe gestures is regulated at the system level, not at the browser, so the only way to disable them is to do so manually in the system preferences (turn off "swipe between pages" in System Preferences -> Trackpad -> More Gestures).
However, after searching for a little while, I stumbled upon a hack that uses JQuery's mousewheel.js to override the settings.
This plugin by Pablo Villalba of Teambox was the first implementation I found when searching for a plugin that implements such an override. Hope this helps.
On mac i disabled swipe between pages under System preferences.
Related
I'm writing a web application with a lot of drag and drop functionality and I want to enable haptic feedback (when possible, using macOS 10.11+ with a Force Touch trackpad) for actions like "snapping in" while dragging items.
Is this possible (I know it's impossible to support every platform, but at least when hardware supports it)? I've tried navigator.vibrate with different time values/patterns but it doesn't seem to do anything even if it returns true.
Should work with the Force Touch events, one of which is webkitmouseforcedown
someElement.addEventListener("webkitmouseforcedown", myFunction, false);
You can read more about this and the other events here
Please note that this will work only on Safari unfortunately
This seems like it could be a bug, but as with all things i'm sure there is also a work-around. The problem description is this; using cordova to develop an android app with a simple page with some textfields, when typing into those fields on the app the softkeyboard appears so that you can enter text, but then when you either "enter" or focus on another element, the keyboard fades away but leaves the "ActionBar" at the bottom of the view.
The ActionBar remains, and if one's app is designed to run full screen - the action bar may overlap app content. The ActionBar itself cannot be swiped down or removed by the end user except for swiping down from the very top (the title bar) then swiping back up again.
This seems to be an issue as of Android 6.0.0 or perhaps I just wasn't noticing it before.
I've noticed that with the plugin cordova-plugin-dialogs that when i use the alert dialog after i close it, the actionbar hides, but I think that ultimately the scenario that would work best is that after X-timeout from typing in a textfield and/or the softkeyboard fades out, the ActionBar should fade out too.
Any suggestions on how to manage the Android ActionBar in PhoneGap - I've seen some other similar questions but generally asking how to show it, seems like getting it to hide is less popular?
After much searching I was able to determine that the phonegap fullscreen setting doesn't necessarily give way to full "immersive" mode by default. After adding the plugin cordova-plugin-fullscreen and setting the immersive mode from the plugin, I was able to resolve this issue.
https://www.npmjs.com/package/cordova-plugin-fullscreen
What's the Problem:
Unfortunately I must use an Iframe in a web solution (tenant scoped SharePoint hosted App with App Parts).
The iframe needs around 50% of the website's space and the space for it in the host will be programmatically blown up in size so that there will be no scrolling bars shown. It works good on every browser except Safari. In Safari the touch event seems to be caught by the iframe window and will not be forwarded to the host window. Imagine this on the iPad: in over 50% of the page the user can't scroll down the page.
Hardware I used for testing:
Windows 8.1 (touch enabled screen) with latest version of Safari (5.1.7)
iPad with iOS version 8.4.1.
What I researched/tried so far:
This has nothing to do with everything that can be solved by "-webkit-overflow-scrolling: touch;" and similar approaches. From what I understood in my research, this will make the iframe scrollable but I need to make the host window scrollable when moving the finger in the iframe area. In other Browsers the iframe for example scrolls down until the end and then starts scrolling the host window
In some post one suggested to overlay the iframe with a div (z-index: 2) and then forward the click events from this overlaying div to the Iframe window ( I do have control on this Iframe window, so I can catch events in there). The overlaying div fixed the scrolling behaviour on my testing page but not in my target application, so it's not a reliable solution. Besides that: I managed the click event to be triggered (with same approach as in 3.) but could not manage to make it click links in my iframe-page (what I need... because this is the reason why I want the clicks to be forwarded.)
Another approach was to forward the touch events from the Iframe page to the host page. I did this via postMessages, JSON-stringified event parameters and a javascript library called "jquery.simulate.js" that is used to simulate touch events. I did not manage to trigger the touchmove event correctly on the parent window (and besides that I doubt that this is really good concerning user experience and performance)
I also thought about getting the simple html from the Iframe and add it to the host page programmatically. Unfortunately SharePoint hosted Apps are hosted on other subdomains, so due to the cross-browser restrictions I think is not worthid to follow.
Another approach was pointer-action: None; - This also breaks the link functionality and unfortunately worked only on the desktop
Setting scrolling="no" (or "yes") did not have any effect nowhere (maybe because it's gone in HTML5)
So here I am stuck... and it seems that no one else in this world has the same problem as I cannot find any really working idea anywhere. But I tested around 20 different websites with iframe - and I tested with the Desktop touch and the iPad.... and I have the same problem. I could not find a single Safari-Touch-working iframe throughout all suggestions and possible solutions.
How to reproduce:
A simple
<iframe src="http://www.w3schools.com"></iframe>
embedded on any html page with long content, Safari and a touch device (similar to the ones I used for testing) should be enough to reproduce.
What I want to know:
Does anyone have the same problem?
Could you put me into the right direction? I am actually unsure which of the above mentioned approaches I should continue to go on with
Do you have a completely new idea that I could follow?
Did you test this on any other device and know it's working? (I am thinking maybe downgrading could be a solution)
Edit: (Solution Nr. 2) The overlaying div makes the page indeed also scrollable in Safari, but I could not find the correct way how to forward the click event to the child successfully (meaning: which of the event parameters are necessary to be forwarded to trigger the click event in the child window?)
Edit: Searching again and found out that you cannot create events like clicking programmatically due to security reasons. Makes sense as this will be a big security issue if you could force the user to click on your ads for example.
How can I click on specific (x,y) coordinates on a web page?
When I select text in Chrome 43 on my Android device I get the "Touch to Search" popup. We're currently using text selection for a feature on our site and this new Chrome feature interferes with some of our UI.
In the long run, we'll be working out new UI/UX to work side-by-side with this feature, but in the interim, we want to disable it on our web app.
Is there some sort of meta tag or JavaScript we can add to turn this off? Does anyone know if this is currently possible?
This can be manipulated in a number of ways. The user can turn it off in flags as PaulI suggested, and you can control it.
Developer control, right now there are a couple of options but the basic summary is if we think it is an user interactable element then it won't be enabled:
CSS: -webkit-user-select: none;
HTML:
Anything with an aria-role will not have the touch to search enbabled
Anything with a tabindex of -1 or > 0
Possible workaround could be to wrap text in <button> tag. This obviously wouldn't work if talking about big blocks of text, but for other elements like titles, icons and other small stuff this works fine.
As of 2021, it isn't possible to disable touch-to-search (when this is triggered by a long-press for text selection) in chrome mobile. The article that Kinlan is referencing is apparently concerned only with touch-to-search triggered through a tap gesture.
Quoting donnd, from bugs.chromium.org:
Regarding #2 -- developer control: The 2015 article that you mentioned (https://developers.google.com/web/updates/2015/10/tap-to-search) focuses on triggering through the tap gesture. As you correctly point out, it does not address the long-press gesture triggering. Touch to Search responds to both tap and long-press but treats them differently. As I'm sure you know, the long-press gesture activates a whole set of features which can include copy, translation, smart text selection, and Web Search. A site developer can markup their page text as non-selectable in order to disable the long-press gesture entirely, but currently there's no way to disable only the Touch to Search response to long pressing. If you'd like to work with us to add such a feature, let us know and we'll file a separate feature request.
If you want disabled "touch to search" in a menu that has an action open / close (toggle), it is necessary to javascript :
event.preventDefault();
Navigate to about:flags or chrome:flags and look for Enable Contextual Search
Then toggle to Disabled and hit restart at the bottom.
I have a single-page mobile application developed with Backbone and Zepto.
It works correctly with the back/forward buttons in the browser.
When the user navigates to a page, the new content slides in from the right as the old contents slides away to the left (and out of the viewport). I want the same thing to happen if the user presses the "forward" browser button. This all works.
I've got a class that I add to the body element navigate-back that will flip this behaviour, so when the user navigates back with the browser's back button, they see the content sliding back in from the left and the other content sliding into the right. Basically just the opposite of going forward.
I need to detect if the user is navigating backwards so I can invoke the alternate behaviour. I have tried implementing my own history stack, but I've ran into lots of problems where sometimes it marks a forward as a back navigation which ruins the visual cue. It's descended into a kludge of hacks now and probably would only embarrass me if I posted it.
What is the best way to implement my own history stack so I can detect if the user is navigating forward/back in the context of a single-page Backbone mobile application?
I don't know about backbone.js1, but I have helped develop a mobile application which had to implement exactly this behavior in html5, so I should be able go give some good advice:
First of all it's good to know that the history.pushState function exists. The big problem with it though is that it is supported up to android 2.3, but not on android 3 till android 4.0.3. As kiranvj points out correctly this can be solved by using the popular history.js library which provides a polyfill solution for the lack of the history functionality.
Now, getting to your actual problem, the way I implemented the history direction animations was by adding data to the pushState function ( history.pushState(data,title,url) ) with which I identified the logical position of the page. In my application I wasn't only limited to a horizontal bar, but in your case you would keep track of position where any new loaded page get's a position which is one higher then your current page. E.g.
History.pushState({position:History.getState().data.position+1},"Your title","Your URL");
Next, when the window.onstatechange or window.onanchorchange event triggers you observe whether the position is higher or lower than your current page (e.g. by using the history.js History.getState() function which I used above) and depending on this you decide in which direction to move (lower is to the left, and higher is to the right), as is illustrated by the image below:
You will also note that I already assumed on the first page that you have {position:1}, whereas normally the first page will have no state information. The way this can be achieved is by using history.replaceState which replaces the current empty state with a more informative state. Alternatively you can also check for an empty state on any of the previously mentioned events and if it's empty you assume it to be the left most one ({position:1}).
Hope this helps and if you have any additional questions feel free to ask.
Please note that this answer assumes you are using history.js and you would need to listen to slightly different events (such as onpopstate) and use slightly different structures (history rather than History) if you would want to build your own solution.
It is also useful to note that it is possible to build this with your own queue array which gives you a lot more control, but will not work in combination with the browser's back button. This is a big issue with browser sites, however is far easier in case you are building a cordova (a.k.a. phonegap) web application.
1 Just read about it and it appears to do some history handling of its own, which might make it more complex to integrate the technique described above.
If you're working on a true single-page app, why not you set up an array to hold history urls in a js variable (as opposed to relying on something like history.pushState and its support)?
Whenever a new page is navigated to, you can push its url into the array, whenever a "back" button is pressed, you can retrieve the url needed as far back as you want. This will work perfectly as long as you correctly discard urls when the user goes back a few steps and then navigates to a new link.
I've never tried implementing this to be used for page history, but this worked perfectly well for in-page undo-redo logic.
Update:
After further research, the approach above would not work for a page reload as it would be an action occuring outside of history handling available through JS. It would still work for tracking back/forward transitions, but such history will be lost on navigating to a url external to the app or a page refresh. David Mulder's answer seems to lack this limitation by relying on browser-level history that persists outside of the page scope.
I had the same issue when working with Zepto on mobile with single page - multiple views.
Initially I used html5 statechange and onhashchange. It all have some issues in one or other mobile device. Finally I used Zepto history plugin from here https://github.com/browserstate/history.js
It somewhat solved most of the issues. Try it, it will be useful, it handle html4 and html5 features wherever possible.
Use this thing in single page mobile application this will allow to the history and move the user to back.
function onBackKeyDown() {
history.go(-1);
navigator.app.backHistory();
}
Sammy.js's v.6.x branch (the one that relies just on hash changes) is a perfect, simplest, most browser-compatible approach to tracking history. There, history is not tracked at all, as Sammy just watches for hashchange.
Relying on "#/slide/123" allows you to support hard page reloads, and simplifies the work
Peel off the last part (slide number) on each page view, push into global. On new route, see if number is more or less than what is stored in global and do the correct (left or right) animation. If global is undefined, no animation.