저장되지 않은 변경 사항으로 웹 페이지를 떠나기 전에 사용자에게 경고


341

신청서에 양식이있는 페이지가 있습니다.

다른 사람이 브라우저 탭을 탐색하거나 닫을 경우 저장되지 않은 데이터로 양식을 실제로 남기고 싶은지 묻는 메시지가 표시되도록 양식을 어떻게 보호 할 수 있습니까?



3
이 질문에 대한 답은 다음과 같습니다 : stackoverflow.com/questions/1244535/…
Nexerus


답변:


556

짧고 오답 :

이벤트처리하고 beforeunload널이 아닌 문자열을 리턴하여 이를 수행 할 수 있습니다 .

window.addEventListener("beforeunload", function (e) {
    var confirmationMessage = 'It looks like you have been editing something. '
                            + 'If you leave before saving, your changes will be lost.';

    (e || window.event).returnValue = confirmationMessage; //Gecko + IE
    return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
});

이 방법의 문제점 은 양식제출하면 unload 이벤트도 발생한다는 것 입니다. 이것은 양식을 제출하는 플래그를 추가하여 쉽게 수정됩니다.

var formSubmitting = false;
var setFormSubmitting = function() { formSubmitting = true; };

window.onload = function() {
    window.addEventListener("beforeunload", function (e) {
        if (formSubmitting) {
            return undefined;
        }

        var confirmationMessage = 'It looks like you have been editing something. '
                                + 'If you leave before saving, your changes will be lost.';

        (e || window.event).returnValue = confirmationMessage; //Gecko + IE
        return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
    });
};

그런 다음 제출시 setter를 호출하십시오.

<form method="post" onsubmit="setFormSubmitting()">     
    <input type="submit" />
</form>

그러나 읽어보십시오 ...

길고 정답 :

또한 사용자가 양식에서 아무 것도 변경하지 않은 경우이 메시지를 표시하지 않으려 고 합니다 . 한 가지 해결책은 beforeunload이벤트를 "dirty"플래그와 함께 사용하여 실제로 관련이있는 경우에만 프롬프트를 트리거하는 것입니다.

var isDirty = function() { return false; }

window.onload = function() {
    window.addEventListener("beforeunload", function (e) {
        if (formSubmitting || !isDirty()) {
            return undefined;
        }

        var confirmationMessage = 'It looks like you have been editing something. '
                                + 'If you leave before saving, your changes will be lost.';

        (e || window.event).returnValue = confirmationMessage; //Gecko + IE
        return confirmationMessage; //Gecko + Webkit, Safari, Chrome etc.
    });
};

이제이 isDirty방법 을 구현하기 위해 다양한 접근 방식이 있습니다.

jQuery와 form serialization을 사용할 수 있지만이 방법에는 몇 가지 결함이 있습니다. 먼저 모든 형식에서 작동하도록 코드를 변경 $("form").each()해야하지만 가장 큰 문제는 jQuery가 serialize()명명되지 않은 비활성화 된 요소에서만 작동하므로 비활성화되거나 명명되지 않은 요소를 변경하면 더티 플래그가 트리거되지 않는다는 것입니다. 이에 대한 해결 방법이 있습니다컨트롤을 활성화, 직렬화 및 비활성화하는 대신 컨트롤을 읽기 전용으로 설정 등의 .

따라서 이벤트는 갈 길로 보입니다. 키 누르기를들을 수 있습니다 . 이 이벤트에는 몇 가지 문제가 있습니다.

  • 확인란, 라디오 버튼 또는 마우스 입력을 통해 변경되는 기타 요소에서는 트리거되지 않습니다.
  • 키와 관련이없는 키 누르기를 트리거합니다 Ctrl.
  • JavaScript 코드를 통해 설정된 값에서 트리거되지 않습니다.
  • 상황에 맞는 메뉴를 통해 텍스트를 자르거나 붙여 넣을 때 트리거되지 않습니다.
  • JavaScript를 통해 숨겨진 입력에 값을 저장하는 날짜 선택기 또는 확인란 / 라디오 버튼 아름답 기와 같은 가상 입력에는 작동하지 않습니다.

