Event proxy for onchange events

Source: Internet
Author: User

Event proxy for onchange events is the most complex. In ff and the latest versions of opera, it can bubble to the top-level Object window. For other standard browsers, because its event listener has three parameters, we set the last one to true, and the implementation of the capture is a hundred times; but it is troublesome for IE, neither bubbling nor capturing, the only option is to use event simulation. In other words, use other events instead of onchange. Jquery uses four kinds of events to simulate it. Through in-depth research on it, it gives up its design and develops its own solution.

There are two key points:

  • Status changes of listening elements (groups)
  • Which event is used to act as a pseudo onchange event.

Solve the first problem first. The elements that can use the onchange event include the following (HTML5 new elements are not considered for the moment)

<Form ID = "AAA"> <select name = "Sweets" multiple = "multiple" id = "BBB"> <option> chocolate </option> <option selected = "selected "> candy </option> <option> taffy </option> <option selected =" selected "> caramel </option> <option> fudge </option> <option> cookie </option> </SELECT> <br> <input type = "file"/> <br/> <input type = "radio" name = "R"> <input type = "radio" name = "R"> <input type = "radio" name = "R"> <br> <input type = "checkbox" name = "DDD"> <input type = "checkbox" name = "DDD"> <br> <input value = "text field" id = "eee"> <br> <textarea> region </textarea> </form>

To listen to their status, first know what it looks like, and then what it looks like at this point in time. In this way, you can compare the values, checked, and selected of the elements. But jquery makes a mistake. Some elements make sense only when they are a set of values, such as the drop-down box (this jquery is correct) and checkbox and radio. See the following experiment.

<Form action = ""> <fieldset> <legend> Experiment 1 </legend> <input type = "radio" name = "R" onclick = "alert (this. checked) "> <input type =" radio "name =" R "onclick =" alert (this. checked) "> <input type =" radio "name =" R "onclick =" alert (this. checked) "> <br> <input type =" checkbox "name =" DDD "onclick =" alert (this. checked) "> <input type =" checkbox "name =" DDD "onclick =" alert (this. checked) "> <br> </fieldset> </form>

We found that radio is very unique. Why is it true? Isn't it possible to tell whether it has changed ?! Let's make another decision.

