原生js修改react+Antd或者vue+Antd打包的表單文件

由于用了框架的原因,用原生js直接賦值是修改不了表單的师脂,或者你肉眼看上去你把表單修改了肛炮,但其實(shí)操作起來(lái)頁(yè)面會(huì)出現(xiàn)問(wèn)題,并且提交表單傳給后端的內(nèi)容其實(shí)并沒(méi)有修改跑揉。因?yàn)橹苯淤x值,vue是監(jiān)聽不到事件的,并不會(huì)修改表單內(nèi)容。react也是同理颠焦。這時(shí)候不能采用直接賦值的方式,而需要使用觸發(fā)事件的方式往枣。由于使用Vue框架不同或者UI框架不同,可能某種js寫法在vue上生效粉渠,但是在react上不生效分冈,只能靠自己去思考嘗試了。場(chǎng)景不一樣霸株,寫的方式也不一樣雕沉,代碼不全,只分享思路去件。本文只針對(duì)自己遇到的情況作以下分享坡椒。

1扰路、輸入框填值

var  event = document.createEvent('HTMLEvents');
 event.initEvent('input', true, false);
var inputId=document.getElementById('inputId');
inputId.setAttribute('value', '輸入框內(nèi)容');
inputId.dispatchEvent(event);
//也可以使用inputId.dispatchEvent(new Event('input',{bubble:true,"bubbles": true, "cancelable": false})),但是注意倔叼,IE瀏覽器不兼容new Event()

2汗唱、多行文本框填值

var  event = document.createEvent('HTMLEvents');
 event.initEvent('input', true, false);
var textareaId=document.getElementById('textareaId');
textareaId.innerHTML= '多行文本框內(nèi)容';
textareaId.dispatchEvent(event);
//也可以使用inputId.dispatchEvent(new Event('input',{bubble:true,"bubbles": true, "cancelable": false})),但是注意丈攒,IE瀏覽器不兼容new Event()

3哩罪、下拉框選中填值

        var parentSelect = document.getElementById('parentId');
        parentSelect.getElementsByClassName('ant-select-selection')[0].click();
        //UI渲染需要一定的時(shí)間,獲取動(dòng)態(tài)生成的頁(yè)面需要加一個(gè)宏任務(wù)
        setTimeout(function () {
            //通過(guò)觀察發(fā)現(xiàn)下拉選擇框的動(dòng)態(tài)生成下拉選項(xiàng)的某個(gè)父級(jí)元素中有個(gè)id屬性是和當(dāng)前這個(gè)下拉選擇框的類ant-select-selection的aria-controls屬性是一一對(duì)應(yīng)的巡验,一樣的际插,所以可以先得到動(dòng)態(tài)生成的下拉選項(xiàng)的id。
            var id = document.getElementById('parentId')
                .getElementsByClassName('ant-select-selection')[0]
                .getAttribute('aria-controls');
            //根據(jù)id獲取下拉選項(xiàng)
            var li_nodes = document.getElementById(id).getElementsByClassName('ant-select-dropdown-menu-item');
            //循環(huán)下拉選項(xiàng)显设,找到傳入的被選中的對(duì)應(yīng)的選項(xiàng)框弛,并觸發(fā)它的click事件
            for (var j = 0; j < li_nodes.length; j++) {
                var li_ele = li_nodes[j];
                var text = li_ele.innerText.replace(/(^\s*)|(\s*$)/g, "");
                if (text === "被選中的選項(xiàng)值") {
                    li_ele.click();
                    break;
                };
            };
        })

4、單選按鈕選中填值

var parentRadio = document.getElementById('parentRadioID');
var radioNodes = parentRadio.getElementsByClassName('ant-radio-wrapper');//獲取一組單選按鈕集合
var radioArr = [].slice.call(radioNodes, 0);//類數(shù)組轉(zhuǎn)換為數(shù)組
var index = radioArr.findIndex(function (val) {
      var text = val.innerText.replace(/(^\s*)|(\s*$)/g, '');
       return text === '被選中的選項(xiàng)內(nèi)容';
});
if (~index) {
    radioNodes[index].click();
}

5捕捂、日期選中填值

