2012-09-07 53 views
3

我有以下情況。 (A jsfiddle of this can be found hereJavascript文本輸入更改處理程序結合div點擊處理程序

HTML

<div id="container"> 
    <input type="text" id="txtBox" /> 

    <div> 
     <div class="option">Option 1</div> 
     <div class="option">Option 2</div> 
     <div class="option">Option 3</div> 
    </div> 

    <div id="out"></div> 
</div>​ 

的Javascript(jQuery的)

$(".option").click(function(){ 
    $("#out").append("<br/>clicked " + $(this).html()); 
    $("#txtBox").val($(this).html()); 
}); 

$("#txtBox").change(function(){ 
    $("#out").append("<br/>changed value to " + $(this).val()); 
}); 

的想法是,用戶可以在文本框中鍵入一個值,或者可替換地選擇一個從選項列表中選擇。使用ajax調用將所選值寫入數據庫,如果用戶輸入值,則會觸發文本框上的更改處理程序,如果單擊某個選項,則會使用click處理程序。

的問題是在下面的步驟:

  • 在文本框中鍵入
  • 一些隨機值,單擊一個選項
  • - >變更處理程序,並單擊處理程序被觸發在一起。

,因爲現在的變化處理程序使用隨機值,這是在文本框中觸發此最後一種情況是非常不可取的,點擊處理程序使用該選項的HTML屬性觸發。

我想要的只是點擊處理程序的執行和變化處理程序在這種情況下無所作爲(或另一種解決方案在每個可能的用例中只產生一個單一動作的效果。如何處理這個問題?

+0

的變化處理,只要更改焦點從#txtBox路程,#txtBox的內容已經改變執行。無論何時您點擊其中一個選項,#txtBox都會失去焦點,因此如果#txtBox的內容已更改,則更改處理程序將運行。您需要決定何時需要更改處理程序運行。你是否希望它在當前條件下運行,但不是在單擊某個選項時運行? –

+0

這只是一個很常見的例子,當你有一個'blur' /'focusout'事件監聽器,但你希望它根據新的活動元素來做些事情。不幸的是,沒有'relatedTarget'屬性可以提供幫助,比如'mouseout'。 – MaxArt

回答

4

您單擊處理程序更改爲鼠標按下事件:

$(".option").mousedown(function(){ 
    $("#out").append("<br/>clicked " + $(this).html()); 
    $("#txtBox").val($(this).html()); 
}); 

試試:http://jsfiddle.net/CAUQv/

你也可以綁定的keyup事件代替,這樣一來,你每次檢測變化通過實際打字進行:

$("#txtBox").keyup(function(){ 
    $("#out").append("<br/>changed value to " + $(this).val()); 
}); 

試試看:http://jsfiddle.net/RZmtz/

文檔

+0

啊,是的,'mousedown'在'blur' /'change'之前被觸發。好點子。 – MaxArt

+0

如果您使用鼠標將文本粘貼或拖動到輸入字段,這項工作是否可行? –

+0

拖放場景不是由這裏的任何建議代碼或OP代碼(至少在Firefox中)處理的 - 如果您嘗試使用此代碼中的任何代碼,「change」事件都不會被觸發!粘貼與'change'無關,但與'keyup'無關 –

3

您可以在選項點擊處理程序中的輸入的值更改處理程序和clear it中構建timeout

var myTimeout; 

$(".option").click(function(){ 
    clearTimeout(myTimeout); 
    $("#out").append("<br/>clicked " + $(this).html()); 
    $("#txtBox").val($(this).html()); 
}); 

$("#txtBox").change(function(){ 
    myTimeout = setTimeout(function(){ 
    $("#out").append("<br/>changed value to " + $("#txtBox").val()); 
    }, 50); 
}); 
+0

如果您使用鼠標將文本粘貼或拖動到輸入字段,這種方式會工作嗎? http://jsfiddle.net/fZnQy/:p –

+0

它應該,因爲值的變化。 ;-) –

+0

...但它不是 –

1

另一種選擇是 「禁用」 選項,如果用戶鍵入的東西成箱:

http://jsfiddle.net/BcMZM/2/

$(".option").click(function(){ 
    if ($(this).hasClass("disabled")) return false; 

    $("#out").append("<br/>clicked " + $(this).html()); 
    $("#txtBox").val($(this).html()); 
}); 

$("#txtBox").change(function(){ 
    if ($(this).val() == '') return false; 

    $("#out").append("<br/>changed value to " + $(this).val()); 
}); 

$("#txtBox").keyup(function(){ 
    var val = $(this).val();  

    if (val != '') 
     $(".option").addClass("disabled"); 
    else 
     $(".option").removeClass("disabled"); 
}); 
+0

如果您使用鼠標將文本粘貼或拖動到輸入字段,這項工作是否可行? –

+0

@JasperdeVries我不這麼認爲。 'keyup'事件必須被解僱。 – Shmiddty

+0

這對我不起作用,因爲我的目標是使用文本框中的值過濾選項。可能是其他情況的解決方案。 – Asciiom

0
var delay = (function(){ 
var timer = 0; 
return function(callback, ms){ 
    clearTimeout (timer); 
    timer = setTimeout(callback, ms); 
}; 
})(jQuery); 

var clickedOption = false; 
$(".option").click(function(){ 
clickedOption = true; 
$("#out").append("<br/>clicked " + $(this).html()); 
$("#txtBox").val($(this).html()); 
}); 

$("#txtBox").change(function(){ 
var changeThis = $(this); 
delay(function(){ 
if(!clickedOption){ $("#out").append("<br/>changed value to " + changeThis.val()); } 
clickedOption = false; 
}, 50); 

});