jQuery-숨겨진 입력 필드에서 값 변경 감지


270

AJAX 응답을 통해 값이 업데이트되는 숨겨진 텍스트 필드가 있습니다.

<input type="hidden" value="" name="userid" id="useid" />

이 값이 변경되면 AJAX 요청을 시작하고 싶습니다. 누구든지 변경을 감지하는 방법에 대해 조언 할 수 있습니까?

다음 코드가 있지만 값을 찾는 방법을 모릅니다.

$('#userid').change( function() {  
    alert('Change!'); 
}) 

2
Ajax 응답을 통해 업데이트되는 경우 응답의 성공 함수에서 새로운 Ajax 요청을 실행하지 않는 이유는 무엇입니까?
BonyT

2
$ ( '# userid'). val ()은 그것이 당신이 요구하는 것이라면 당신에게 가치를 줄 것입니다
BonyT

업데이트 : 숨겨진 필드의 값이 업데이트되면 변경 이벤트가 트리거됩니다.
Steven

답변:


622

그래서 이것은 늦었지만이 스레드를 우연히 본 사람에게 유용 할 경우를 대비하여 답을 찾았습니다.

숨겨진 요소의 값을 변경해도 .change () 이벤트가 자동으로 발생하지 않습니다. 따라서 해당 값을 설정하는 위치에 관계없이 jQuery에 값을 트리거하도록 지시해야합니다.

function setUserID(myValue) {
     $('#userid').val(myValue)
                 .trigger('change');
}

그런 경우

$('#userid').change(function(){
      //fire your ajax call  
})

예상대로 작동합니다.


5
.trigger()바로 전화를 통해 사용할 수 일반적으로 더 나은 change()?
Hanna

1
작동하지만 변경 이벤트를 두 번 트리거하는 것처럼 보입니다!. 이 코드를 넣는 것과 같습니다. 코드를 제거하면 트리거가 두 번 발생하지 않습니다.
베네수엘라에서 Janx

