Отключение контекстного меню при длинных нажатиях на Android

Я хотел бы отключить контекстное меню, которое появляется после долгого нажатия (касание и удержание) изображений в моем веб-приложении. Я видел сообщения с разными идеями, как это сделать, но ни один из них, похоже, не работает для меня.

Есть ли способ сделать это на Android через HTML/CSS/Javascript?


person Roy Sharon    schedule 05.08.2010    source источник


Ответы (12)


Это должно работать на 1.6 или более поздних версиях (если я правильно помню). Я не верю, что есть обходной путь для 1.5 или более ранних версий.

<!DOCTYPE html>
<html>
<head>
  <script>
    function absorbEvent_(event) {
      var e = event || window.event;
      e.preventDefault && e.preventDefault();
      e.stopPropagation && e.stopPropagation();
      e.cancelBubble = true;
      e.returnValue = false;
      return false;
    }

    function preventLongPressMenu(node) {
      node.ontouchstart = absorbEvent_;
      node.ontouchmove = absorbEvent_;
      node.ontouchend = absorbEvent_;
      node.ontouchcancel = absorbEvent_;
    }

    function init() {
      preventLongPressMenu(document.getElementById('theimage'));
    }
  </script>
</head>
<body onload="init()">
  <img id="theimage" src="http://www.google.com/logos/arthurboyd2010-hp.jpg" width="400">
</body>
</html>
person Roman Nurik    schedule 09.08.2010
comment
Ничего не видел в OP с 8 августа, поэтому я решил проверить это сам, используя SDK. Я протестировал версии 1.5, 1.6 и 2.2, и на всех из них все работало отлично, поэтому я рад присудить награду сейчас, не дожидаясь подтверждения ОП. +1 за хороший ответ тоже. - person Andy E; 12.08.2010
comment
Роман, большое спасибо за ответ. Мне нужно протестировать его (не то чтобы я игнорирую тест Энди, но я видел много вещей, которые отлично работают с SDK, а затем терпят неудачу на реальных устройствах). Извините, что так долго не отвечал, но я обещаю проверить это до выходных. Еще раз спасибо вам и Энди! - person Roy Sharon; 12.08.2010
comment
@Энди -- спасибо, @Рой -- конечно; Я тестировал на Nexus One, я бы рекомендовал тестировать и на устройствах с нестандартными браузерами по умолчанию, @Tegeril - давно не виделись! - person Roman Nurik; 13.08.2010
comment
@Roy: вы можете использовать тест, который я установил, если хотите. jsfiddle.net/M7pfy/1 — верхнее изображение должно отменять контекстное меню, нижнее — разрешить это. - person Andy E; 13.08.2010
comment
@Энди, еще раз спасибо! @Roman - я проверил ваше решение, используя страницу Энди, на двух моделях Motorola Blur. Та что с Android 1.5 работала нормально, а та что с 2.1-update1 не работала. Черт. Я действительно хотел, чтобы это сработало. Иногда мне хочется, чтобы мир Android был больше похож на мир iPhone, с его единым вкусом... Итак, что мне теперь делать с точки зрения обычаев stackoverflow: отметить решение Романа как ответ или нет? Я предполагаю, что его идея заключается в том, как это должно быть сделано, но, с другой стороны, это не решает мою проблему... Спасибо за совет. - person Roy Sharon; 15.08.2010
comment
@Roy: это кажется действительно странным, для меня это работает в 1.5, 1.6 и 2.2, но не для вас 2.1. Вам не обязательно принимать ответ Романа, хотя вы можете принять его и задать другой вопрос о проблемах, которые у вас возникли с решением. Лучшей идеей было бы провести более широкий тест, если это возможно — больше версий на большем количестве устройств. Здесь может помочь другой вопрос и ссылка на пример. Если это работает на других устройствах, то вы знаете, что это правильное решение, и проблема связана с устройством, на котором оно не сработало. - person Andy E; 15.08.2010
comment
@Энди: Звучит как хорошая идея. Я принял ответ Романа и попытаюсь провести более широкий тест. Если это похоже на баг устройства, то так тому и быть. Если нет, я отправлю другой - более конкретный - вопрос. Еще раз спасибо за теплый прием для новичка в stackoverflow! - person Roy Sharon; 15.08.2010
comment
Одна потенциальная проблема, которую я обнаружил с этим решением, заключается в том, что если пользователь выполняет какую-либо сенсорную команду над изображением, например, пытается прокрутить или масштабировать, то его команда не будет выполнена. - person Doug S; 12.02.2013
comment
Это решение отключает все сенсорные события. Это может быть ограничением! - person bbsimonbb; 26.02.2015
comment
Это действительно правильный ответ? Вроде img.addEventListener('contetxmenu', function(e) { e.preventDefault(); return false; }, false); должно работать нет? Приведенное выше решение предотвратит ввод всех данных. - person gman; 18.05.2015
comment
Вы часто сталкиваетесь с подобными вещами, но вы действительно хотите избежать вмешательства в распространение событий, если можете. Данное событие может быть важным как для вашего компонента, так и для других компонентов на странице. Например, щелчок за пределами раскрывающегося списка может быть очередью для свертывания раскрывающегося списка, а также любым действием, непосредственно соответствующим щелчку. Найдите способ, который не разрушает полностью обработку событий на вашей странице. - person bbsimonbb; 18.05.2015

Контекстное меню имеет собственное событие. Вам просто нужно поймать его и остановить его распространение.

