Suppress Tap Gesture when user clicks on HTML button on UIWebView - javascript

I have a view. Over this view i have placed a UIWebView.
Size of UIWebView is exactly same as that of the view.
On the view i have applied TapGesture. Whenever user taps on the web view my tap gesture method gets called which is fine as per my expectations.
Now issue arises when i load an HTML file with some buttons on it. These Buttons are associated with Javascript methods.
If i click on any button in html the javascript method gets called [Perfect] but i want to suppress the Native Tap gesture method on this case.
Can anybody suggest me what should i do to suppress tap gesture method.
I only want to suppress tap gesture method when user clicks on any HTML button that is already associated with some other method.
Waiting for help :)
Tap Gesture Code
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
{
if (touch.tapCount ==1 && self.view.superview != nil)
{
NSLog(#"tag :: %ld",(long)touch.view.tag);
NSLog(#"name :: %#",touch.view);
BOOL isYesNo=NO;
if(touch.view.tag!=100)// ([touch.view isKindOfClass:[UIWebView class]])
{
// we did not touched our UIWebView
isYesNo=NO;
}
else
{
// we touched our UIWebView
isYesNo=YES;
}
}
return isYesNo;
}
TAG value is always returned as ZERO

Related

How to display Find dialog in a WebView2 control?

I have got an old C++ MFC app upgraded to use the WebView2 web browser control, based on Edge. Otherwise I have got it working fine, one of the remaining issues is opening the Find dialog in it via the main MFC app Edit-Find menu item or via Ctrl+F (which is also intercepted by MFC framework). What I have now is:
m_webView->ExecuteScript(L"window.find(\"\", 0, 0, 0, 0, 0, 1);");
where m_webView is a pointer to ICoreWebView2 interface.
The problem is that sometimes it does bring up the Find dialog, sometimes not. Sometimes it does it after page refresh, sometimes not. When I close the Find dialog from cross, it typically refuses to open it again.
How can I make it behave properly? Maybe there is a way which does not need to go through Javascript?
Update: it appears it only worked if the Ctrl+F keystroke was somehow sent directly to the WebView2 control, bypassing MFC. It looks like the above Javascript line never worked. So maybe there is a way to simulate Ctrl+F for the WebView2 control?
AFAIK, WebView2 currently has no support for you invoking or otherwise controlling the find in page dialog. You can also refer to this thread. There is a similar thread in GitHub and the official hasn't given a solution.
You can use Ctrl+F keystroke directly in WebView2 control or provide feedback about this issue on WebView2 Feedback page. Thanks for your understanding.
As #yu-zhou answered, there is no official way yet to do what I wanted. For now I resorted back for emulating Ctrl+F programmatically for the WebView2 control, but the result ain't so pretty. For the record I still present it here:
First, the user has to click in the webview2 control at least once, so I can record its HWND in the GotFocus event handler registered by add_GotFocus():
void MyHtmlView::OnGotFocus() {
if (!m_webview2_hwnd) {
m_webview2_hwnd = ::GetFocus();
}
}
Now, when I want to bring up the Find bar programmatically, I need to ensure the correct window is focused and send it the Ctrl+F key. Alas, it appears the control checks the Ctrl key state in async way, so it gets a bit tricky, I need to alter the keyboard state for the thread and add an extra event handler for restoring it afterwards. After some trial and error I reached this (error checks omitted for brevity):
void MyHtmlView::Find() {
if (::GetFocus()!=m_webview2_hwnd) {
::SetFocus(m_webview2_hwnd);
}
std::uint8_t state[256];
::GetKeyboardState(state);
bool restoreCtrlState = false;
if ((state[VK_CONTROL] & 0x80)==0) {
// Ctrl key is currently not pressed.
// Mark it pressed.
state[VK_CONTROL] |= 0x80;
::SetKeyboardState(state);
restoreCtrlState = true;
}
std::thread auxThread([this, restoreCtrlState]() {
::SendMessage(m_webview2_hwnd, WM_KEYDOWN, 'F', 1);
::SendMessage(m_webview2_hwnd, WM_KEYUP, 'F', 1);
if (restoreCtrlState) {
::PostMessage(m_hWnd, WM_COMMAND, ID_RESTORE_CONTROL_STATE, 0);
}
});
auxThread.detach();
}
// This needs to be registered to handle ID_RESTORE_CONTROL_STATE
void HtmlView::OnRestoreCtrlState() {
std::uint8_t state[256];
::GetKeyboardState(state);
if ((state[VK_CONTROL] & 0x80)!=0) {
state[VK_CONTROL] &= ~0x80;
::SetKeyboardState(state);
}
}
Needless to say, this hack may easily cease to work if they change something in the webview2 implementation.

a11y & angularjs - windows screen reader overrides keydown event

im working on making a photo gallery app more accessible.
the app has a feature of showing expanded view of an image when clicked.
one of the a11y requirements is that when a user focus an image and click enter the expand mode will open and the focus will go inside the expanded view, and will be set on one of the buttons in it. it work's fine without screen reader, or with screen reader on mac. but on windows
when using screen reader it seems that the code that fires is the one that subscribed to the click event and not the keydown event. because the flag that suppose to be set to true on keydown is false (both events fire the same function but the keydown also add the enterClicked variable set to true).
this is the div that hold the image and subscribed to the events:
<div
tabindex="0"
id="{{media.id}}"
data-ng-repeat="media in row track by media.id"
data-ng-mouseenter="events.toggleVideoPlay(media.type, media.id, media.link, ( rowNummer ) * (row.length) + ($index + 1))" class="imgContainer"
ng-keydown="$event.keyCode == 13 ? events.openExpandMode(media.id, true) : null"
data-ng-click="events.openExpandMode(media.id)"
>
openExpandMode function:
$scope.events.openExpandMode = (mediaId, isEnterClicked) => {
const state = {
isEnterClicked,
mediasId,
currentIndex,
pagination: $scope.mediasPagination,
settings: {
isUserName: $scope.settings.user_name_checkbox,
isTemplate: !$scope.userConnected && !$scope.userConnectedWithOldApi,
isLikeComments: $scope.settings.like_comments_checkbox,
isDescriptions: $scope.settings.description_checkbox,
isComments: $scope.settings.comments_checkbox,
theme: $scope.settings.expand_theme,
lang: $translate.use()
}
};
localStorageService.set('state', state);
}
expand mode component init:
const _init = () => {
if ($scope.isOpenFromEnter) {
document.getElementById('nextArrow').setAttribute('data-focus-visible-added', "");
document.getElementById('nextArrow').className += ' focus-visible';
document.getElementById('nextArrow').focus();
}
}
is there a way to stop windows screen reader event interception ?
Short answer
It's common to send a click event instead of a press enter event.
The best is probably to adapt your code so that click and enter do the same thing, and that either or both event can be sent, because
you only have a quite limited influence on which is sent or not and when
Longer answer
You haven't indicated which screen reader you were using (Jaws or NVDA), but anyway, it's common for both to send a click event when pressing enter, instead of sending key events.
Reasons for that may seem strange and illogical at first, but there are at least two good ones:
It's certainly as much illogical to have two different things happening when clicking or pressing enter. IN all applications since GUI exist, most often, both do the same action (the only exception I can think of right now is multiline or rich text fields).
Scren readers existed before web accessibility, and accessibility is still rarely implemented nowadays. Sending a click event when pressing enter provide a minimal usability in all the places where designers didn't even thought that the keyboard could be used instead of the mouse.
By the way, screen reader or not, guess which event is sent if you press enter when the focus is on a link or a button?
Depending on the browser, the answer isn't unanimous as far as I know.
And on the screen reader side, it isn't unanimous either. Some even allow to configure the exact behavior to take, in order to adapt to different more or less unaccessible sites.
is there a way to stop windows screen reader event interception ?
You can stop some form of interception by calling preventDefault in your event listener function, if the click event is generated by the browser.
By doing so, you can actually do something different on click and on enter. But ask yourself first if it is really justified. Think about my first point above.
However, you can't prevent screen readers from intercepting keyboard events, translate them to something else and send or don't send them to your page.
There exists the ARIA application mode, but it has several important implications, so you shouldn't use it unless you have true good reasons.
To wrap up, the best is probably to adapt your code so that click and enter do the same thing, and that either or both event can be sent.
adding role="application" to the container div fixed it.

AngularJS unbind after onBeforeUnload prompt, $destroy not firing

I have a requirement to show a prompt whenever our reservation page is navigated away from. When navigating within the app, there is no problem. A simple $onLocationChange works fine with a custom prompt. However when navigating to , for example, google or our logout page (which is in a separate angular app) the $onLocationChange does not work. In this case, I used:
window.onbeforeunload = onUnloadAppStart;
function onUnloadAppStart() {
var message = figureOutWhichMessageToUse();
return message;
}
this way I can at least customize the navigate message, even though I cant change the prompt box itself. However this causes a memory leak. So I need to set to null when I leave. Something like this:
$scope.$on("$destroy", function() {
window.onbeforeunload = null;
}
however this(the $destroy event) only seems to fire when I navigate within the app, same as the $onLocationChange. Furthermore I need to clean up binding AFTER the prompt, which is after the onUnloadAppStart function. This is because if I remove the binding and the user says "no, stay on this page", now my "onbeforeunload" is screwed up. Is there a way to fire functions after the onbeforeunload prompt?

Android - Webview Javascript to call a function for a specific DIV class

I am loading a JS webpage in my WebView. The webpage looks like a calendar and has items on the calendar that, when clicked or double-clicked, call functions defined on the page.
When a user taps once on the item, I want it to call the proper function as well as do the same for tapping twice on it. I know this is android, but users are expecting the function to happen when "double-clicking".
The function for double-clicking the item is:
function openPairingDetails(tripSequenceNumber) {
var url = "/csswa/ea/fa/getPairingDetails.do?popup=true&tripSequenceNumber=" + tripSequenceNumber;
var features = "height=600,width=900,location=no,menubar=no,resizable=no,scrollbars=yes,status=no,toolbar=no";
openWindow(url, features);
return false;
For now at least, all the items that the user will be double-clicking are of the same class:
<div class="boardpiece clickable" onclick="selectPairing(event, this);" ondblclick="openPairingDetails('5545220');"
So, the short version is this: I need to display the webpage (done) and allow the user to single-click to select the item and double-click to open the item. Each of these events link to a defined function. So, do I set up an OnClickListener to initiate a JS function on a single/double click of the DIV CLASS?
edit: I do not have the luxury of altering the website.
edit 2: Here is my logic: Page is displayed with an object. That object has a specific div class. The object ID is dynamic so it cannot be used. The object calls a specific function when either single or double clicked. Can I set a tap listener to call those specific functions? In other words - if the user taps once on one of these objects, the "onClick" function is called. If the user performs a longpress on an object, the "onDblClick" function is called. Can I set these to call the respective functions?
public void onClick(View v)
{
// some other code here
}
public boolean onLongClick(View view)
{
// just showing a Toast here
return false;
}
Thank you
~ Dan
double click cannot handle it in android webview. Any click listener on webview will work complete webview not on any element.
better u need to implement it on div only with this link
link
den use javascript bridge interface if u want to some android native related stuff

Is it possible to suppress the "Long Hold" (aka "long press") pop-up dialog on Android browsers via CSS or JavaScript

I'm having a heckuva time trying to find a way to use javascript or css (not Java) to prevent Android devices from showing the pop up dialog when long-pressing on an html element like an image or anchor in a web page.
I'm trying to make a carousel and if I hold the left or right arrow down on my carousel, a window pops up asking me to open in a new tab, save the image, etc. I can do this easily enough on iOS/Safari with a css rule.
Thanks in advance.
how are you setting your setOnLongClickListener and onTouch?
make sure it's similar to this
setOnLongClickListener(new View.OnLongClickListener() {
public boolean onLongClick(View view) {
activity.openContextMenu(view);
return true; // avoid extra click events
}
});
setOnTouch(new View.OnTouchListener(){
public boolean onTouch(View v, MotionEvent e){
switch(e.getAction & MotionEvent.ACTION_MASK){
// do drag/gesture processing.
}
// you MUST return false for ACTION_DOWN and ACTION_UP, for long click to work
// you can return true for ACTION_MOVEs that you consume.
// DOWN/UP are needed by the long click timer.
// if you want, you can consume the UP if you have made a drag - so that after
// a long drag, no long-click is generated.
return false;
}
});
setLongClickable(true);
code curtosy of Sanjay Manohar
Detect touch press vs long press vs movement?

Categories

Resources