1
change이벤트 와 동일하게 작동하려면 setUserID()값을 실제로 변경하는지 여부를 확인하기 위해 코드를 추가해야합니다 . if ($('#userid').val() != myVaule) { // set val() and trigger change }
nnattawat

1
당신은 자바 스크립트를 통해 변경되는대로, 그렇지 않으면 자바 스크립트에 의한 변경이 .change (핸들러) 또는 CSTE 연구진 ( "변화", 핸들러)에 의해 체포 될 수없는 "변경"이벤트를 잡으려고 노력하는 경우에 특히 유용합니다
JJK

7
숨겨진 필드의 값을 변경하는 함수를 제어하지 않으면 (즉 트리거를 실행할 수 없음)이 솔루션이 작동하지 않습니다.
osama yaccoub

31

숨겨진 입력은 변경시 "change"이벤트를 트리거하지 않기 때문에 대신 MutationObserver를 사용하여이를 트리거했습니다.

(때로는 숨겨진 입력 값 변경은 수정할 수없는 다른 스크립트에 의해 수행됩니다)

IE10 이하에서는 작동하지 않습니다

MutationObserver = window.MutationObserver || window.WebKitMutationObserver;

var trackChange = function(element) {
  var observer = new MutationObserver(function(mutations, observer) {
    if(mutations[0].attributeName == "value") {
        $(element).trigger("change");
    }
  });
  observer.observe(element, {
    attributes: true
  });
}

// Just pass an element to the function to start tracking
trackChange( $("input[name=foo]")[0] );

AFAIK 변이 관측기는 텍스트 필드 내부의 변경에 대해 해고되지 않습니다 (숨겨져 있든
없든

3
잘 작동합니다! @OleAlbers-OP에 대해 질문input[type=hidden]
Shay

1
jquery의 map 명령을 사용하여 숨겨진 입력 필드 값 모음을 검색하는 함수와 함께 이것을 사용했습니다. 너무 감사합니다 @lulalala!
AdamJones

2
간단하고 이해하기 쉽습니다. "값을 변경할 때 이벤트를 트리거해야합니다"솔루션과 달리이 솔루션은 값이 변경되는 시점에서 코드에 액세스 할 수있는 프로그래머에게 의존하지 않으므로 원하는만큼 유용합니다. IE11 이전 버전을 지원할 필요가 없습니다. 그것은 나를 위해 잘 작동했습니다. 감사합니다
조 살라 자르

훌륭한 솔루션! 감사합니다! 어떤 이유로 든 trigger('change')나를 위해 작동하지 않아서 CustomEvent를 만들고 등록 한 다음element.dispatchEvent(myCustomEvent)
tbutcaru

8

아래 함수를 사용하면됩니다. type 요소를 변경할 수도 있습니다.

 $("input[type=hidden]").bind("change", function() {
       alert($(this).val()); 
 });

숨겨진 요소의 값을 변경해도 .change () 이벤트가 자동으로 발생하지 않습니다. 따라서 해당 값을 설정하는 위치에 관계없이 jQuery에 값을 트리거하도록 지시해야합니다.

HTML

 <div id="message"></div>
<input type="hidden" id="testChange" value="0"  />    

자바 스크립트

var $message = $('#message');
var $testChange = $('#testChange');
var i = 1;

function updateChange() {
    $message.html($message.html() + '<p>Changed to ' + $testChange.val() + '</p>');
}

$testChange.on('change', updateChange);

setInterval(function() {
    $testChange.val(++i).trigger('change');; 
    console.log("value changed" +$testChange.val());
}, 3000);

updateChange();

예상대로 작동합니다.

http://jsfiddle.net/7CM6k/3/


1
나를 위해 일하지 않고 ... 어쨌든 숨겨진 필드에 가치를 붙여 넣을 수 있습니까? : /
Simon Dugré

고마워요, 붙여 넣기는 없어야하지만 변경 사항은 숨겨진 필드 변경 이벤트를 감지 할 수 있습니다
Tarun Gupta

는이 바이올린 업데이트 따르십시오, 명시 적으로 변화를 감지 할 수 있도록 @KrisErickson 덕분에 바이올린, 나는 코드를 업데이트 한 jsfiddle.net/7CM6k/3
Tarun 굽타

1
@TarunGupta 예, 트리거에서 작동하지만 값을 변경하지는 않습니다. 숨겨진 값이 변경된 경우 브라우저가 변경 이벤트를 시작하지 않으므로 수동으로 수행해야합니다.
Kris Erickson

모든 숨겨진 필드에 대한 바인딩에 대한이 답변의 첫 부분은 매우 유용했습니다. 감사!
차드


4

사용할 수 있습니다 Object.defineProperty()입력 요소의 '값'속성을 재정의하고 변화하는 동안 무엇을하기 위해.

Object.defineProperty() 속성에 대한 getter 및 setter를 정의하여 제어 할 수 있습니다.

replaceWithWrapper($("#hid1")[0], "value", function(obj, property, value) { 
  console.log("new value:", value)
});

function replaceWithWrapper(obj, property, callback) {
  Object.defineProperty(obj, property, new function() {
    var _value = obj[property];
    return {
      set: function(value) {
        _value = value;
        callback(obj, property, value)
      },
      get: function() {
        return _value;
      }
    }
  });
}

$("#hid1").val(4);

https://jsfiddle.net/bvvmhvfk/


1
나는이 접근 방식을 좋아한다. 특히 다른 모든 사람들의 대답은 "변화를 스스로 유발한다"는 것이기 때문에 항상 실현 가능한 것은 아니다.
sMyles

1
jsfiddle을 확인하면 숨겨진 필드 값이 '123'(Chrome 사용)에서 변경되지 않음을 확인하면 숨겨진 필드의 최종 값은 실제로 변경되지 않습니다.
MetaGuru

매우 가깝지만 다른 사람들이 언급했듯이 필드의 원래 뮤 테이터 / 세터에 대한 참조를 유지하지 않으므로 업데이트가 숨겨진 입력 자체에 영향을 미치지 않습니다. 이 접근법의 일부와 stackoverflow.com/a/38802602/4342230
GuyPaddock

0

이 예에서는 숨겨진 초안 필드의 값이 변경 될 때마다 초안 필드 값을 반환합니다 (크롬 브라우저).

var h = document.querySelectorAll('input[type="hidden"][name="draft"]')[0];
//or jquery.....
//var h = $('input[type="hidden"][name="draft"]')[0];

observeDOM(h, 'n', function(draftValue){ 
  console.log('dom changed draftValue:'+draftValue);
});


var observeDOM = (function(){
var MutationObserver = window.MutationObserver || 
window.WebKitMutationObserver;

  return function(obj, thistime, callback){
    if(typeof obj === 'undefined'){
      console.log('obj is undefined');
      return;
    }

    if( MutationObserver ){

        // define a new observer
        var obs = new MutationObserver(function(mutations, observer){

            if( mutations[0].addedNodes.length || mutations[0].removedNodes.length ){

               callback('pass other observations back...');

            }else if(mutations[0].attributeName == "value" ){

               // use callback to pass back value of hidden form field                            
               callback( obj.value );

            }

        });

        // have the observer observe obj for changes in children
        // note 'attributes:true' else we can't read the input attribute value
        obs.observe( obj, { childList:true, subtree:true, attributes:true  });

       }
  };
})();

0

의 오프 구축 비크의 대답 , 여기 당신이 그 이후의 변경 이벤트 get 및 해고 보장하기 위해 주어진 숨겨진 입력 요소에 한 번 호출 할 수 있습니다 구현입니다 때마다 입력 요소의 값이 변경 :

/**
 * Modifies the provided hidden input so value changes to trigger events.
 *
 * After this method is called, any changes to the 'value' property of the
 * specified input will trigger a 'change' event, just like would happen
 * if the input was a text field.
 *
 * As explained in the following SO post, hidden inputs don't normally
 * trigger on-change events because the 'blur' event is responsible for
 * triggering a change event, and hidden inputs aren't focusable by virtue
 * of being hidden elements:
 * https://stackoverflow.com/a/17695525/4342230
 *
 * @param {HTMLInputElement} inputElement
 *   The DOM element for the hidden input element.
 */
function setupHiddenInputChangeListener(inputElement) {
  const propertyName = 'value';

  const {get: originalGetter, set: originalSetter} =
    findPropertyDescriptor(inputElement, propertyName);

  // We wrap this in a function factory to bind the getter and setter values
  // so later callbacks refer to the correct object, in case we use this
  // method on more than one hidden input element.
  const newPropertyDescriptor = ((_originalGetter, _originalSetter) => {
    return {
      set: function(value) {
        const currentValue = originalGetter.call(inputElement);

        // Delegate the call to the original property setter
        _originalSetter.call(inputElement, value);

        // Only fire change if the value actually changed.
        if (currentValue !== value) {
          inputElement.dispatchEvent(new Event('change'));
        }
      },

      get: function() {
        // Delegate the call to the original property getter
        return _originalGetter.call(inputElement);
      }
    }
  })(originalGetter, originalSetter);

  Object.defineProperty(inputElement, propertyName, newPropertyDescriptor);
};

/**
 * Search the inheritance tree of an object for a property descriptor.
 *
 * The property descriptor defined nearest in the inheritance hierarchy to
 * the class of the given object is returned first.
 *
 * Credit for this approach:
 * https://stackoverflow.com/a/38802602/4342230
 *
 * @param {Object} object
 * @param {String} propertyName
 *   The name of the property for which a descriptor is desired.
 *
 * @returns {PropertyDescriptor, null}
 */
function findPropertyDescriptor(object, propertyName) {
  if (object === null) {
    return null;
  }

  if (object.hasOwnProperty(propertyName)) {
    return Object.getOwnPropertyDescriptor(object, propertyName);
  }
  else {
    const parentClass = Object.getPrototypeOf(object);

    return findPropertyDescriptor(parentClass, propertyName);
  }
}

다음과 같이 준비된 문서에서 이것을 호출하십시오.

$(document).ready(function() {
  setupHiddenInputChangeListener($('myinput')[0]);
});

-4

이 글타래는 3 살이지만 내 해결책은 다음과 같습니다.

$(function ()
{
    keep_fields_uptodate();
});

function keep_fields_uptodate()
{
    // Keep all fields up to date!
    var $inputDate = $("input[type='date']");
    $inputDate.blur(function(event)
    {
        $("input").trigger("change");
    });
}

3
블러 이벤트는 입력에서 포커스를 잃을 때만 트리거됩니다. 숨겨진 입력에 대한 올바른 응답이 아닙니다
manuerumx
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.