change이벤트JavaScript 코드에서 설정된 값에서 트리거되지 않으므로 가상 입력에서도 작동하지 않습니다.

input이벤트를 페이지의 모든 input(및 textareas 및 selects)바인딩하면 이전 브라우저에서 작동 하지 않으며 위에서 언급 한 모든 이벤트 처리 솔루션과 마찬가지로 실행 취소를 지원하지 않습니다. 사용자가 텍스트 상자를 변경 한 다음 취소하거나 확인란을 선택 및 선택 취소하면 양식이 여전히 더티로 간주됩니다.

특정 요소를 무시하는 등 더 많은 동작을 구현하려면 더 많은 작업을 수행해야합니다.

바퀴를 재발 명하지 마십시오 :

따라서 이러한 솔루션과 필요한 모든 해결 방법을 구현하기 전에 휠을 재발 명하고 다른 사람들이 이미 해결 한 문제가 발생하기 쉽다는 것을 알아야합니다.

응용 프로그램에서 이미 jQuery를 사용하는 경우 자체 롤링 대신 테스트되고 유지 관리되는 코드를 사용하고이 모든 부분에 대해 타사 라이브러리를 사용할 수 있습니다. jQuery는 확실합니까? 플러그인 은 훌륭하게 작동 합니다 . 데모 페이지를 참조하십시오 . 다음과 같이 간단합니다.

<script src="jquery.are-you-sure.js"></script>

<script>
  $(function() {
    $('#myForm').areYouSure(
      {
        message: 'It looks like you have been editing something. '
               + 'If you leave before saving, your changes will be lost.'
      }
    );
  });

</script>

모든 곳에서 지원되지 않는 맞춤 메시지

양해를 수행 파이어 폭스 4는 이 대화 상자에서 지원 사용자 정의 메시지하지 않았다. 2016 년 4 월 기준 으로 맞춤 메시지도 제거 되는 Chrome 51이 출시 되고 있습니다. .

이 사이트의 다른 곳에서 일부 대안이 존재하지만 이와 같은 대화가 충분히 명확하다고 생각합니다.

이 사이트를 떠나시겠습니까?

변경 사항이 저장되지 않을 수 있습니다.

Leave Stay


6
Chrome에서는 맞춤 문자열을 사용하는 것이 더 이상 작동하지 않습니다. chromestatus.com/feature/5349061406228480
AMANN

5
예, 그것은 저의 대답의 마지막 섹션에 설명되어 있습니다.
CodeCaster

2
@Chris는 Angular가 현재 문서에서 벗어나지 않고 페이지를 변경하기 위해 DOM을 조작하기 때문입니다.
CodeCaster

15
jQuery areYouSure는 2014 년 이후 포기되었습니다 ( Github의 57 가지 공개 문제 ), 내 경험의 버그로 가득 차 있습니다. 처음에는 작동하는 것처럼 보이지만 몇 가지 빠른 테스트 후에는 항상 작동하지 않는다는 것을 깨달았습니다. 전혀 권장하지 않음
Mark

4
@JacopoStanchi 불행히도 아무것도 찾지 못했습니다. 그리고 나는 꽤 많이 보았다는 것을 의미합니다. 그러나 이것은 1 월 10 일에 다시 시작되었으므로 누군가가 무언가를 썼을 수도 있지만 의심합니다. 최선의 방법은 직접 구현하는 것입니다. 너무 죄송합니다. (그러나 적어도 jQuery areYouSure를 사용했던 것처럼 놀랍지 않을 것입니다.) 게다가 누가 오픈 소스를 만들 수도 있고 구현이 다른 사람들과 공유 될 수도 있다는 것을 아는 사람은 누구입니까?
Mark

75

JavaScript onbeforeunload 이벤트를 확인하십시오 . Microsoft에서 도입 한 비표준 JavaScript이지만 대부분의 브라우저에서 작동하며 해당 설명서 에는 더 많은 정보와 예제가 있습니다.


3
나는 그것이 표준이되었다고 생각한다. >>이 이벤트는 Microsoft의 Internet Explorer 4에서 처음 소개되었으며 HTML5 사양으로 표준화되었습니다.
vee

