Js實現監聽數據,單向雙向綁定

你可能需要項目地址https://github.com/licunzhi/dream_on_sakura_rain/blob/master/html_bind_event/src/main/resources/index/jianting.html

扣下來項目之後,只要有正確的jquery的地址就OK了希望你玩的開心(如果玩的動的話)

單項數據綁定

原理

監聽各種選擇框的動態事件一旦發生數據改變直接進行數據的存儲,基本的輸入類型也就這幾種了(樣式不太會寫 大家湊合看)
在這裏插入圖片描述

因此我在外面定義了一個對象,爲了防止出現很多的監聽的對象類型,因此這裏面的判斷的tag和修改的對象都在方法中作爲參數傳進來。
我要是用嘴說估計就是扯淡,核心的代碼展示一下再說吧

單向數據綁定

/**
     * @desc 數據的單向綁定,拜託以前的手動採集
     *
     * @param tag 自定義tag,避免tag衝突
     * @param outObject 動態輸出對象,需要定義全局對象
     * @param defaultValue 默認監聽的對象無數據的時候默認值,不傳輸默認null
     */
    function bindWatchEvent(tag, outObject, defaultValue) {
        outObject = outObject || {};
        //單選   radio
        $(`[${tag}]`).each(function () {
            if ($.inArray($(this)[0].tagName.toLocaleLowerCase(), ['input', 'textarea']) >= 0 &&
                $.inArray($(this)[0].type.toLocaleLowerCase(), ['text', 'textarea']) >= 0) {
                $(this).bind('input propertychange', 'textarea', function () {
                    if ($(this).val()) {
                        outObject[$(this).attr(tag)] = $(this).val();
                    } else {
                        outObject[$(this).attr(tag)] = defaultValue || null;
                    }
                });
            } else if ($(this)[0].tagName.toLocaleLowerCase() === 'select') {
                $(this).bind('select change', function () {
                    if ($(this).val()) {
                        outObject[$(this).attr(tag)] = {
                            k: $(this).children('option:selected').val(),
                            v: $(this).children('option:selected').text()
                        };
                    } else {
                        outObject[$(this).attr(tag)] = defaultValue || null;
                    }
                });
            } else if ($(this)[0].tagName.toLocaleLowerCase() === 'input' && $(this)[0].type.toLocaleLowerCase() === 'checkbox') {
                $(this).on('click', function () {
                    var tagValue = $(this).attr(tag);
                    outObject[tagValue] = [];
                    $('[' + tag + '=' + $(this)[0].getAttribute(tag) + ']').each(function () {
                        if ($(this)[0].checked) {
                            outObject[tagValue].push({
                                k: $(this)[0].getAttribute('k'),
                                v: $(this)[0].getAttribute('v')
                            });
                        }
                    });
                });
            } else if ($(this)[0].tagName.toLocaleLowerCase() === 'input' && $(this)[0].type.toLocaleLowerCase() === 'radio') {
                $(this).on('click', function () {
                    if ($(this)[0].checked) {
                        outObject[$(this).attr(tag)] = {
                            k: $(this)[0].getAttribute('k'),
                            v: $(this)[0].getAttribute('v')
                        };
                    }
                });
            }
        });
    }

雙向後臺數據同步

