Using ngTouch for ng-click events on the body element can cause issues with links and input fields on mobile

Seeking assistance with a unique issue I am facing on my app-like website. I have implemented a swipable menu but I want it to close whenever the user taps outside the menu. I have tried using ngTouch for swiping and attached ng-click="menuToggled = false" to achieve this functionality.

However, I encountered a problem where attaching ng-click to the body resulted in links within the menu not working and being unable to focus on input fields on the body. This issue only occurs on mobile devices such as iOS, Android, or when using Chrome device emulation.

I am considering alternative solutions to close the menu on tap, but I find this problem peculiar. Any thoughts or suggestions on how to resolve this would be greatly appreciated.

For a demonstration, you can view a simple demo here. Please note that it works on desktop, but when using device emulation in Chrome, you may encounter issues with input field focus unless you hold down the mouse button:

<body ng-app="myApp" ng-click="showMenu = false">
    <input type="text">
    <button type="button" ng-click="showMenu = true; $event.stopPropagation();">Show menu</button>
    <div class="menu" ng-show="showMenu"></div>        
</body>

Answer №1

It's difficult to pinpoint the exact cause of your initial issue. It appears that using ng-click on the body tag may not be the best approach as it seems to interfere with focus in some cases.

I've come up with a somewhat intricate solution that has been tested on desktop and emulated mobile devices in Firefox. This solution effectively addresses the 'click + touch' issue. You can view the implementation here: http://jsfiddle.net/s_light/L85g3grs/6/

To set up the click event on the button, use the following code:

<button type="button" ng-click="menuShow($event)">
    Show menu
</button>

Then, include the corresponding handling in your controller:

app.controller('MainController',[
    '$scope',
    '$document',
    '$timeout',
function($scope, $document, $timeout) {

    $scope.menu = {
        visible: false,
    };

    var menu_clickPrevent = false;

    function menuHide(event) {
        console.log("menuHide");

        $scope.menu.visible = false;

        $scope.$apply();

        $document.off('click', menuHide);
    }

    $scope.menuShow = function(event) {
        console.log("menuShow", event);

        if( !menu_clickPrevent ) {
            event.preventDefault();
            event.stopPropagation();

            $scope.menu.visible = true;

            menu_clickPrevent = true;
            $timeout(function () {
                menu_clickPrevent = false;
            }, 100);

            $document.on('click', menuHide);
        }
    };

}
]);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Automate your workflow with Apps Script: Save time by appending a row and seamlessly including additional details to the

I currently have 2 server-side scripts that handle data from an html form. The first script saves user input to the last row available in my Google sheet, while the second script adds additional details to the newly created row. Although both scripts work ...

Having issues displaying the & symbol in HTML from backend data

I recently worked on a project using express handlebars, where I was fetching data from the YouTube API. However, the titles of the data contained special characters such as '# (the ' symbol) and & (the & symbol). When attempting to render the ...

What is the process for generating a three-dimensional surface using 3D points in Three.js?

I am currently working on a project that involves creating simple 3D models using dots and lines, whether curved or straight. In the initial version of the project, I utilized SVG elements for rendering, smooth curves, and mouse events. Now, I am explorin ...

The custom filter in AngularJS fails to activate when a click event occurs

I am trying to customize the filtering of my table data based on selected conditions from a dropdown menu. I have created an AngularJS custom filter and passed all the necessary parameters. The desired functionality is that if no conditions are selected, ...

Upon loading, the IntersectionObserver immediately declares the isIntersecting property true for all elements

Yesterday, when I executed this code, everything functioned as expected. The observer successfully loaded the images once they intersected the viewport: <template> <div id="gallery" class="gallery"> <div class=" ...

The getInitialProps function in Next.js React components does not automatically bind props

When building applications with Next.js, you have the opportunity to leverage a server-side rendering lifecycle method within your React components upon initial loading. I recently attempted to implement this feature following instructions from ZEIT' ...

Whenever I attempt to alter the text of a single button in the map using ReactJS, the change reflects on all buttons simultaneously

Currently, I am facing an issue while trying to create a map in React JS with buttons. When I click on a button, it changes the text of all buttons instead of just the specific one. I believe the problem lies in not specifying the button_id, but I am unsur ...

Using JavaScript to display a line using `document.write`

I'm having trouble displaying a line using the Document.Write function in JavaScript. When I submit the form, the line briefly appears and then disappears Any ideas on why this might be happening? <!DOCTYPE html> <html> <head& ...

Is there a technique to block small increments in a Time Input field?

Currently in the process of developing a tool to automate task scheduling within an Angular app. I am looking for a way to restrict the user's input when selecting the hour for task execution without having to install a complex input management packag ...

Unable to hide content in Shopify using @media

How can I hide a Facebook like button when the browser window is resized to a certain width? This is the code I am using: @media all and (max-width: 300px) { .fb-like { float: right; display: none; } } While this code works on regular websites, it do ...

Tips for incorporating multi-lingual email templates into your node.js application

I integrated node email templates into my project to automatically send emails to users based on certain events. Check out the Node Email Templates GitHub page for more information. For sending emails with Node.js, Nodemailer is a great tool. While I wa ...

The art of transforming properties into boolean values (in-depth)

I need to convert all types to either boolean or object type CastDeep<T, K = boolean> = { [P in keyof T]: K extends K[] ? K[] : T[P] extends ReadonlyArray<K> ? ReadonlyArray<CastDeep<K>> : CastDeep<T[P]> ...

Using JavaScript to grab an entire div containing an SVG element

I am looking to capture an entire div as an image and save it locally as proof. Despite reading numerous articles on converting SVG to image or div to image, I have encountered challenges in achieving the desired result. Several attempts with JavaScript l ...

Exploring the contrast between window and document within jQuery

I'm curious about the distinction between document and window in jQuery. These two are commonly utilized, but I haven't quite grasped their differences. ...

Gaining entry to specialized assistance through an occasion

Having trouble accessing a custom service from a custom event. Every time the event is fired, the service reference turns out to be null. @Component({ selector: "my-component", template: mySource, legacy: { transclude: true } }) export class myComponent { ...

I have been attempting to implement validation in JQuery, but it doesn't seem to be functioning correctly

Can someone assist me with adding validation in jQuery? I'm stuck and need help solving this problem. $(function(){ $("#btn").click(function(){ var b=prompt("Enter your link"); $("a").attr("href",b); if($("b").v ...

Is it possible to utilize Angular's $http.get method with a dynamic route

I recently started working with Angular and I'm trying to figure out how to retrieve data from a REST API using a scope variable to determine the URI for the GET request. Imagine that I have an array of numbers being generated by a service in my app ...

Add a new component in front of another component based on its attribute value

Creating a dynamic DIV and positioning it in between other Div's based on their attribute value is the goal. The desired outcome is to maintain sequence. <div data-door="1">1</div> <div data-door="3">3</div> <div data-door ...

Combining THREE.Sprite with fog or utilizing THREE.ParticleSystem with an array of texture maps

Currently attempting to create a particle system using Sprite, however, encountering an issue where Sprite does not appear to respond to the "fog" parameter, meaning it does not fade away with distance. While ParticleSystem does adhere to the fog parameter ...

Include a query parameter each time a page is added to bookmarks

Is there a way to automatically add a query parameter to a page URL when bookmarked using Chrome? For example, if I bookmark https://www.example.com, can it be saved as https://www.example.com/?bookmarked? I'm thinking I might need to use JavaScript ...