34

jquery를 통해

$('#form').data('serialize',$('#form').serialize()); // On load save form current state

$(window).bind('beforeunload', function(e){
    if($('#form').serialize()!=$('#form').data('serialize'))return true;
    else e=null; // i.e; if form state change show warning box, else don't show it.
});

Google JQuery 양식 직렬화 기능을 사용하면 모든 양식 입력을 수집하여 배열에 저장합니다. 나는이 설명이 충분하다고 생각합니다 :)


6
window가 form이라는 이름의 객체를 생성하고 생성하기 때문에 #form을 form id로 사용하지 마십시오.)
mdikici

1
당신을 위해 작동하지 않는 경우 여기를 확인하십시오 stackoverflow.com/questions/7080269/...
Leniel Maccaferri

16

컨텐츠 편집 가능 요소를 포함하여 모든 입력 수정을 자동으로 감지하는 구성이 필요없는 범용 솔루션 :

"use strict";
(() => {
const modified_inputs = new Set;
const defaultValue = "defaultValue";
// store default values
addEventListener("beforeinput", (evt) => {
    const target = evt.target;
    if (!(defaultValue in target || defaultValue in target.dataset)) {
        target.dataset[defaultValue] = ("" + (target.value || target.textContent)).trim();
    }
});
// detect input modifications
addEventListener("input", (evt) => {
    const target = evt.target;
    let original;
    if (defaultValue in target) {
        original = target[defaultValue];
    } else {
        original = target.dataset[defaultValue];
    }
    if (original !== ("" + (target.value || target.textContent)).trim()) {
        if (!modified_inputs.has(target)) {
            modified_inputs.add(target);
        }
    } else if (modified_inputs.has(target)) {
        modified_inputs.delete(target);
    }
});
// clear modified inputs upon form submission
addEventListener("submit", () => {
    modified_inputs.clear();
    // to prevent the warning from happening, it is advisable
    // that you clear your form controls back to their default
    // state after submission
});
// warn before closing if any inputs are modified
addEventListener("beforeunload", (evt) => {
    if (modified_inputs.size) {
        const unsaved_changes_warning = "Changes you made may not be saved.";
        evt.returnValue = unsaved_changes_warning;
        return unsaved_changes_warning;
    }
});
})();

1
시원한 콩. 이 코드를 복사하여 테스트 페이지에 붙여넣고 변경 한 다음 새로 고침을 누르십시오. 저장하지 않은 변경 사항이 있음을 알리는 기본 브라우저 경고가 표시됩니다.
TheLegendaryCopyCoder 8

1
이것은 Chrome 71.0.3578.98 (공식 빌드) (64 비트)에서 작동했습니다.
JacobRossDev

2
이것은 실제로 잘 작동하지만 제출을 위해 양식과 함께 사용하는 경우 먼저 modify_inputs 세트를 지워야합니다. 그렇지 않으면 변경 확인 경보가 나타납니다. 제출할 때 호출하기 위해 양식에 이벤트 리스너를 추가하고 setunloads를 실행하여 언로드 이벤트 리스너가 실행될 때 modified_inputs가 지워지고 게시를 계속할 수 있도록했습니다.
stepquick

1
실제로 복사하여 붙여 넣습니다. 시간을 내 주셔서 감사합니다. Firfox 75.0에서 나를 위해
Connectify_user

1
이 스 니펫을 좋아하십시오
Rawburner

10

일련 번호를 사용 하는 Wasim A.의 훌륭한 아이디어 위에 구축되었습니다 . 문제는 양식을 제출할 때 경고가 표시되었다는 것입니다. 이것은 여기에서 수정되었습니다.

var isSubmitting = false

$(document).ready(function () {
    $('form').submit(function(){
        isSubmitting = true
    })

    $('form').data('initial-state', $('form').serialize());

    $(window).on('beforeunload', function() {
        if (!isSubmitting && $('form').serialize() != $('form').data('initial-state')){
            return 'You have unsaved changes which will not be saved.'
        }
    });
})

