변경 전 선택 (드롭 다운) 값 얻기


237

내가 달성하고자하는 것은 <select>드롭 다운이 변경 될 때마다 변경하기 전에 드롭 다운 값을 원한다는 것입니다. 1.3.2 버전의 jQuery를 사용하고 on change 이벤트를 사용하고 있지만 내가 얻은 값은 변경 후입니다.

<select name="test">
<option value="stack">Stack</option>
<option value="overflow">Overflow</option>
<option value="my">My</option>
<option value="question">Question</option>
</select>

onchange 이벤트에서 스택으로 변경할 때 (즉, 스택으로 변경했을 때) 현재 My 옵션이 선택되어 있다고 가정 해 보겠습니다.이 경우 이전 값을 원합니다.

이것이 어떻게 달성 될 수 있습니까?

편집 : 내 경우에는 같은 페이지에 여러 개의 선택 상자가 있고 모든 항목에 동일한 항목이 적용되기를 원합니다. 또한 모든 선택은 ajax를 통해 페이지를로드 한 후에 삽입됩니다.


1
이것을 확인
— 하셨습니까

답변:


434

포커스 이벤트를 변경 이벤트와 결합하여 원하는 것을 달성하십시오.

(function () {
    var previous;

    $("select").on('focus', function () {
        // Store the current value on focus and on change
        previous = this.value;
    }).change(function() {
        // Do something with the previous value after the change
        alert(previous);

        // Make sure the previous value is updated
        previous = this.value;
    });
})();

실례 : http://jsfiddle.net/x5PKf/766


1
@Alpesh : 불행히도, jQuery 1.4.1 이상을 사용하지 않기 때문에 포커스 및 변경 이벤트 와 함께 live () 를 사용할 수 없습니다 . 요소를 페이지에 삽입 한 후 바인드하도록 스크립트를 조정하면됩니다.
— Andy E

1
고마워 나는 이미 라이브와 함께 바인딩했으며 성공적으로 작동했습니다. :)
— Alpesh

4
변경 핸들러에서 select 요소에 집중해야합니다. 그렇지 않으면 반복되는 값 변경 후에 트리거되지 않습니다.
— Alex

52
이 솔루션에 동의하지 않습니다. 값을 한 번 변경하면 작동하지만 한 번 더 변경하면 작동하지 않습니다. 초점을 풀려면 드롭 다운을 클릭하고 다른 곳을 클릭해야합니다. 제안 : $ ( "# dropdownId"). on ( 'change', function () {var ddl = $ (this); var previous = ddl.data ( 'previous'); ddl.data ( 'previous', ddl .val ());});
— free4ride

5
@ free4ride, $(this).blur();변경 함수의 끝에서 호출 할 수 있도록 수정
— chiliNUT

135

이것에 전역 변수를 사용하지 마십시오-여기에 데이터에 이전 값을 저장하십시오 예 : http://jsbin.com/uqupu3/2/edit

심판의 코드 :

$(document).ready(function(){
  var sel = $("#sel");
  sel.data("prev",sel.val());

  sel.change(function(data){
     var jqThis = $(this);
     alert(jqThis.data("prev"));
     jqThis.data("prev",jqThis.val());
  });
});

방금 페이지에 많은 선택이 있음을 보았습니다.이 방법은 각 선택에 대해 선택 값의 데이터에 이전 값을 저장하기 때문에 효과가 있습니다.


jQuery.data는 여기서 좋은 솔루션입니다. 솔루션에서 선택 요소가 많으면 성능에 영향을 미치는 각 선택 항목에 대한 클로저를 작성합니다
— Avi Pinto

내 관심사는 성능에 관한 것이 아니었고, 함수를 만드는 것이 jQuery.data어쨌든 느리다는 것을 확신하지 못한다 .
— August Lilleaas

9
jQuery.data 사용에 대한 반대 의견은 무엇입니까? 내가 아는 한 jQuery 라이브러리도 내부적으로 사용하고 그것을 사용하는 것이 좋습니다
— Avi Pinto

jQuery Data를 사용하는 것에 확실히 동의합니다. 전역 변수를 사용하려고한다는 사실을 상기시켜 주셔서 감사합니다. 전역 변수에는 아무런 문제가 없지만 데이터를 사용하는 것이 더 간결합니다. 그러나 체인 초점과 변화도 좋습니다 :)
— Piotr Kula

4
@ppumkin : 전역 변수에있어 한 가지 분명한 것은 하나만 지원합니다 select! 수락 된 답변은 모두 일치 select하지만 첫 번째 답변 의 값만 저장 하므로 중단됩니다 . data 입니다 그것을 할 수있는 더 좋은 방법. +1 :)
— Gone Coding

86

나는 Avi Pinto의 솔루션을 사용합니다. jquery.data()