<Form action = ""> <fieldset> <legend> Experiment 2 </legend> <input type = "radio" name = "GGGG" onclick = "getval (this) "> <input type =" radio "name =" GGGG "onclick =" getval (this) "> <input type =" radio "name =" GGGG "onclick =" getval (this) "> <br> <input type =" checkbox "name =" ddd2 "onclick =" getval (this) "> <input type =" checkbox "name =" ddd2 "onclick =" getval (this) "> <br> </fieldset> </form> <SCRIPT type =" text/JavaScript "> var get Val = function (EL) {var els = El. Name? El. ownerdocument. getelementsbyname (El. name): [El]; for (VAR I = 0, rI = 0, Re = [], El; El = els [I ++];) {re [ri ++] = el. checked} alert (Re. join ("-")} </SCRIPT>

For the drop-down box of the select-multiple type, we also use this value method. Other values can be directly obtained. The following is my getval function:

VaR getval = function (EL) {var type = el. type, val = el. value, prop, array; If (type = "select-multiple") {array = el. options, prop = "selected";} else if (type = "radio" | type = "checkbox") {array = el. name? El. ownerdocument. getelementsbyname (El. name): [El];} else if (type = "select-one") {val = ELEM. selectedindex;} If (array) {// if it is not a select element, change prop to checked prop | (prop = "checked "); // prop is "selected" or "checked" for (VAR I = 0, rI = 0, Re = [], ELEM; ELEM = array [I ++];) {re [ri ++] = ELEM [prop];} val = Re. join ("-");} return val ;}

But when will it be called. We must get a value before using the pseudo onchange event and save it. When using the onchange event, we will retrieve it again to check whether the event has changed. If the event changes, we will execute the callback function, then save the new value. Because the onchange events of different elements are also different, we adopt the following method.

El. attachevent ("onbeforeactivate", function () {var El = Window. event. srcelement, type = el. type; If (/select /. test (type) {// The data correction in the drop-down box will only be executed once in the onbeforeactive event if (El ["_ change_data"] === undefined) el ["_ change_data"] = getval (EL )} else {// other form elements always use it for data correction El ["_ change_data"] = getval (EL )}});

Data correction is a self-made word. It places the state field indicating the form element to a custom attribute of the element. Every time we click the form element, we extract it, compare with the latest value. Undoubtedly, to trigger the onchange event, clicking or inputting operations are required. The onchange event in the text field and region is triggered when the focus is lost, while the checkbox is very real-time in a single region like a drop-down box and a single region. It is triggered when you click it, but the data correction in the drop-down box is very troublesome. Like other form elements, there must be a situation where the focus is lost, but the drop-down box is a set of elements, which are composed of select tags and option tags (optgroup may also exist ), we use E. the event source object obtained by screlement is always the select tag. When you click between options, we cannot trigger events that lose focus. Note that because blur does not bubble up, we use the focusout event unique to IE here. Therefore, for form elements such as text fields, upload areas, and upload fields, we use click events for simulation and data correction in the onbeforeactive event.

        el.attachEvent("onfocusout" , function(){             testChange(focusoutChangeOne)       });

The testchange function is very different from jquery. Jquery also uses event Dispatch here. In my implementation, we directly use event processing functions to execute all callback functions cyclically.

      var rselect = /select/,     focusoutChangeOne = dom.oneObject(["text","password","textarea","file"]),     clickChangeOne = dom.oneObject(["radio","checkbox","select-multiple","select-one"]),     testChange = function (oneObject) {                var e = dom.event.fix(window.event),                el = e.target, type = el.type;                e.live = true;                if(oneObject[type] && !el.readOnly){                    var data = dom.store( el, "_change_data" ),val = getVal(el);                    if (data === undefined || val === data ) {                        return;                    }                    if ( data != null || val ) {                        if(rselect.test(type))                            dom.store(el,"_change_data",val)                        return dom.event.handle.call(el,e)                    }                }            }

The following is my Event System, the classic de architecture ......

 dom.event = {  add:function(){},  remove:function(){},  handle:function(){},  fix:function(){},  fire:function(){},  analog:{}}

Because the cache system is involved, it cannot be demonstrated. However, in the testchange function, it is also responsible for correcting the data in the drop-down box. Speaking of onfocusout, there is a classic bug in IE, that is, the onchange event of the single-choice button is triggered by the loss of the Focus event, rather than the click event.

<Br/> <! Doctype HTML> <br/> <HTML lang = "ZH-ch"> </P> <p> <pead> <br/> <meta charset = "UTF-8"/> <br/> <meta content = "Ie = 8" http-equiv = "X-UA-compatible"/> <br/> <title> ie onchange bug by situ zhengmei </title> </P> <p> </pead> <br/> <body> </P> <p> <Form ID = "AAA"> <br/> <p> Use onchange event </p> <br/> <input type = "radio" name = "options" id = "option1" onchange = "alert ('option1 ') "/> <br/> <input type =" radio "name =" options "id =" option2 "onchange =" alert ('option2 ') "/> <br/> <p> onclick event </p> <br/> <input type =" radio "name =" options "id =" option1 "onclick = "alert ('option1 ') "/> <br/> <input type =" radio "name =" options "id =" option2 "onclick =" alert ('option2 ') "/> </P> <p> </form> <br/> </body> <br/> </ptml> <br/>

Run code

The Event System of jquery and I use onclick to simulate it. A single-choice button in a form element, a check box, and a drop-down box are triggered when you click it. Therefore, onclick is the most suitable method for simulating them.

      el.attachEvent("onclick", function(){        testChange(clickChangeOne)     });

Well, the difficulties have been clarified. Competent People can try it on their own.

Livesetup: [function (OBJ) {obj. attachevent ("onbeforeactivate", function () {var El = Window. event. srcelement, type = el. type; If (rselect. test (type) {// data correction if (Dom. store (El, "_ change_data") === undefined) Dom. store (El, "_ change_data", getval (EL)} else {Dom. store (El, "_ change_data", getval (EL) }}) ;}, function (OBJ) {// pair of text textarea File Password obj. attachevent ("onfocusout", function () {testchange (focusoutchangeone) // data correction}) ;}, function (OBJ) {// select checkbox radio obj. attachevent ("onclick", function () {testchange (clickchangeone) // event call and data correction});}]

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.