//antd日歷組件為3.X可以用如下方法瑟枫,因?yàn)?.X日歷組件選項(xiàng)有輸入框,4.X沒(méi)有绞蹦,無(wú)法觸發(fā)日歷選項(xiàng)框的input事件去填值力奋,觸發(fā)enter事件去隱藏日歷選項(xiàng)框,這點(diǎn)需要注意幽七。
var event = document.createEvent('HTMLEvents');
    event.initEvent('input', true, true);//創(chuàng)建一個(gè)input事件
    var eventEnter = document.createEvent('Event');
    eventEnter.initEvent('keydown', true, false);
    eventEnter = Object.assign(eventEnter, {
        ctrlKey: false,
        metaKey: false,
        altKey: false,
        which: 13,
        keyCode: 13,
        key: 'Enter',
        code: 'Enter'
    });//創(chuàng)建一個(gè)enter事件
document.getElemntById('dateId').click();//觸發(fā)日期控件input框的點(diǎn)擊事件景殷,為了吧日歷組件顯示出來(lái)
setTimeout(function () {
        var ss_input = document.getElementsByClassName('ant-calendar-input')[0];
        var len = ss_input.length;
        ss_input[0].setAttribute('value', '具體日期' || undefined);
        ss_input[0].dispatchEvent(event);
        setTimeout(function () {
            ss_input[0].dispatchEvent(eventEnter);//觸發(fā)enter事件,讓日歷框選項(xiàng)隱藏
        });
    });

5澡屡、級(jí)聯(lián)選中填值

上面我都只舉了單個(gè)填值的例子猿挚,這里寫的多個(gè)級(jí)聯(lián)選中框填值的例子,因?yàn)闃I(yè)務(wù)需要驶鹉,表單中可能會(huì)存在多個(gè)級(jí)聯(lián)填值绩蜻,但是這個(gè)和antd的下拉框通過(guò)對(duì)應(yīng)的id去獲取每個(gè)下拉框選項(xiàng)組件不一樣。這個(gè)沒(méi)有id唯一不同的可能就是絕對(duì)定位的高度不一樣室埋。所以我這里是按照順序傳入父級(jí)選項(xiàng)的input框和值办绝,根據(jù)絕對(duì)定位去從小到大排序獲取對(duì)應(yīng)的級(jí)聯(lián)選擇框。然后按照傳入的順序一一對(duì)應(yīng)上值姚淆。日歷的話也可以參考這種思路孕蝉,但是如果日歷的placeholder不一樣也可以根據(jù)placeholder的不同對(duì)應(yīng)上,只要能找到一個(gè)可以唯一對(duì)應(yīng)的標(biāo)識(shí)點(diǎn)即可腌逢。

//遞歸觸發(fā)級(jí)聯(lián)選擇框的點(diǎn)擊事件(因?yàn)槲易约簶I(yè)務(wù)是級(jí)聯(lián)設(shè)置了點(diǎn)擊降淮,如果是hover,就觸發(fā)hover事件)
function menuItemClick(dom, area, index) {
    index = index || 0;
    if (index > area.length || !area[index]) return;
    var parentNodes = dom.querySelectorAll('.ant-cascader-menu')[index];
    if (!parentNodes) return;
    var nodes = parentNodes.querySelectorAll('.ant-cascader-menu-item')
    for (var i = 0; i < nodes.length; i++) {
        var text = nodes[i].innerText.replace(/(^\s*)|(\s*$)/g, "");
        if (text === area[index]) {
            nodes[i].click()
            setTimeout(function () {
                menuItemClick(dom, area, ++index)
            })
        }
    }
};
function handleCascader(arr) {
    for (var i = 0; i < arr.length; i++) {
        var parentId = document.getElementById(arr[i].id)
        parentId.querySelectorAll('.ant-cascader-input')[0].click()//觸發(fā)父級(jí)級(jí)聯(lián)input框的的點(diǎn)擊事件搏讶,為了讓級(jí)聯(lián)選項(xiàng)框顯示到頁(yè)面上
    }
    setTimeout(function () {
        var parentContents = [].slice.call(document.querySelectorAll('.ant-cascader-menus'));//獲取級(jí)聯(lián)選項(xiàng)框的集合佳鳖,并轉(zhuǎn)換為數(shù)組
        //根據(jù)絕對(duì)定位的高度從大到小排序
        parentContents.sort(function (a, b) {
            return a.offsetTop - b.offsetTop;
        })
        //執(zhí)行每個(gè)級(jí)聯(lián)的選中對(duì)比填值
        for (var i = 0; i < parentContents.length; i++) {
            menuItemClick(parentContents[i], arr[i].value);
        }
    })
};