초점을 사용하는 것은 유효한 해결책이 아닙니다. 처음에는 옵션을 변경할 때 작동하지만 해당 선택 요소를 유지 한 상태에서 "위"또는 "아래"키를 누릅니다. 포커스 이벤트를 다시 거치지 않습니다.

따라서 솔루션은 다음과 같이 보입니다.

//set the pre data, usually needed after you initialize the select element
$('mySelect').data('pre', $(this).val());

$('mySelect').change(function(e){
    var before_change = $(this).data('pre');//get the pre data
    //Do your work here
    $(this).data('pre', $(this).val());//update the pre data
})

3
선택된 답변보다 훨씬 나은 훌륭한 솔루션!
— TJL

2
두 번째 부분은 잘 작동하지만 첫 번째 부분은 데이터 속성을 설정하지 않습니다. 어떤 아이디어?
— Sinaesthetic

1
@ Sinaesthetic, 나는 같은 문제가 있었고 이미이 대답을 찬성했습니다. 나는 $ (this)가 .data () 메소드에서 살아남지 않는다고 생각합니다. Avi Pinto의 대답은 그 가치에 대한 선택 요소로 되돌아 갔고 이것은 나를 위해 일했습니다 (따라서 Avi도 찬성했습니다).
— goodeye

1
이것은! == $ ( 'mySelect') 이후 작동하지 않습니다. 다음은 고정 버전입니다. var $selectStatus = $('.my-select'); $selectStatus.on('change', function () { var newStatus = $(this).val(); var oldStatus = $(this).data('pre'); }).data('pre', $selectStatus.val());
— Capy

2
은 "mySelect"요소를 모두 @Sinaesthetic이 라인 세트 하나 개의 값 $('mySelect').data('pre', $(this).val());이 같이되어야한다 : $('mySelect').each(function() { $(this).data('pre', $(this).val()); });나는 편집에 대한 답변을 충분히 평판이 없습니다 : /
— 압 데라

8

손으로 값을 추적하십시오.

var selects = jQuery("select.track_me");

selects.each(function (i, element) {
  var select = jQuery(element);
  var previousValue = select.val();
  select.bind("change", function () {
    var currentValue = select.val();

    // Use currentValue and previousValue
    // ...

    previousValue = currentValue;
  });
});

내가 다루어야 할 동일한 페이지에 여러 개의 선택 상자가 있기 때문에 위의 방법을 사용할 수 없습니다.
— Alpesh

1
귀하의 질문에 여러 선택 버튼에 대해 언급하지 않았습니다. 여러 상자를 지원하도록 답변을 업데이트했습니다.
— August Lilleaas

1
가장 좋은 답변입니다. 나는 그 다음 브라우저 호환성 raither에 대한 JQuery와에 의존하는 두 가지 방법의 올바른 흐름 EF 실행 원인이 솔루션 ') usign 초점 ()과 변화 (보다 더 좋은 생각
— coorasse

@ coorasse : 올바른 실행 흐름은 결코 다를 수 없습니다. 요소가 포커스를 갖기 전에 사용자가 선택 상자 값을 변경할 수 없었습니다 . 즉,이 접근 방식에는 아무런 문제가 없습니다 :-)
— Andy E

'클로저'사용 관점에서 이것이 '초점'솔루션보다 나은지 확실하지 않습니다.
— James Poulose 2013

8
 $("#dropdownId").on('focus', function () {
    var ddl = $(this);
    ddl.data('previous', ddl.val());
}).on('change', function () {
    var ddl = $(this);
    var previous = ddl.data('previous');
    ddl.data('previous', ddl.val());
});

이것은 나를 위해 일에만 약간의 보정은 dropdownId에 선택의에 하나가 아닌, 감사
— malkoty

2
사용자 상호 작용없이 변경 이벤트가 발생할 수 있으므로 이는 생각이 아닙니다
— qdev

3

이벤트 "live"를 사용하고 있는데 솔루션은 기본적으로 Dimitiar와 유사하지만 "focus"를 사용하는 대신 "click"이 트리거 될 때 이전 값이 저장됩니다.

var previous = "initial prev value";
$("select").live('click', function () {
        //update previous value
        previous = $(this).val();
    }).change(function() {
        alert(previous); //I have previous value 
    });

2
나는 이것을 사용하지 않을 것입니다. 사용자가 select 요소를 '탭'하고 키보드 화살표를 사용하여 다른 옵션을 선택하면 어떻게됩니까?
— 크리스티안 런달

@Perplexor 예, 키로는 작동하지 않습니다. 그렇지 않으면 키를 누를 때마다 각 값이 저장됩니다. 이것은 사용자가 드롭 다운 메뉴를 클릭한다고 가정합니다. 문제는 '실시간'이벤트가 '포커스'와 함께 작동하지 않는다는 것입니다. 더 나은 해결책을 모르겠습니다.
— 시카 구 스티 아니