Chrome 및 IE 11에서 테스트되었습니다.


Wasim A와 Eerik Sven Puudist-감사합니다. 모든 버튼이 형식 제출 <form action = ""id = "marksform"method = "POST"> <td> <input type = "submit"name = "submit_button"id = "save"value = "Save"> </ td> <td> <input type = "submit"name = "submit_button"value = "Next"> </ td> 및 소수 더 모든 유형은 따라서 특정 클릭 $ ( '저장 #')로 .Submit (대체 제출할 대신 '형태'의 (함수 () {isSubmitting = TRUE}를 사용하여 '#marksform')를 클릭합니다.
얀타

7

이전 답변을 기반으로 스택 오버플로의 여러 곳에서 함께 모여서, 실제로 변경 사항을 제출하려는 경우를 처리하는 솔루션이 있습니다.

window.thisPage = window.thisPage || {};
window.thisPage.isDirty = false;

window.thisPage.closeEditorWarning = function (event) {
    if (window.thisPage.isDirty)
        return 'It looks like you have been editing something' +
               ' - if you leave before saving, then your changes will be lost.'
    else
        return undefined;
};

$("form").on('keyup', 'textarea', // You can use input[type=text] here as well.
             function () { 
                 window.thisPage.isDirty = true; 
             });

$("form").submit(function () {
    QC.thisPage.isDirty = false;
});
window.onbeforeunload = window.thisPage.closeEditorWarning;

IE11은 경고를 표시하지 않기 위해 closeEditorWarning함수가 반환 해야한다고 생각 undefined합니다.


이 솔루션은 값이 원래 상태에서 변경되었는지 확인하지 않으므로 사용자가 텍스트를 입력하고 이동하기 전에 입력 한 텍스트를 삭제하는 경우 무효화됩니다.
Brett Weber

좋은 지적, @BrettWeber. 이 경우 closeEditorWarning을 수정하고 "if (window.thisPage.isDirty && uiHasChanged ())"를 가질 수 있습니다. 여기서 uiHasChanged는 서버의 원래 상태를 알고 모든 차이점을 확인하는 함수이지만이 솔루션은 특히 여분의 작업을 모두하고 싶지 않은 경우, 텍스트 영역에서 실제 키를 누른 경우에만 잘못된 긍정을 가졌으며 합리적인 타협이라고 생각했습니다. :)
Jonathan

QC.thisPage.isDirty = false;window.thisPage.isDirty = false;? 그러면 양식을 제출하고 경고를 표시하지 않는지 확인합니다. 내 테스트에서 작동하는 것 같았습니다. 또한, 대부분의 형태는이 input보다는를 textarea. 나는 다음 중 어느 $("form").on('keyup', 'textarea,input,select', function () {
Mike

7

다음 한 줄짜리가 나를 위해 일했습니다.

window.onbeforeunload = s => modified ? "" : null;

그냥 설정 modified 또는 거짓이 응용 프로그램의 상태에 따라.


2
일부 제안 : 일부 브라우저는 빈 문자열 대신 사용자 정의 메시지를 반환하고 (예 : Edge) IE 가 false 인 경우 'null'을 인쇄하므로 undefined대신 반환하십시오 . nullmodified
Kevin Lee

1
휴대 기기는 어떻습니까? 내 이해는 IOS 장치가로드를 존중하지 않는다는 것입니다.
jaybro

4

다음 코드는 훌륭하게 작동합니다. id 속성을 통해 양식 요소의 입력 변경에 도달해야합니다.

var somethingChanged=false;
            $('#managerForm input').change(function() { 
                somethingChanged = true; 
           }); 
            $(window).bind('beforeunload', function(e){
                if(somethingChanged)
                    return "You made some changes and it's not saved?";
                else 
                    e=null; // i.e; if form state change show warning box, else don't show it.
            });
        });

3
var unsaved = false;
$(":input").change(function () {         
    unsaved = true;
});

function unloadPage() {         
    if (unsaved) {             
        alert("You have unsaved changes on this page. Do you want to leave this page and discard your changes or stay on this page?");
    }
} 
window.onbeforeunload = unloadPage;

