<p>O folheto 1.7.1 faz com que eventos de 2 cliques sejam emitidos pelos controles do folheto no Safari</p>

Criado em 5 set. 2020  ·  39Comentários  ·  Fonte: Leaflet/Leaflet

Passos para reproduzir
Passos para reproduzir o comportamento:

  • configura um mapa básico, com um controle que tem um botão, que escuta os eventos de clique e os publica no console
  • clique no botão no controle usando o Safari em um Mac
  • veja dois eventos de clique no console, um com isTrusted:true e outro com isTrusted:false atributos

(Usar 'forçar toque' para clicar no botão em um trackpad resulta na emissão de apenas um único evento de clique, mas também aciona o pop-up de visualização do Safari.)

Comportamento esperado

Deve haver apenas um evento de clique emitido, com o atributo isTrusted:true .

O Leaflet seria capaz de filtrar com segurança os eventos de clique com isTrusted:false ?

Comportamento atual

Na versão 1.6 o comportamento esperado é observado. Na versão 1.7.1, o Chrome exibe o comportamento esperado, mas o Safari não.

As diferenças entre os dois eventos estão incluídas abaixo.

MouseEvent 1:

MouseEvent

_simulated: true
composed: false
isTrusted: false
layerX: 15
layerY: 28
offsetX: 15
offsetY: 28
pageX: 410
pageY: 46
screenX: 1390
screenY: 189
timeStamp: 499337
webkitForce: 0
x: 410
y: 38

MouseEvent 2:

MouseEvent

composed: true
isTrusted: true
layerX: 15
layerY: 20
offsetX: 15
offsetY: 20
pageX: 410
pageY: 38
screenX: 1390
screenY: 189
timeStamp: 538265
webkitForce: 1
x: 410
y: 38

_simulated , composed , isTrusted e talvez webkitForce parecem ser as principais diferenças, mas também parece estranho que haja diferentes carimbos de data / hora e dimensões Y entre os dois eventos.

Meio Ambiente

  • Versão do folheto: 1.7.1
  • Navegador (com versão): Safari 13.1.2
  • OS / Plataforma (com versão): OS X 10.13.6 e 10.15.6

Contexto adicional

Percebi isso depois que o OpenStreetMap foi atualizado para a versão mais recente do Leaflet, onde o problema se manifesta ao impedir que algumas das ferramentas de mapa sejam usadas, pois o primeiro evento ativa uma ferramenta e o segundo a desativa. Problema relacionado postado em https://github.com/openstreetmap/openstreetmap-website/issues/2811

Exemplo mínimo reproduzindo o problema

Consulte https://codepen.io/dankarran/pen/JjXMXzd

bug compatibility

Comentários muito úteis

Também encontrei esse problema no Firefox (e no safari móvel). Não fui capaz de reproduzi-lo de forma confiável, mas a dica de que vem da opção de toque me levou à solução que desativa totalmente o toque, pois aparentemente não preciso disso para abrir o pop-up, mesmo no safari móvel:

var map = L.map('map', { "tap": false });

Todos 39 comentários

Exemplo mínimo reproduzindo o problema