현재 값을 포커스에 별도의 변수에 저장할 수 있습니다. 이것은 단지 내 머리 꼭대기에서 온 것이므로 이것이 이상적인지 확실하지 않습니다.
— 크리스티안 런달

'focus'가 'live'이벤트와 함께 작동 할 수 있으면 완벽합니다. 그러나 동적으로 드롭 다운 메뉴를 만들면 '실시간'만 사용할 수 있습니다. 이것이 바로 제가 아는 것입니다. '라이브'에 '초점'불행하게도, 새 값을 저장하기 위해 이벤트를 트리거하지 않습니다,하지만 난 새로운 jQuery로 모르는
— CICA Gustiani에게

jQuery의 새 버전에서는 라이브가 죽었습니다! [ stackoverflow.com/questions/14354040/…
— remo

2

드롭 다운 '변경시'액션 함수를 작성하기 전에 현재 선택된 드롭 다운 값을 선택한 jquery로 전역 변수에 유지하십시오. 함수에서 이전 값을 설정하려면 전역 변수를 사용할 수 있습니다.

//global variable
var previousValue=$("#dropDownList").val();
$("#dropDownList").change(function () {
BootstrapDialog.confirm(' Are you sure you want to continue?',
  function (result) {
  if (result) {
     return true;
  } else {
      $("#dropDownList").val(previousValue).trigger('chosen:updated');  
     return false;
         }
  });
});

1

각도 감시 유형 인터페이스와 함께 사용자 정의 jQuery 이벤트를 사용하는 것은 어떻습니까?

// adds a custom jQuery event which gives the previous and current values of an input on change
(function ($) {
    // new event type tl_change
    jQuery.event.special.tl_change = {
        add: function (handleObj) {
            // use mousedown and touchstart so that if you stay focused on the
            // element and keep changing it, it continues to update the prev val
            $(this)
                .on('mousedown.tl_change touchstart.tl_change', handleObj.selector, focusHandler)
                .on('change.tl_change', handleObj.selector, function (e) {
                // use an anonymous funciton here so we have access to the
                // original handle object to call the handler with our args
                var $el = $(this);
                // call our handle function, passing in the event, the previous and current vals
                // override the change event name to our name
                e.type = "tl_change";
                handleObj.handler.apply($el, [e, $el.data('tl-previous-val'), $el.val()]);
            });
        },
        remove: function (handleObj) {
            $(this)
                .off('mousedown.tl_change touchstart.tl_change', handleObj.selector, focusHandler)
                .off('change.tl_change', handleObj.selector)
                .removeData('tl-previous-val');
        }
    };

    // on focus lets set the previous value of the element to a data attr
    function focusHandler(e) {
        var $el = $(this);
        $el.data('tl-previous-val', $el.val());
    }
})(jQuery);

// usage
$('.some-element').on('tl_change', '.delegate-maybe', function (e, prev, current) {
    console.log(e);         // regular event object
    console.log(prev);      // previous value of input (before change)
    console.log(current);   // current value of input (after change)
    console.log(this);      // element
});

1

나는 이것이 오래된 실이라는 것을 알고 있지만 조금 더 추가 할 수 있다고 생각했습니다. 제 경우에는 텍스트, val 및 기타 데이터 속성을 전달하고 싶었습니다. 이 경우 전체 옵션을 val이 아닌 prev 값으로 저장하는 것이 좋습니다.

아래 예제 코드 :

var $sel = $('your select');
$sel.data("prevSel", $sel.clone());
$sel.on('change', function () {
    //grab previous select
    var prevSel = $(this).data("prevSel");

    //do what you want with the previous select
    var prevVal = prevSel.val();
    var prevText = prevSel.text();
    alert("option value - " + prevVal + " option text - " + prevText)

    //reset prev val        
    $(this).data("prevSel", $(this).clone());
});

편집하다:

요소에 .clone ()을 추가하는 것을 잊었습니다. 값을 되 찾을 때 이전 선택이 아닌 선택의 새 사본을 가져옵니다. clone () 메소드를 사용하면 인스턴스 대신 선택 사본을 저장합니다.


0

음, 현재 선택된 값을 저장하지 않는 이유는 무엇입니까? 선택한 항목이 변경되면 이전 값이 저장됩니까? (원하는대로 다시 업데이트 할 수 있습니다)


내 경우에는 동일한 페이지에 여러 개의 선택 상자가 있기 때문에 그렇게 할 수 없습니다. 그리고 처음에 모든 초기 가치를 저장하는 것은 너무 번거로울 것입니다.
— Alpesh

0

다음 코드를 사용하여 테스트했으며 작동합니다.

var prev_val;
$('.dropdown').focus(function() {
    prev_val = $(this).val();
}).change(function(){
            $(this).unbind('focus');
            var conf = confirm('Are you sure want to change status ?');

            if(conf == true){
                //your code
            }
            else{
                $(this).val(prev_val);
                $(this).bind('focus');
                return false;
            }
});

0
(function() {

    var value = $('[name=request_status]').change(function() {
        if (confirm('You are about to update the status of this request, please confirm')) {
            $(this).closest('form').submit(); // submit the form
        }else {
            $(this).val(value); // set the value back
        }
    }).val();
})();

0

이 문제를 해결하기 위해 다른 옵션을 제공하고 싶습니다. 위에서 제안한 솔루션이 내 시나리오를 해결하지 못했기 때문에.

(function()
    {
      // Initialize the previous-attribute
      var selects = $('select');
      selects.data('previous', selects.val());

      // Listen on the body for changes to selects
      $('body').on('change', 'select',
        function()
        {
          $(this).data('previous', $(this).val());
        }
      );
    }
)();

이것은 jQuery를 사용하여 def를 사용합니다. 여기에 의존하지만 순수한 자바 스크립트에서 작동하도록 조정할 수 있습니다. (본인에 리스너를 추가하고 원래 대상이 선택, 실행 기능인지 확인하십시오.)

바디에 변경 리스너를 연결하면 선택에 대한 특정 리스너 이후에 이것이 발생하는지 확인할 수 있습니다 . 그렇지 않으면 데이터를 읽기 전에 '데이터 이전'값을 덮어 씁니다.

이것은 물론 이전 값과 체크 값에 별도의 리스너를 사용하는 것을 선호한다고 가정합니다. 단일 책임 패턴과 잘 맞습니다.

참고 : 이렇게하면이 '이전'기능이 모든 선택에 추가되므로 필요한 경우 선택기를 미세 조정해야합니다.


0

이것은 @thisisboris 답변의 개선입니다. 데이터에 현재 값을 추가하므로 코드는 현재 값으로 설정된 변수가 변경되는시기를 제어 할 수 있습니다.

(function()
{
    // Initialize the previous-attribute
    var selects = $( 'select' );
    $.each( selects, function( index, myValue ) {
        $( myValue ).data( 'mgc-previous', myValue.value );
        $( myValue ).data( 'mgc-current', myValue.value );  
    });

    // Listen on the body for changes to selects
    $('body').on('change', 'select',
        function()
        {
            alert('I am a body alert');
            $(this).data('mgc-previous', $(this).data( 'mgc-current' ) );
            $(this).data('mgc-current', $(this).val() );
        }
    );
})();

0

최고의 솔루션 :

$('select').on('selectric-before-change', function (event, element, selectric) {
    var current = element.state.currValue; // index of current value before select a new one
    var selected = element.state.selectedIdx; // index of value that will be selected

    // choose what you need
    console.log(element.items[current].value);
    console.log(element.items[current].text);
    console.log(element.items[current].slug);
});

1
이 답변은 "일반"jQuery 또는 자바 스크립트가 아닌 "Selectric"js 라이브러리를 기반으로합니다. Eventhough가 최고이며, 원래 질문에 맞지 않거나 사용자가 작동하기 위해 다른 것을 설치해야한다고 말하지도 않습니다
— gadget00

0

원하는 결과를 얻는 몇 가지 방법이 있습니다. 이것은 겸손한 방법입니다.

요소가 이전 값을 보유하게하려면 속성 'previousValue'를 추가하십시오.

<select id="mySelect" previousValue=""></select>

초기화되면 'previousValue'를 속성으로 사용할 수 있습니다. JS에서이 선택의 이전 값에 액세스하려면 다음을 선택하십시오.

$("#mySelect").change(function() {console.log($(this).attr('previousValue'));.....; $(this).attr('previousValue', this.value);}

'previousValue'를 사용한 후 속성을 현재 값으로 업데이트하십시오.


0

선택에 따라 다른 div를 공개해야했습니다.

이것이 jquery 및 es6 구문으로 수행하는 방법입니다

HTML

<select class="reveal">
    <option disabled selected value>Select option</option>
    <option value="value1" data-target="#target-1" >Option 1</option>
    <option value="value2" data-target="#target-2" >Option 2</option>
</select>
<div id="target-1" style="display: none">
    option 1
</div>
<div id="target-2" style="display: none">
    option 2
</div>

JS

$('select.reveal').each((i, element)=>{
    //create reference variable 
    let $option = $('option:selected', element)
    $(element).on('change', event => {
        //get the current select element
        let selector = event.currentTarget
        //hide previously selected target
        if(typeof $option.data('target') !== 'undefined'){
            $($option.data('target')).hide()
        }
        //set new target id
        $option = $('option:selected', selector)
        //show new target
        if(typeof $option.data('target') !== 'undefined'){
            $($option.data('target')).show()
        }
    })
})
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.