/**
     * @desc 數據的雙向綁定
     *
     * @param tag 自定義tag,避免tag衝突
     * @param inObject 動態輸出對象,需要定義全局對象
     */
    function bindEachEvent(tag, inObject, outObject) {
        var nameArr = [];
        $(`[${tag}]`).each(function () {
            if ($.inArray($(this).attr(tag), nameArr) >= 0) {
                return;
            }
            nameArr.push($(this).attr(tag));
            var tagValue = $(this).attr(tag);
            Object.defineProperty(inObject, tagValue, {
                get: function () {
                    return name;
                },
                set: function (value) {
                    console.log(tagValue, "--------", value);
                    $('[' + tag + '="' + tagValue + '"' + ']').each(function () {
                        if ($.inArray($(this)[0].tagName.toLocaleLowerCase(), ['input', 'textarea']) >= 0 &&
                            $.inArray($(this)[0].type.toLocaleLowerCase(), ['text', 'textarea']) >= 0) {
                            $(this).val(inObject[tagValue]);
                            outObject[tagValue] = $(this).val();
                        } else if ($(this)[0].tagName.toLocaleLowerCase() === 'select') {
                            $(this).find(`[value=${value.k}]`).prop('selected', true);
                            outObject[tagValue] = value;
                        } else if ($(this)[0].tagName.toLocaleLowerCase() === 'input' && $(this)[0].type.toLocaleLowerCase() === 'checkbox') {
                            for (var i = 0; i < value.length; i++) {
                                $(`[${tag}=${tagValue}][k=${value[i].k}]`).prop('checked', true);
                            }
                            outObject[tagValue] = value;
                        } else if ($(this)[0].tagName.toLocaleLowerCase() === 'input' && $(this)[0].type.toLocaleLowerCase() === 'radio') {
                            $(`[${tag}=${tagValue}][k=${value.k}]`).prop('checked', true);
                            outObject[tagValue] = value;
                        }
                    });
                }
            });
        });
    }

整個頁面的代碼

<!DOCTYPE html>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
    <meta http-equiv="X-UA-Compatible" content="IE=Edge">
    <title>監聽事件,自定義監聽</title>
    <!--引入jQuery-->
    <script src="../../js/jquery/jquery.min.js" type="text/javascript" charset="utf-8"></script>
</head>
<body>
<!--假裝寫個樣式-->
<div style="width: 20%; text-align: center; float: left">
    <input type="text" lczer="name">
    <hr>
    <textarea type="text" lczer="desc"></textarea>
    <hr>
    <select name="city" lczer="city">
        <option value="">請選擇</option>
        <option value="1">北京</option>
        <option value="2">上海</option>
        <option value="3">南京</option>
    </select>
    <hr>
    <input type="checkbox" name="hobby" lczer="hobby" k="1" v="籃球">籃球
    <input type="checkbox" name="hobby" lczer="hobby" k="2" v="乒乓球">乒乓球
    <hr>
    <input type="radio" name="drink" lczer="drink" k="1" v="啤酒">啤酒
    <input type="radio" name="drink" lczer="drink" k="2" v="牛奶">牛奶
    <hr>
    <button onclick="see()">我想看看結果</button>
    <hr>
    <button onclick="city()">city屬性被修改</button>
    <hr>
    <button onclick="hobby()">愛好屬性被修改</button>
    <hr>
    <button onclick="drink()">喝的屬性被修改</button>

</div>
<pre>
    <div style="width: 50%; height: 600px; border: 1px black solid; float: left" id="resultInfo">

    </div>
