読者です 読者をやめる 読者になる 読者になる

みかづきブログ その3

3ヶ月つづけてみました。

iPhoneでフォームが入力中のときにページを遷移しようとした際にアラートを出す

iOS JavaScript

kimizuka.hatenablog.com

遷移しようとした際にconfirmを出すことは簡単なのですが、キャンセルを押した際、どのような処理が適切なのかが思いつきませんでした。
本当は遷移をキャンセルしたかったのですが、それはできず。
次点として一旦遷移後にlocation.hrefを書き換えて戻ってこようとしたのですが、それもできず。
結果として同じ内容が入力されたページを別ウィンドウで開いてみました。


HTML

<form id="form">
    <input id="input" name="mail" type="text" placeholder="Email" />
</form>

JavaScript

(function(win, doc) {

    "use strict";
    
    var form  = doc.getElementById("form"),
        input = doc.getElementById("input"),
        isOverWriting = false,
        TXT = "フォーム入力中ですけど本当にいいんですね?",
        obj = _convertQueryToObject();
    
    if (typeof obj.mail === "string") {
        input.value = obj.mail;
    }
    
    win.addEventListener("pagehide",     _handlePageHide,     false);
    
    form.addEventListener("submit", _handleSubmit, false);
    
    input.addEventListener("focus", _handleFocus, false);
    input.addEventListener("blur",  _handleBlur,  false);
    
    function _handlePageHide() {
        if (isOverWriting) {
            if (win.confirm(TXT)) {
                return;
            } else {
//                evt.preventDefault(); // => 失敗
//                location.href = location.href; // => 失敗
//                setTimeout(function() {
//                    location.href = location.href; // => 失敗
//                }, 0);
                win.open(location.href = location.protocol + "//" + location.hostname + location.pathname + "?" + $("#form").serialize());
            }
        }
    }
    
    function _handleSubmit() {
        isOverWriting = false;
    }
    
    function _handleFocus() {
        isOverWriting = true;
    }
    
    function _handleBlur() {
        if (!this.value.length) {
            isOverWriting = false;
        }
    }
    
    function _convertQueryToObject() {
        var obj    = {},
            query  = location.search,
            params = query.split(/[?&]/),
            p, key, val;

        for (var i = 0, len = params.length; i < len; ++i) {
            p   = params[i].split("=");
            key = _normalize(p[0]);
            val = _normalize(p[1]);

            if (key) {
                obj[key] = val;
            }
        }

        return obj;
        
        function _fixedDecodeURIComponent(str) {
            return decodeURIComponent(str.replace(/[!'()*]/g, unescape));
        }
    
        function _normalize(arg) {
            return (!arg) ? null : _fixedDecodeURIComponent(arg);
        }
    }
    
})(this, document);

DEMO

f:id:kimizuka:20150929130253g:plain

※ iPhoneでご確認ください。(iPhone6 iOS9.0.1で確認)


挙動的にはとてもわかりにくいですが、フォームの内容を保存するという目的だけは達成できました。