별도의 파일에 삽입하고 <script src = "warnOnChange.js"> </ script>에 포함 시켰지만 텍스트 필드를 수정 한 다음 헤더 명령을 실행할 때 아무 반응이 없습니다.
Fabrizio Bartolomucci

2

serialize ()를 사용하여 양식 값을 직렬화하여 URL로 인코딩 된 텍스트 문자열을 만들고 언로드 전에 양식이 변경되었는지 확인할 수 있습니다.

$(document).ready(function(){
    var form = $('#some-form'),
        original = form.serialize()

    form.submit(function(){
        window.onbeforeunload = null
    })

    window.onbeforeunload = function(){
        if (form.serialize() != original)
            return 'Are you sure you want to leave?'
    }
})

이 링크를 참조하십시오 https://coderwall.com/p/gny70a/alert-when-leaving-page-with-unsaved-form 글쓴이 Vladimir Sidorenko


1
그것은 작동했지만 코드 캐스터의 대답에 따르면이 방법에는 몇 가지 결함이 있습니다. stackoverflow.com/a/7317311/10555981
Pradeep

를 사용하여 이미 몇 가지 답변이 serialize()있으며 실제로 단점이 있습니다.
CodeCaster

이것은 정답이어야하며, 사용하기 매우 간단하고 예상대로 작동합니다.
Jodyshop

1

@codecaster에 대한 아이디어를 추가하면 양식이있는 모든 페이지에 이것을 추가 할 수 있습니다 (제 경우에는 전역 방식으로 사용하므로 양식에서만 경고합니다).

if ( formSubmitting || document.getElementsByTagName('form').length == 0) 

또한 로그인 및 취소 버튼 링크를 포함한 양식 제출을 클릭하면 사람이 취소를 클릭하거나 양식을 제출할 때 양식을 가진 모든 페이지에서도 경고가 트리거되지 않습니다 ...

<a class="btn btn-danger btn-md" href="back/url" onclick="setFormSubmitting()">Cancel</a>

1

여기에서 자세한 설명을 확인할 수 있습니다 : http://techinvestigations.redexp.in/comparison-of-form-values-on-load-and-before-close/ 비교 -의 - 형태 - 값 - 온 -로드 및 -닫기 전에

주요 코드 :

function formCompare(defaultValues, valuesOnClose) {

    // Create arrays of property names
    var aPropsFormLoad = Object.keys(defaultValues);
    var aPropsFormClose = Object.keys(valuesOnClose);

    // If number of properties is different,
    // objects are not equivalent
    if (aPropsFormLoad.length != aPropsFormClose.length) {
        return false;
    }

    for (var i = 0; i < aPropsFormLoad.length; i++) {
        var propName = aPropsFormLoad[i];

        // If values of same property are not equal,
        // objects are not equivalent
        if (defaultValues[aPropsFormLoad]+"" !== valuesOnClose[aPropsFormLoad]+"") {
            return false;
        }
    }

    // If we made it this far, objects
    // are considered equivalent
    return true;

}

//add polyfill for older browsers, as explained on the link above

//use the block below on load
    for(i=0; i < document.forms[0].elements.length; i++){
    console.log("The field name is: " + document.forms[0].elements[i].name +
        " and it’s value is: " + document.forms[0].elements[i].value );
    aPropsFormLoad[i] = document.forms[0].elements[i].value;
    }

//create a similar array on window unload event.

//and call the utility function
    if (!formCompare(aPropsOnLoad, aPropsOnClose))
    {
    //perform action: 
    //ask user for confirmation or
    //display message about changes made
    }

1

짧은 답변:

let pageModified = true

window.addEventListener("beforeunload", 
  () => pageModified ? 'Close page without saving data?' : null
)

1

Eerik Sven Puudist의 솔루션 ...

var isSubmitting = false;

$(document).ready(function () {
    $('form').submit(function(){
        isSubmitting = true
    })

    $('form').data('initial-state', $('form').serialize());

    $(window).on('beforeunload', function() {
        if (!isSubmitting && $('form').serialize() != $('form').data('initial-state')){
            return 'You have unsaved changes which will not be saved.'
        }
    });
})