……省略
//方法調(diào)用霍殴,按從上到下的順序依次傳入
var cascaders=[
        {
            id: "PermanentAddrCode",
            value: ['安徽', '合肥']
        },
        {
            id: "PermanentAddrCode",
            value: ['天津', '和平區(qū)']
        }
    ];
handleCascader(cascaders);

6系吩、多選選中填值

       var parentSelect = document.getElementById('parentId');
       parentSelect.getElementsByClassName('ant-select-selection')[0].click();//觸發(fā)多選組件里面的input框的click事件来庭,為了在dom節(jié)點(diǎn)中獲取多選組件的下拉選項(xiàng)框
       var selectedValue = ['被選中的值1','被選中的值2','被選中的值3'] //需要被選中的值
        setTimeout(function () {
            var id = parentSelect.getElementsByClassName('ant-select-selection')[0]
                .getAttribute('aria-controls');//獲取多選組件下拉框選項(xiàng)的id
            var li_nodes = document.getElementById(id).getElementsByClassName('ant-select-dropdown-menu-item');//獲取下拉框選項(xiàng)節(jié)點(diǎn)集合
            for (var j = 0; j < li_nodes.length; j++) {
                var text = li_nodes[j].innerText.replace(/(^\s*)|(\s*$)/g, "");
                var index = selectedValue.indexOf(text);//獲取需要被選中的值在節(jié)點(diǎn)集合中的索引
                var isSelected = li_nodes[j].className.indexOf('ant-select-dropdown-menu-item-selected');//判斷當(dāng)前節(jié)點(diǎn)是否已經(jīng)被選中
                if ((~index && isSelected === -1) || (index === -1 && ~isSelected)) {//當(dāng)前值存在選項(xiàng)中并且未被選中,或者當(dāng)前值已被選中但是當(dāng)前選項(xiàng)中不存在
                    (
                        function (num) {
                            setTimeout(function () {
                                li_nodes[num].click();
                            });
                        }
                    )(j);//構(gòu)建閉包傳入j
                }
            };
        });

7淑玫、月份組件選中填值

var time="YYYY-MM"http://當(dāng)前被選中的時(shí)間巾腕,到月
var monthId= document.getElementById('monthId');
    var monthId_input = monthId.getElementsByTagName('input')[0];
    if (!time) {
        monthId_input .nextSibling.click();//如果傳入時(shí)間為空,觸發(fā)清空時(shí)間的那個(gè)小圖標(biāo)的click事件
        return;
    }
    monthId_input .click();//觸發(fā)月份組件的input框的click事件
    setTimeout(function () {
        var date = new Date(time);
        var oldYear = date.getFullYear();
        var oldMonth = date.getMonth();
        var year = document.getElementsByClassName('ant-calendar-month-panel-year-select-content')[0].innerText;
        var count = year - oldYear;
        var months = document.getElementsByClassName('ant-calendar-month-panel-cell');
        var dom = document.getElementsByClassName('ant-calendar-month-panel-' + (count > 0 ? 'prev' : 'next') + '-year-btn')[0];//根據(jù)count大小判斷當(dāng)前傳入時(shí)間是小于還是大于月份組件打開的年份(year)絮蒿,如果大于獲取倒退那個(gè)圖標(biāo)的節(jié)點(diǎn)尊搬,如果小于獲取前進(jìn)那個(gè)圖標(biāo)的節(jié)點(diǎn)
        for (var i = 0; i < count; i++) {
            setTimeout(function () {
                dom.click();//觸發(fā)千金難或者倒退圖標(biāo)的事件,選中傳入時(shí)間的年份
            })
        }
        setTimeout(function () {
            months[oldMonth].click();//選中傳入的時(shí)間的月份
        })
    })

8土涝、其他