Por uma questão de clareza: esse exemplo está usando

    L.DomEvent.on(container, "click", function(e) {

O Leaflet seria capaz de filtrar com segurança os eventos de clique com isTrusted:false ?

Seria possível fazer isso em addOne() em DomEvent.js , por volta de https://github.com/Leaflet/Leaflet/blob/4f32a5e83525a3a42980c974e48712b058510eb5/src/dom/DomEvent.js#L109

Com uma nova ramificação nessa cadeia if-then-else, algo provavelmente como

} else if (Browser.safari && !Browser.mobile && type === 'click') {
  handler = function (ev) {
    if (ev.isTrusted) { originalHandler(ev); }
  }
  obj.addEventListener('click', handler, false);
} // etc

No entanto, não possuo nenhum hardware Apple (no momento), então não posso testar isso; e não sei se isso pode afetar as versões anteriores do Safari para desktop.

O evento simulado vem de https://github.com/Leaflet/Leaflet/blob/4f32a5e83525a3a42980c974e48712b058510eb5/src/map/handler/Map.Tap.js#L100

Portanto, sugiro alterar a condição em https://github.com/Leaflet/Leaflet/blob/4f32a5e83525a3a42980c974e48712b058510eb5/src/map/handler/Map.Tap.js#L87

em algo como

if (this._fireClick && e && e.changedTouches && !(Browser.safari && !Browser.mobile)) { 

No entanto, não possuo nenhum hardware Apple (no momento), então não posso testar isso; e não sei se isso pode afetar as versões anteriores do Safari para desktop ou outros navegadores (o bug pode ser reproduzido no celular firefox?).

Acho que esse bug foi introduzido em

https://github.com/Leaflet/Leaflet/pull/7010/files#diff -c2e3d5ef35bf1c4a7c6b549ddf734725R134

@ johnd0e , pode dar uma olhada? Talvez você tenha introduzido essa mudança na conta do iOS, mas afetou acidentalmente o macOS para desktop?

Obrigado por investigar isso @IvanSanchez. Fico feliz em ajudar a testar quaisquer alterações propostas no Safari no Mac ou iOS.

Só para acrescentar, há um problema relacionado no Safari no iOS, mas parece se comportar de maneira um pouco diferente. Eu não fiz muitos testes nisso.

@ johnd0e , pode dar uma olhada? Talvez você tenha introduzido essa mudança na conta do iOS, mas afetou acidentalmente o macOS para desktop?

Isso definitivamente foi feito para resolver problemas do iOS, consulte a discussão: https://github.com/Leaflet/Leaflet/pull/7010.
E usamos safari propriedade intencionalmente, para não ser muito específico.

Possíveis correções rápidas:

  • introduzir Browser.ios propriedade
  • ou use Browser.safari && Browser.mobile

Mas e se amanhã recebermos o macbook com touchscren? Isso vai quebrar tudo de novo.

Portanto, proponho aplicar a correção rápida ( Browser.safari && Browser.mobile ) o mais rápido possível e, em seguida, discutir a solução final aqui: # 6980

* or use `Browser.safari && Browser.mobile`

Eu gosto dessa abordagem (como uma correção "rápida e suja").

Mas e se amanhã recebermos o macbook com touchscren? Isso vai quebrar tudo de novo.

Você sabe que minha resposta, no final, será # 7200 :-)

Você sabe que minha resposta, no final, será # 7200 :-)

Não tenho tanta certeza)
Mas, de qualquer forma, prefiro consertar tudo o que pudermos mantendo a abordagem atual e, em seguida, seguir adiante (para o # 7200 ou qualquer outra coisa).

Não tenho certeza se este é o mesmo problema (por favor, perdoe a marcação no final do tíquete existente), mas shift-drag para aumentar o zoom também está quebrado em 1.7.1 no Safari para desktop. Fico feliz em abrir um novo problema se o # 7260 não tiver corrigido isso também.

@systemed Você pode tentar arrastar e arrastar usando https://s3.amazonaws.com/leafletjs-cdn/content/leaflet/master/leaflet-src.js ? (por exemplo, https://plnkr.co/edit/v4GzrCYSxpIO1aOo) Essa é uma construção de master que já inclui as alterações de # 7260.

Spot on - isso funciona bem. 👍

Como apareceu, o mesmo problema afeta não apenas o Safari para desktop, mas também o Edge (e quem sabe o que mais).
AFAIK atm tap handler é necessário apenas para iOS.

Então ... Podemos mudar o padrão de false map.options.tap para false .

Atualizei meu codepen para usar o código criado a partir do mestre e também para exibir os eventos para facilitar o teste no celular.

Está funcionando bem no Safari para desktop, mas, infelizmente, parece que o Safari móvel ainda está disparando dois eventos de clique.

Se o JS em https://s3.amazonaws.com/leafletjs-cdn/content/leaflet/master/leaflet-src.js for a versão mais recente, ainda está disparando dois eventos de clique no iOS Safari.

@dagjomar
Você é capaz de inspecionar esses eventos?

Pode ser um problema diferente.

Porque em touchstart (e pointerdown ) nós evitamos click aqui:
https://github.com/Leaflet/Leaflet/blob/dda26ba96d7dc79213818d1bcc0565b6ac3c69c4/src/map/handler/Map.Tap.js#L43
E não vejo razão para que isso não funcione.

@ johnd0e Vou ver se consigo mais detalhes e avisar você. Faria diferença que tipo de elemento foi usado (por exemplo, a ou button que teria seus próprios manipuladores de clique vs div que não teria)?

Eu atualizei o codepen para registrar alguns detalhes de eventos simplificados no console. Os eventos no iOS parecem ser os mesmos vistos na área de trabalho antes desta atualização:

type: click
isTrusted: false
composed: false
_simulated: true
webkitForce: 0
type: click
isTrusted: true
composed: true
webkitForce: 1

Além disso, os elementos a e div se comportam da mesma forma e adicionar e.preventDefault() em meu manipulador de eventos não resolve.

Deixe-me saber se há mais alguma coisa que você gostaria que eu tentasse @ johnd0e?

É possível que as seguintes linhas não sejam necessárias, se o Safari estiver disparando seus próprios eventos de clique?

https://github.com/Leaflet/Leaflet/blob/4f32a5e83525a3a42980c974e48712b058510eb5/src/map/handler/Map.Tap.js#L98 -L101

A propósito, acabei de verificar e o Chrome (v85) no iOS está se comportando da mesma forma, com dois eventos disparados.

Ok, veja o que encontrei:
1) Impedir mousedown / pointerdown não cancela click . Apenas touchstart pode ser evitado.
2) Mas atualmente o Leaflet tem um comportamento bastante estranho (# 7077): quando eventos de ponteiro estão disponíveis - ele substitui eventos de toque por eventos de ponteiro.

É por isso que agora temos esses cliques extras.

Portanto, para corrigir isso, devemos adotar um destes: # 7029, # 7026.
@IvanSanchez

Se ajudar como uma solução rápida como um paliativo (e não quebrar outras coisas), comentar esse evento simulado parece funcionar para mim no Chrome e no Safari no iOS ...

https://github.com/Leaflet/Leaflet/blob/4f32a5e83525a3a42980c974e48712b058510eb5/src/map/handler/Map.Tap.js#L100

@systemed Você pode tentar arrastar e arrastar usando https://s3.amazonaws.com/leafletjs-cdn/content/leaflet/master/leaflet-src.js ? (por exemplo, https://plnkr.co/edit/v4GzrCYSxpIO1aOo) Essa é uma construção de master que já inclui as alterações de # 7260.

https://s3.amazonaws.com/leafletjs-cdn/content/leaflet/master/leaflet-src.js
^ esta versão parece funcionar muito melhor do que 1.7.1 no Safari 14.0 para desktop.
tocar ou clicar dispara apenas uma vez 👍

Se ajudar como uma solução rápida como um paliativo (e não quebrar outras coisas), comentar esse evento simulado parece funcionar para mim no Chrome e no Safari no iOS ...

https://github.com/Leaflet/Leaflet/blob/4f32a5e83525a3a42980c974e48712b058510eb5/src/map/handler/Map.Tap.js#L100

Tive o problema de evento de 2 cliques em todos os dispositivos (desktop firefox, chrome, ios safari, chrome ..) e isso resolveu o problema

O mesmo problema acontece comigo e só acontece no Safari. O Chrome e o Firefox só disparam o evento uma vez no MacOS 10.15.6 e no Safari 14.0.

Eu diminuí temporariamente o folheto para 1.6 e tudo funciona normalmente.

Existe uma chance de que esse bug seja corrigido?
Alguém trabalha nisso?

Como eu já disse: o bug é causado por tap handler extremamente desatualizado (# 6980).

Para começar, precisamos tomar algumas decisões: https://github.com/Leaflet/Leaflet/issues/7255#issuecomment -691109158
@IvanSanchez @mourner

Para começar, precisamos tomar algumas decisões: # 7255 (comentário)

@ johnd0e Não tenho tempo para testar isso, nem qualquer hardware iOS. De qualquer forma, estou confiando em você nisso, então estou dando sinal verde para o # 7026 (que parece mais limpo do que o # 7029)

Alguém trabalha nisso?

Você sabe o que seria legal, @ PeterPan73? Para você prosseguir fazendo algumas compilações de # 7026 e # 7029, e testando-as para mais problemas de compatibilidade, em vez de apenas colocar mais pressão sobre os mantenedores.

então estou dando luz verde # 7026 (que parece mais limpo do que # 7029)

Infelizmente, no último commit de # 7026, tive que aplicar soluções alternativas para superar outros bugs (que por sua vez podem ser corrigidos por # 7029 e # 7059).

Então, no final, ainda teremos que lidar com o # 7029 e outros PRs conectados, é por isso que os uni em https://github.com/Leaflet/Leaflet/projects/1

Eu me deparo com esse problema no macOS 10.15.7 usando o Chrome 85 DevTools com o dispositivo iOS habilitado. A solução mais rápida para mim foi usar a função Lodash debounce .

Hoje me deparei com um problema que parece relacionado a este, então postarei minha experiência aqui.
Isso ocorre com o trackpad do Macbook e eu descobri isso, ao tentar adicionar um menu de contexto personalizado ao mapa.
O que acontece é que, uma vez que o mapa tenha o foco, mesmo se você clicar com o botão direito do mouse no menu de contexto, o Leaflet disparará um evento _click_ simulado, que não deve ser disparado e tem button valor 0. Isso leva a interações estranhas com meu manipulador próximo para o menu de contexto.

Para produzir o bug, você pode acessar https://leafletjs.com e:

  1. Clique no mapa (para que o mapa tenha o foco)
  2. "Clique com o botão direito"
  3. Clique no mapa
  4. "Clique com o botão direito"

O que você verá é que o cursor está no modo de arrastar e quando você clicar duas vezes no mapa (uma vez no menu de contexto de fechamento e uma vez para acionar o evento de clique), o mapa irá pular.

Talvez isso também esteja relacionado a alguns outros problemas (por exemplo, # 6865).

Este evento de clique duas vezes (um confiável, outro não) ocorre para mim em 1.7.1 ao simular mobile no Chrome e Firefox no desktop Linux (não aconteceu no 1.6). Funciona bem em dispositivos reais de toque Android (Chrome / Firefox testado). Por enquanto, resolvi isso implementando meu próprio temporizador de rejeição no manipulador de eventos de clique, filtrando os cliques que acontecem dentro de 150 ms a partir do último.

Por enquanto, resolvi isso implementando meu próprio temporizador de rejeição no manipulador de eventos de clique, filtrando os cliques que acontecem dentro de 150 ms a partir do último.

Olá @atorger , como você implementou isso? Tentei event.originalEvent.preventDefault(); no manipulador de eventos onClick, mas sem sucesso. Você pode compartilhar um exemplo mínimo? 🙏 😄

Por enquanto, resolvi isso implementando meu próprio temporizador de rejeição no manipulador de eventos de clique, filtrando os cliques que acontecem dentro de 150 ms a partir do último.

Olá @atorger , como você implementou isso? Tentei event.originalEvent.preventDefault(); no manipulador de eventos onClick, mas sem sucesso. Você pode compartilhar um exemplo mínimo? reze sorriso

certo:

var lastClick = Date.now();
e.addEventListener('click', function(event) {
    var now = Date.now();
    var diff = now - lastClick;
    lastClick = now;
    event.stopPropagation();
    if (diff > 150) {
        // handle the click event
    }
});

Observe que esse problema também faz com que bindPopup não funcione com marcadores:

Também encontrei esse problema no Firefox (e no safari móvel). Não fui capaz de reproduzi-lo de forma confiável, mas a dica de que vem da opção de toque me levou à solução que desativa totalmente o toque, pois aparentemente não preciso disso para abrir o pop-up, mesmo no safari móvel:

var map = L.map('map', { "tap": false });

Também encontrei esse problema no Firefox (e no safari móvel). Não fui capaz de reproduzi-lo de forma confiável, mas a dica de que vem da opção de toque me levou à solução que desativa totalmente o toque, pois aparentemente não preciso disso para abrir o pop-up, mesmo no safari móvel:

var map = L.map('map', { "tap": false });

Obrigado por esta solução, @eikes! Eu encontrei esse problema hoje e isso o resolveu.

Aparentemente, não preciso abrir o pop-up, mesmo no safari móvel:

No safári móvel, o manipulador tap é necessário para simular o evento contextmenu no taphold.

Este bug dispara dois toques ao tentar clicar no mapa em um dispositivo móvel.

Esta página foi útil?
0 / 5 - 0 avaliações