... 필요한 변경없이 복잡한 객체 지향 환경에서 저를 위해 저를 위해 일했습니다.

내가 적용한 유일한 변경 사항은 "formForm"( 'form'-> '#formForm')이라는 구체적인 양식 (파일 당 하나의 양식) 만 참조하는 것입니다.

<form ... id="formForm" name="formForm" ...>

제출 버튼이 "혼자"있다는 사실이 특히 잘 이루어집니다.

또한 최신 버전의 Firefox (2019 년 2 월 7 일 현재)에서도 작동합니다.


1

Eli Grey의 범용 솔루션을 테스트했으며 코드를 단순화 한 후에 만 ​​작동했습니다.

  'use strict';
  (() => {
    const modified_inputs = new Set();
    const defaultValue = 'defaultValue';
    // store default values
    addEventListener('beforeinput', evt => {
      const target = evt.target;
      if (!(defaultValue in target.dataset)) {
        target.dataset[defaultValue] = ('' + (target.value || target.textContent)).trim();
      }
    });

    // detect input modifications
    addEventListener('input', evt => {
      const target = evt.target;
      let original = target.dataset[defaultValue];

      let current = ('' + (target.value || target.textContent)).trim();

      if (original !== current) {
        if (!modified_inputs.has(target)) {
          modified_inputs.add(target);
        }
      } else if (modified_inputs.has(target)) {
        modified_inputs.delete(target);
      }
    });

    addEventListener(
      'saved',
      function(e) {
        modified_inputs.clear()
      },
      false
    );

    addEventListener('beforeunload', evt => {
      if (modified_inputs.size) {
        const unsaved_changes_warning = 'Changes you made may not be saved.';
        evt.returnValue = unsaved_changes_warning;
        return unsaved_changes_warning;
      }
    });

  })();

그의 수정은 사용을 삭제하고 사용 target[defaultValue]target.dataset[defaultValue] 하고 실제 기본값을 저장하는 합니다.

그리고 '저장된'이벤트 리스너를 추가하여 '저장된'이벤트가 사용자의 저장 조치 성공에 의해 트리거됩니다.

그러나이 '유니버설'솔루션은 브라우저에서만 작동하며 wechat 브라우저와 같은 앱의 웹뷰에서는 작동하지 않습니다.

wechat 브라우저에서 (부분적으로) 작동하도록 또 다른 개선 사항이 있습니다.

  'use strict';
  (() => {
    const modified_inputs = new Set();
    const defaultValue = 'defaultValue';
    // store default values
    addEventListener('beforeinput', evt => {
      const target = evt.target;
      if (!(defaultValue in target.dataset)) {
        target.dataset[defaultValue] = ('' + (target.value || target.textContent)).trim();
      }
    });

    // detect input modifications
    addEventListener('input', evt => {
      const target = evt.target;
      let original = target.dataset[defaultValue];

      let current = ('' + (target.value || target.textContent)).trim();

      if (original !== current) {
        if (!modified_inputs.has(target)) {
          modified_inputs.add(target);
        }
      } else if (modified_inputs.has(target)) {
        modified_inputs.delete(target);
      }

      if(modified_inputs.size){
        const event = new Event('needSave')
        window.dispatchEvent(event);
      }
    });

    addEventListener(
      'saved',
      function(e) {
        modified_inputs.clear()
      },
      false
    );

    addEventListener('beforeunload', evt => {
      if (modified_inputs.size) {
        const unsaved_changes_warning = 'Changes you made may not be saved.';
        evt.returnValue = unsaved_changes_warning;
        return unsaved_changes_warning;
      }
    });

    const ua = navigator.userAgent.toLowerCase();

    if(/MicroMessenger/i.test(ua)) {
      let pushed = false

      addEventListener('needSave', evt => {
        if(!pushed) {
          pushHistory();

          window.addEventListener("popstate", function(e) {
            if(modified_inputs.size) {
              var cfi = confirm('确定要离开当前页面嘛?' + JSON.stringify(e));
              if (cfi) {
                modified_inputs.clear()
                history.go(-1)
              }else{
                e.preventDefault();
                e.stopPropagation();
              }
            }
          }, false);
        }

        pushed = true
      });
    }

    function pushHistory() {
      var state = {
        title: document.title,
        url: "#flag"
      };
      window.history.pushState(state, document.title, "#flag");
    }
  })();