</pre>
</body>
<script type="text/javascript">


    /**
     * @desc 數據的單向綁定,拜託以前的手動採集
     *
     * @param tag 自定義tag,避免tag衝突
     * @param outObject 動態輸出對象,需要定義全局對象
     * @param defaultValue 默認監聽的對象無數據的時候默認值,不傳輸默認null
     */
    function bindWatchEvent(tag, outObject, defaultValue) {
        outObject = outObject || {};
        //單選   radio
        $(`[${tag}]`).each(function () {
            if ($.inArray($(this)[0].tagName.toLocaleLowerCase(), ['input', 'textarea']) >= 0 &&
                $.inArray($(this)[0].type.toLocaleLowerCase(), ['text', 'textarea']) >= 0) {
                $(this).bind('input propertychange', 'textarea', function () {
                    if ($(this).val()) {
                        outObject[$(this).attr(tag)] = $(this).val();
                    } else {
                        outObject[$(this).attr(tag)] = defaultValue || null;
                    }
                });
            } else if ($(this)[0].tagName.toLocaleLowerCase() === 'select') {
                $(this).bind('select change', function () {
                    if ($(this).val()) {
                        outObject[$(this).attr(tag)] = {
                            k: $(this).children('option:selected').val(),
                            v: $(this).children('option:selected').text()
                        };
                    } else {
                        outObject[$(this).attr(tag)] = defaultValue || null;
                    }
                });
            } else if ($(this)[0].tagName.toLocaleLowerCase() === 'input' && $(this)[0].type.toLocaleLowerCase() === 'checkbox') {
                $(this).on('click', function () {
                    var tagValue = $(this).attr(tag);
                    outObject[tagValue] = [];
                    $('[' + tag + '=' + $(this)[0].getAttribute(tag) + ']').each(function () {
                        if ($(this)[0].checked) {
                            outObject[tagValue].push({
                                k: $(this)[0].getAttribute('k'),
                                v: $(this)[0].getAttribute('v')
                            });
                        }
                    });
                });
            } else if ($(this)[0].tagName.toLocaleLowerCase() === 'input' && $(this)[0].type.toLocaleLowerCase() === 'radio') {
                $(this).on('click', function () {
                    if ($(this)[0].checked) {
                        outObject[$(this).attr(tag)] = {
                            k: $(this)[0].getAttribute('k'),
                            v: $(this)[0].getAttribute('v')
                        };
                    }
                });
            }
        });
    }

    /**
     * @desc 數據的雙向綁定
     *
     * @param tag 自定義tag,避免tag衝突
     * @param inObject 動態輸出對象,需要定義全局對象
     */
    function bindEachEvent(tag, inObject, outObject) {
        var nameArr = [];
        $(`[${tag}]`).each(function () {
            if ($.inArray($(this).attr(tag), nameArr) >= 0) {
                return;
            }
            nameArr.push($(this).attr(tag));
            var tagValue = $(this).attr(tag);
            Object.defineProperty(inObject, tagValue, {
                get: function () {
                    return name;
                },
                set: function (value) {
                    console.log(tagValue, "--------", value);
                    $('[' + tag + '="' + tagValue + '"' + ']').each(function () {
                        if ($.inArray($(this)[0].tagName.toLocaleLowerCase(), ['input', 'textarea']) >= 0 &&
                            $.inArray($(this)[0].type.toLocaleLowerCase(), ['text', 'textarea']) >= 0) {
                            $(this).val(inObject[tagValue]);
                            outObject[tagValue] = $(this).val();
                        } else if ($(this)[0].tagName.toLocaleLowerCase() === 'select') {
                            $(this).find(`[value=${value.k}]`).prop('selected', true);
                            outObject[tagValue] = value;
                        } else if ($(this)[0].tagName.toLocaleLowerCase() === 'input' && $(this)[0].type.toLocaleLowerCase() === 'checkbox') {
                            for (var i = 0; i < value.length; i++) {
                                $(`[${tag}=${tagValue}][k=${value[i].k}]`).prop('checked', true);
                            }
                            outObject[tagValue] = value;
                        } else if ($(this)[0].tagName.toLocaleLowerCase() === 'input' && $(this)[0].type.toLocaleLowerCase() === 'radio') {
                            $(`[${tag}=${tagValue}][k=${value.k}]`).prop('checked', true);
                            outObject[tagValue] = value;
                        }
                    });
                }
            });
        });
    }


    var outObject = {};
    var inObject = {};
    $(function () {
        bindWatchEvent('lczer', outObject);

        bindEachEvent('lczer', inObject, outObject);
        
    });

    function see() {
        $('#resultInfo').text(JSON.stringify(outObject, null, 4));
    }
    
    function city() {
        inObject.city = {
            k: 2,
            v: '上海'
        };
    }
    
    function hobby() {
        inObject.hobby = [
            {
                k: "1",
                v: "籃球"
            },
            {
                k: "2",
                v: "乒乓球"
            }
        ]
    }
    
    function drink() {
        inObject.drink = {
                k: "1",
                v: "啤酒"
            }
    }
</script>
</html>

敗筆

早就有很多人都實現這個寫法了,這個思想也是在很多現在的前端框架中。心太大想學這個又想學那個,心裏還想發財夢。

這種綁定時間然而也只是在最基本的html結構中使用而已,除了讓自己的代碼變得更騷,也是沒誰了。

現在的很多前端UI框架,都是內部自帶了很多render的方式,因此這個的意義 哎 也就是自己玩玩吧

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章