有關(guān)event的了解可以看這篇dispatchEvent 學(xué)習(xí) - 簡(jiǎn)書 (jianshu.com)佛寿。目前就這樣,歡迎指正評(píng)論但壮、交流冀泻。
上面有時(shí)候因?yàn)闉g覽器原因,或者js框架原因等等蜡饵,可能會(huì)有input事件不觸發(fā)弹渔、填值填不上去(有時(shí)候可能是虛假填值,這個(gè)時(shí)候怎么辨別某個(gè)表單選項(xiàng)呢溯祸,可以先聚焦當(dāng)前選項(xiàng)肢专,然后再觸發(fā)該選項(xiàng)失焦事件、如果值還存在焦辅,表示值已經(jīng)填充上去博杖,否則值是沒(méi)填上去的)的情況,這個(gè)時(shí)候可以修改input的事件為冒泡事件筷登,填值如果通過(guò)document.getElementById('inputId').value='輸入框的值'方式填值不上的話剃根,就采用document.getElementById('inputId').setAttribute('value','輸入框的值'),在填值不上就采用下面的方式賦值:

function setNativeValue(element, value) {
            const { set: valueSetter } = Object.getOwnPropertyDescriptor(element, 'value') || {}
            const prototype = Object.getPrototypeOf(element)
            const { set: prototypeValueSetter } = Object.getOwnPropertyDescriptor(prototype, 'value') || {}
            if (prototypeValueSetter && valueSetter !== prototypeValueSetter) {
                prototypeValueSetter.call(element, value)
            } else if (valueSetter) {
                valueSetter.call(element, value)
            } else {
                throw new Error('The given element does not have a value setter')
            }
        }

注意:如果需要兼容IE瀏覽器,原生js盡力別使用es6語(yǔ)法前方,或者如果使用的話狈醉,一定要自己安裝babel相關(guān)依賴,配置下babel轉(zhuǎn)換規(guī)則,將腳本轉(zhuǎn)換一下惠险,如果要是使用了es7舔糖、es8相關(guān)語(yǔ)法,比如async await一定要引入polyfill,如果是腳手架安裝了莺匠,將js引入也不會(huì)報(bào)錯(cuò),否則在ie上使用會(huì)報(bào)錯(cuò)的十兢。vue安裝babel-polyfill,在mian.js引入import 'babel-polyfill';趣竣;react安裝react-app-polyfill,在main.js最上方引入import 'react-app-polyfill/ie11'; import 'react-app-polyfill/stable';

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末摇庙,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子遥缕,更是在濱河造成了極大的恐慌卫袒,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件单匣,死亡現(xiàn)場(chǎng)離奇詭異夕凝,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)户秤,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門码秉,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人鸡号,你說(shuō)我怎么就攤上這事转砖。” “怎么了鲸伴?”我有些...
    開封第一講書人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵府蔗,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我汞窗,道長(zhǎng)姓赤,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任仲吏,我火速辦了婚禮不铆,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蜘矢。我一直安慰自己狂男,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開白布品腹。 她就那樣靜靜地躺著岖食,像睡著了一般。 火紅的嫁衣襯著肌膚如雪舞吭。 梳的紋絲不亂的頭發(fā)上泡垃,一...
    開封第一講書人閱讀 49,031評(píng)論 1 285
  • 那天,我揣著相機(jī)與錄音羡鸥,去河邊找鬼蔑穴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛惧浴,可吹牛的內(nèi)容都是我干的存和。 我是一名探鬼主播,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼捐腿!你這毒婦竟也來(lái)了纵朋?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤茄袖,失蹤者是張志新(化名)和其女友劉穎操软,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體宪祥,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡聂薪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蝗羊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片藏澳。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肘交,靈堂內(nèi)的尸體忽然破棺而出笆载,到底是詐尸還是另有隱情,我是刑警寧澤涯呻,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布凉驻,位于F島的核電站,受9級(jí)特大地震影響复罐,放射性物質(zhì)發(fā)生泄漏涝登。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一效诅、第九天 我趴在偏房一處隱蔽的房頂上張望胀滚。 院中可真熱鬧,春花似錦乱投、人聲如沸咽笼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)剑刑。三九已至,卻和暖如春双肤,著一層夾襖步出監(jiān)牢的瞬間施掏,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工茅糜, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留七芭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓蔑赘,卻偏偏與公主長(zhǎng)得像狸驳,于是被迫代替她去往敵國(guó)和親预明。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容