0

다른 사람이 도움을 받고 Chrome으로 만 테스트 할 수 있도록 여기에서 공유했습니다.

변경 사항이있는 경우에만 탭을 닫기 전에 사용자에게 경고하고 싶었습니다.

<input type="text" name="field" value="" class="onchange" />

var ischanged = false;

$('.onchange').change(function () {
    ischanged = true;
});

window.onbeforeunload = function (e) {
    if (ischanged) {
        return "Make sure to save all changes.";
    }        
};

내가 원치 않는 경고 메시지가 양식을 제출할 때 잘 작동하지만-다른 문제를 가지고, 내가 onsubmit 그게 전부 이전입니다 onbeforeunload 화재는 우리가 같은 onsubmit 이벤트를 처리 할 수없는 이유 때문입니다, 그것을 해결 방법을 많이보고 onbeforeunload = null있지만, 제출 버튼의 onclick 이벤트는이 두 이벤트 전에 발생하므로 코드를 업데이트했습니다.

var isChanged = false;
var isSubmit = false;

window.onbeforeunload = function (e) {
    if (isChanged && (!isSubmit)) {
        return "Make sure to save all changes.";
    }        
};

$('#submitbutton').click(function () {
    isSubmit = true;
});

$('.onchange').change(function () {
    isChanged = true;
});

-5

우선, 대부분의 브라우저에는 기본적으로이 기능이 있습니다. 그리고 왜 이것이 전혀 필요합니까? 양식을 동기화 상태로 유지하지 않는 이유는 무엇입니까? 즉, 사용자의 제출을 ​​기다리지 않고 변경 사항을 저장하십시오. Google 주소록처럼. 물론 양식의 모든 필드 만 필수 인 경우. 사용자는 필요할 때 생각하지 않고 무언가를 채우려 고 할 때 싫어합니다. :)


당신이 옳지 만 내 양식이 동적으로 생성되고 필드가 내 통제에 있지 않으므로 나를 위해 모든 필드를 추적하고 아약스를 통해 요청을 보낼 수는 없습니다.

네 목적에 필요하지는 않지만 여전히 구현할 수 있습니다. 양식 요소가 화면에있는 경우 고유 한 이벤트 핸들러를 첨부하고 원하는 데이터를 얻을 수 있습니다. 그런 다음 AJAX를 사용하여 원하는 곳에 데이터를 저장하십시오. 양식에 임의로 생성 된 ID 또는 클래스 이름이 있더라도 양식의 구조를 예상 할 수 있으면 XPath를 사용할 수 있습니다. XML / HTML이 맞습니까? 따라서 동적으로 생성 된 양식을 담당하는 직원과 JAD를 보유하고이 프로젝트에서 XSTL이 어떻게 이점을 얻을 수 있는지에 대해 이야기 할 수도 있습니다. 그냥 생각 ...
SimonDever

1
save it on any change without waiting any submitting from user항상 이렇게하고 싶지는 않습니다. 때때로 사용자는 많은 변경을 한 다음 저장하고 싶은지 검토하고 확인하려고합니다.
BadHorsie

1
양식 제출을 제안하지 않았습니다. 데이터는 localStorage, 일부 캐시에 저장되거나 초안 플래그와 함께 제출 될 수도 있습니다. 이 동작에는 여러 가지 방법이 있습니다. 양식을 작성하지 않았다는 사실을 사용자에게 알리는 것보다 훨씬 낫습니다. 창을 닫지 않고 닫을 경우 다음에 다시 작성해야합니다. "잠깐만, 게으르지 마라. 기차 / 버스 / 비행기 등은 중요하지 않다. 랩탑에서 충전기를 잊어 버린 것을 신경 쓰지 말고,이 빌어 먹을 양식을 채우십시오!"
YuS
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.