Не дозволяйте веб-сторінці переходити за допомогою JavaScript


129

Як запобігти навігації веб-сторінки за допомогою JavaScript?


Що змушує цю сторінку переміщатися?
Ніяз

9
Відповідно до запитання, JavaScript змушує його рухатися далеко ...
Shog9


@ Shog9 це може закрити вкладку, щоб змусити її рухатися. Мій вказівний палець зробив тха ...
Боб Штейн

Відповіді:


159

Використання onunloadдозволяє відображати повідомлення, але не перериватиме навігацію (бо це занадто пізно). Однак використання onbeforeunloadперерве навігацію:

window.onbeforeunload = function() {
  return "";
}

Примітка. Порожня рядок повертається, оскільки нові веб-переглядачі надають повідомлення типу "Будь-які незбережені зміни будуть втрачені", які неможливо змінити.

У старих браузерах ви можете вказати повідомлення, яке відображатиметься у запиті:

window.onbeforeunload = function() {
  return "Are you sure you want to navigate away?";
}

11
У браузері відобразиться відповідне підказку. Просто використовуйтеwindow.onbeforeunload = function() { return ""; }
KIM Taegyoon

Але цього недостатньо. Що з контролями всередині форми? Вони також викликають це.
Fandango68

1
Сучасні веб-переглядачі не дозволяють відображати користувальницьке повідомлення у запиті, оскільки це зловживають фішерів тощо.
Flimm

Дякую @Flimm, я оновив відповідь, і тепер вона є точною для поточних браузерів.
Джиммі Р. Хоуц

@FlimmЯ хочу оновити статус користувача в Інтернеті, коли користувачі Інтернету закривають вкладку браузера або браузер. Я використовував код у рішенні, але він не працював. Чи є для цього рішення?
Насімба

23

На відміну від інших методів, представлених тут, цей біт коду не призведе до того, що браузер відображатиме попередження, запитуючи користувача, чи хоче він вийти; натомість він використовує врівноважений характер DOM для перенаправлення назад на поточну сторінку (і тим самим скасування навігації), перш ніж у браузера з’явиться шанс вивантажити її з пам'яті.

Оскільки він працює безпосередньо за допомогою короткого замикання на навігацію, його не можна використовувати для запобігання закриття сторінки; однак він може бути використаний для відключення перебору кадрів.

(function () {
    var location = window.document.location;

    var preventNavigation = function () {
        var originalHashValue = location.hash;

        window.setTimeout(function () {
            location.hash = 'preventNavigation' + ~~ (9999 * Math.random());
            location.hash = originalHashValue;
        }, 0);
    };

    window.addEventListener('beforeunload', preventNavigation, false);
    window.addEventListener('unload', preventNavigation, false);
})();

Відмова: Ти ніколи цього не повинен робити. Якщо на сторінці є код перебору кадрів, будь ласка, поважайте побажання автора.


як показати модальний, якщо користувач хоче закрити браузер (натисніть на закрити)? це насправді?

15

Я закінчив цю трохи іншу версію:

var dirty = false;
window.onbeforeunload = function() {
    return dirty ? "If you leave this page you will lose your unsaved changes." : null;
}

В іншому випадку я встановив брудний прапор істинним, коли форма забруднилася (або я інакше хочу запобігти навігації). Це дозволяє мені легко контролювати, отримує чи не користувач підказка «Підтвердити навігацію».

З текстом у вибраній відповіді ви бачите зайві підказки:

введіть тут опис зображення


3
У IE, якщо брудна помилка, відобразиться рядок "null". Просто загорніть його всередину у виписку if. Дивіться: stackoverflow.com/questions/11793996/…
Якоб ван Лінген

Погодився @JacobvanLingen, це була б найкраща відповідь тут і на три інші питання, якби це закінчилося undefinedзамість нуля. (1) це умовно (2) він згадує "брудний" найпоширеніший законний привід перешкоджати навігації і (3) у нього скріншот.
Боб Штейн

Чи буде це працювати у всіх браузерах, якби він закінчувався невизначеним, а не нульовим?
Небезпека

9

Еквівалент більш сучасним і сумісним для браузера способом, використовуючи сучасні API addEventListener.

window.addEventListener('beforeunload', (event) => {
  // Cancel the event as stated by the standard.
  event.preventDefault();
  // Chrome requires returnValue to be set.
  event.returnValue = '';
});

Джерело: https://developer.mozilla.org/en-US/docs/Web/Events/beforeunload


1
Не забудьте правильно використати великі літериevent.returnValue
Flimm

7

У прикладі Аймана, повертаючи помилку, ви не дозволяєте закрити вікно / вкладку браузера.

window.onunload = function () {
  alert('You are trying to leave.');
  return false;
}

2
Якщо браузер не є Opera, який пропускає подію при завантаженні, якщо вкладка / вікно / програма закрита.
Powerlord

5

Еквівалент прийнятої відповіді в jQuery 1.11:

$(window).on("beforeunload", function () {
    return "Please don't leave me!";
});

Приклад JSFiddle

Відповідь altCognito використовувала unloadподію, яка занадто пізно трапляється, щоб JavaScript перервав навігацію.


3

Використання OnUnload .

Для jQuery я думаю, що це працює так:

$(window).unload(function() { 
  alert("Unloading"); 
  return falseIfYouWantToButBeCareful();
});

Повернення помилки не скасує завантаження, на жаль - unloadподія стартує, коли користувач залишає сторінку, на відміну від того, beforeunloadщо спрацьовує заздалегідь (і може бути скасовано)
Jimbo

@altCognito: Ти дав мені гарну ідею з falseIfYouWantToButBeCareful () Тепер я можу уникнути спливаючих параметрів за замовчуванням, наданих IE або FF. Але для хромування це не працює. Дивлячись у це.
user367134

3

Пропоноване повідомлення про помилку може дублювати повідомлення про помилку, яке браузер уже відображає. У хромі 2 подібних повідомлення про помилки відображаються одне за одним у тому ж вікні.

У хромі, текст, який відображається після користувацького повідомлення: "Ви впевнені, що хочете залишити цю сторінку?". У Firefox він взагалі не відображає власне повідомлення про помилку (але все одно відображає діалогове вікно).

Більш відповідним повідомленням про помилку може бути:

window.onbeforeunload = function() {
    return "If you leave this page, you will lose any unsaved changes.";
}

Або стиль stackoverflow: "Ви почали писати чи редагувати публікацію."


2

Якщо ви переймаєте кнопку назад / вперед браузера і не хочете переміщатися, ви можете скористатися:

window.addEventListener('popstate', function() {
    if (window.location.origin !== 'http://example.com') {
        // Do something if not your domain
    } else if (window.location.href === 'http://example.com/sign-in/step-1') {
        window.history.go(2); // Skip the already-signed-in pages if the forward button was clicked
    } else if (window.location.href === 'http://example.com/sign-in/step-2') {
        window.history.go(-2); // Skip the already-signed-in pages if the back button was clicked
    } else {
        // Let it do its thing
    }
});

В іншому випадку, ви можете використовувати beforeunload подія, але повідомлення може або не може працювати крос-браузер, і вимагає повернення то , що сили , вбудований в рядку.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.