window.oncontextmenu = function(event) {
     event.preventDefault();
     event.stopPropagation();
     return false;
};
person bbsimonbb    schedule 26.02.2015
comment
работает! Но теперь я хочу заблокировать контекстное меню только на якорных элементах. У меня работает фильтр (возвращает false, когда [a], иначе true), но при возврате true диалоговое окно не отображается. Итак ... как вы говорите браузеру, что он должен отображаться? - person REJH; 31.10.2016
comment
Я бы не стал ставить фильтр в функцию. Было бы лучше и чище привязывать функцию только к тем элементам, контекстные меню которых вы хотите отключить. - person bbsimonbb; 01.11.2016
comment
Работаем над Win10/UWP/MS Edge WebView для Cordova Windows :) - person Neptune Systems; 25.10.2017

Для меня поглощение всех событий не было вариантом, поскольку я хотел отключить загрузку при длительном нажатии, но при этом позволить пользователю масштабировать и панорамировать изображение. Я смог решить эту проблему с помощью css и html, только наложив «защитный» div поверх изображения следующим образом:

<div class="img-container">
  <div class="shield"></div>
  <img src="path.jpg">
</div>

img {
    max-width: 100%;
}

.shield {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    z-index: 1;
}

Надеюсь, это поможет кому-то!

person Brian FitzGerald    schedule 12.07.2013
comment
Возможно, вам придется добавить position:relative в родительский контейнер, чтобы родитель не занял все пространство. Это особенно сложно, если родителем является td, с которым связан ontouchstart или другой обработчик событий взаимодействия, поскольку визуально вы не увидите, что td занимает всю эту область. - person Daniel F; 23.01.2019

Это можно сделать с помощью CSS:

img {
  pointer-events: none;
}
person Artem Andreev    schedule 14.04.2015
comment
Это не только отключает долгое нажатие, но и, например. обычный кран, так что не всегда вариант. - person gvlasov; 27.05.2020

Я использую полный пример Нурика, но элемент (входное изображение на моей странице) также был отключен для клика.

Я изменяю исходную строку следующим образом:

исходная строка:

node.ontouchstart = absorbEvent_;

мое изменение:

node.ontouchstart = node.onclick;

с помощью этого подхода я отключаю всплывающее меню сохранения изображения в logpress, но сохраняю событие щелчка.

Я тестирую на 7-дюймовом планшете с Android 2.2 под браузером Dolphin HD и отлично работает!

person GAL    schedule 30.01.2012

Используйте эти коды CSS для мобильных устройств

-webkit-touch-callout: none;
-webkit-user-select: none; /* Disable selection/copy in UIWebView */
person vitralyoz    schedule 06.11.2014
comment
Это не работает для запрошенного браузера, chrome. - person bbsimonbb; 26.02.2015

Это отключит копирование, но не отключит выбор.

document.oncontextmenu = function() {return false;};

Работает в вебвиви.

person devasia2112    schedule 03.07.2019

У меня была аналогичная проблема. Я пробовал пару решений из этого потока и другой поток для сафари по той же проблеме (Предотвращение контекстного меню по умолчанию при длительном нажатии / длительном щелчке в мобильном Safari (iPad / iPhone)). Плохая часть заключалась в том, что я не мог использовать onTouchStart, onTouchEnd и т.д.

Предотвращайте событие только от onContextMenu. Фрагмент из React 16.5.2. Проверял только в хроме.

    <img {...props} onContextMenu={event => event.preventDefault()}
    onTouchStart={touchStart}
    onTouchEnd={touchEnd} />

Надеюсь, это поможет кому-то. Ваше здоровье!


person Vlad Ilie    schedule 19.11.2018
comment
отлично работает в реакции, спасибо ???? - person Maninderpreet Singh; 12.02.2021

<a id="moo" href=''> </a>

<script type="text/javascript">
    var moo = document.getElementById('moo');

    function handler(event) {
        event = event || context_menu.event;

        if (event.stopPropagation)
            event.stopPropagation();

        event.cancelBubble = true;
        return false;
    }

    moo.innerHTML = 'right-click here';

    moo.onclick = handler;
    moo.onmousedown = handler;
    moo.onmouseup = handler;
</script>

Захватите событие onContextMenu и верните false в обработчике событий.

Вы также можете зафиксировать событие щелчка и проверить, какая кнопка мыши вызвала событие с помощью event.button, в любом случае в некоторых браузерах.

person Hare-Krishna    schedule 09.08.2010
comment
Извините, но оба эти метода не работают на Android. Событие oncontextmenu никогда не запускается, а событие click еще не запускается, когда пользователь удерживает элемент касанием. - person Roy Sharon; 12.08.2010

Только что была аналогичная проблема. Приведенные выше предложения не сработали для меня в браузере Android, но я обнаружил, что отображение проблемного изображения в качестве фонового изображения CSS, а не встроенного изображения, решило проблему.

person RichardB    schedule 04.09.2016

Через необработанный javascript нет событий, которые вызываются для контекстного меню. Возможно, в мире Java есть что-то... На самом деле есть несколько проблем, связанных с событиями javascript (например, неправильная работа фокуса) в веб-ките Android.

person Moncader    schedule 09.08.2010
comment
Да я согласен. Поскольку я разработал библиотеку JavaScript, которая будет использоваться внутри браузера, использование java для меня не вариант. - person Roy Sharon; 12.08.2010

person    schedule
comment
пожалуйста, добавьте описание, объясняющее ответ. - person jjj; 12.06.2017
comment
pointer-events: none; по сути является return false CSS для элементов, поэтому в данном случае моя кнопка не работает. - person Vael Victus; 19.01.2021