0

1 つの入力フィールドに 2 つのイベント リスナーがあります。1 つは変更時に呼び出され、もう 1 つは Google のオートコンプリート ドロップダウンをクリックしたときに呼び出されます。私の問題は、このようなオートコンプリートをクリックすると、両方のハンドラーが呼び出され、Google API にリクエストを送信することです。

onchange イベントをバインドして、Google オートコンプリート ajax 呼び出しが発生したときにバインドを解除しようとしましたが、onchange イベントが最初に実行されます。したがって、バインドが解除されることはありません。では、ユーザーが手動で入力したか、自動推測を介して入力したかを検出する可能性はありますか? ユーザーが手動で入力し、オートコンプリート ドロップダウンを使用しない場合にのみ、「requestlocation」機能を実行したいと考えています。「フォーカスアウト」などの他のイベントハンドラーで試しましたが、成功しませんでした。

この行はバインドを行います:

autoCompleteInput.on "change", requestlocation

これは呼び出される関数です:

requestlocation = () ->
  address = autoCompleteInput.val()
  geocoder = new google.maps.Geocoder()
  geocoder.geocode
    address: address, (results, status) ->
      if status is google.maps.GeocoderStatus.OK

        if results[0].address_components.length > 1
          city = results[0].address_components[0].long_name
          country = results[0].address_components[results[0].address_components.length-1].long_name
          setHiddenFields results[0].geometry.location.lat(), results[0].geometry.location.lng(), city, country 
          autoCompleteInput.val(city+", "+country)
        else
          city = null
          country = results[0].address_components[0].long_name
          setHiddenFields results[0].geometry.location.lat(), results[0].geometry.location.lng(), city, country
          autoCompleteInput.val(country)
        setMarker new google.maps.LatLng(latInput.val(), lngInput.val())
      else
        console.log "Geocode was not successful for the following reason: " + status

これは、オートコンプリート ハンドラーが要求を行うコードです。

google.maps.event.addListener autocomplete, 'place_changed', ->
  autoCompleteInput.off "change", requestlocation

  place = autocomplete.getPlace()

  if !!place.geometry
    autoCompleteInput.attr "data-valid", "true"
    setMarker place.geometry.location
    address = place.address_components
    if address.length > 1
      setHiddenFields place.geometry.location.lat(), place.geometry.location.lng(), address[0].long_name, address[address.length-1].long_name
    else
      setHiddenFields place.geometry.location.lat(), place.geometry.location.lng(), null, address[0].long_name
  else
    autoCompleteInput.attr "data-valid", "false"

  autoCompleteInput.on "change", requestlocation

回答ありがとうございます。

4

2 に答える 2

2

最初のアプローチ: のkeyup代わりにイベントをリッスンしchange、ハンドラーでのキー押下のタイプを決定し (矢印キー、タブ、およびリターン キーをフィルターで除外) requestlocation、適切な変更が発生した場合にのみ呼び出します。キーイベントをトリガーしない入力フィールドにテキストを貼り付けることができるため、実際には機能しない可能性があります。

次の試行: 短いタイムアウトを使用し、オートコンプリート イベントが発生した場合は停止します。

autocomplete.on "change", ->
  # stop previous timeouts
  clearTimeout autocomplete.data('timeout')
  # start a new timeout and store reference
  timeout = setTimeout requestlocation, 100
  autocomplete.data timeout: timeout

オートコンプリート ハンドラーでは、実行中のタイムアウトを強制終了し、呼び出しを実行する必要があります。

google.maps.event.addListener autocomplete, 'place_changed', ->
  # stop any running timeout
  clearTimeout autocomplete.data('timeout')
  # perform your autocompletion calls
  place = autocomplete.getPlace()
  ...

changeこれにより、複数のイベントが急速に発生した場合の複数の呼び出しも防止されます。タイムアウト (ここでは 100ms) を適切な値に調整する必要がある場合があります。

于 2012-04-18T21:32:00.203 に答える
0

「requestlocation」がどのように見えるかわかりません。しかし、change イベントのさまざまなイベント プロパティを確認するのはどうでしょうか。(event.target / event.currentTarget) 今はテストできませんが、違いがあるかもしれません。ただのアイデア

function requestlocation(event) {
  console.log(event.target, event.currentTarget);
}

var timeout;
autoCompleteInput.on("input", function() {
  clearTimeout(timeout);
  timeout = setTimeout(requestlocation, 100);
});

プレーンなJavaScriptで申し訳ありませんが、私はコーヒースクリプトには興味がありません:/

于 2012-04-18T20:33:18.593 に答える