Kirish qiymati JavaScript tomonidan o'zgartirilsinmi?

<input> elementining qiymati JavaScript-kod orqali o'zgartirilganda nima bo'ladi? Misol uchun:

$input.value = 12;

input hodisasi bu erda yordam bermaydi, chunki u qiymatni o'zgartiruvchi foydalanuvchi emas.

Chrome brauzerini sinab ko'rganda, change hodisasi ishdan chiqarilmaydi. Ehtimol, element odatdagidan mahrum bo'lgandir (u e'tiborni o'ziga jalb qilmadi, shuning uchun uni yo'qotib bo'lmaydi)?

4
Qiymat Javascript tomonidan o'zgartirilganda hech qanday hodisa yo'q.
qo'shib qo'ydi muallif Barmar, manba
Ba'zi istisnolar mavjud bo'lsa-da, voqealar ko'pincha faqat Javascript kodidan emas, brauzerga ta'sir qiluvchi tashqi harakatlar tufayli o'chiriladi.
qo'shib qo'ydi muallif Barmar, manba
@Kinduser yo'q ...
qo'shib qo'ydi muallif epascarello, manba
@Kinduser "Yo'q" to'liq javob.
qo'shib qo'ydi muallif epascarello, manba
jQuery dublikatini topa olmayapman. title = "qiymatni qo'l bilan belgilashda onchange voqeasi yoqilmaydi"> stackoverflow.com/questions/30291801/…
qo'shib qo'ydi muallif epascarello, manba

6 javoblar

Buning uchun ichki voqea yo'q. Sizda kamida to'rt variant mavjud:

  1. Kod ichidagi $ input.value kodini o'zgartirganingizda, o'zgarish natijasida paydo bo'lgan kodni chaqiring
  2. O'zgarishlar uchun so'rov
  3. O'zingizga o'zingizninig qiymatini o'zgartirish uchun foydalanadigan metod bering, bu shuningdek bildirishnomalar beradi.
  4. (3-variant) O'zgartirishni ishlatish uchun foydalanadigan xususiyati ni bering, u ham bildirishnomalarni beradi

Buning ustiga, # 1, # 3 va # 4 kodlari sizning kodingizdan faqatgina $ input.value = "new value"; 2, faqat value ni belgilaydigan kod bilan ishlaydigan yagona narsa.

Tafsilotlar:

  1. The simplest solution: Any time you change $input.value in code, call the code you want triggered by the change:

    $input.value = "new value";
    handleValueChange();
    
  2. Poll for changes:

    var last$inputValue = $input.value;
    setInterval(function() {
        var newValue = $input.value;
        if (last$inputValue != newValue) {
            last$inputValue = newValue;
            handleValueChange();
        }
    }, 50);//20 times/second
    

    Polling has a bad reputation (for good reasons), because it's a constant CPU consumer. Modern browsers dial down timer events (or even bring them to a stop) when the tab doesn't have focus, which mitigates that a bit. 20 times/second isn't an issue on modern systems, even mobiles.

    But still, polling is an ugly last resort.

    Example:

    <div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false"> <div class="snippet-code snippet-currently-hidden">

    var $input = document.getElementById("$input");
    var last$inputValue = $input.value;
    setInterval(function() {
        var newValue = $input.value;
        if (last$inputValue != newValue) {
            last$inputValue = newValue;
            handleValueChange();
        }
    }, 50);//20 times/second
    function handleValueChange() {
        console.log("$input's value changed: " + $input.value);
    }
    // Trigger a change
    setTimeout(function() {
        $input.value = "new value";
    }, 800);
    <input type="text" id="$input">
    </div> </div>
  3. Give yourself a function to set the value and notify you, and use that function instead of value, combined with an input event handler to catch changes by users:

    $input.setValue = function(newValue) {
        this.value = newValue;
        handleValueChange();
    };
    $input.addEventListener("input", handleValueChange, false);
    

    Usage:

    $input.setValue("new value");
    

    Naturally, you have to remember to use setValue instead of assigning to value.

    Example:

    <div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false"> <div class="snippet-code snippet-currently-hidden">

    var $input = document.getElementById("$input");
    $input.setValue = function(newValue) {
        this.value = newValue;
        handleValueChange();
    };
    $input.addEventListener("input", handleValueChange, false);
    function handleValueChange() {
        console.log("$input's value changed: " + $input.value);
    }
    // Trigger a change
    setTimeout(function() {
        $input.setValue("new value");
    }, 800);
    <input type="text" id="$input">
    </div> </div>
  4. A variant on #3: Give yourself a different property you can set (again combined with an event handler for user changes):

    Object.defineProperty($input, "val", {
        get: function() {
            return this.value;
        },
        set: function(newValue) {
            this.value = newValue;
            handleValueChange();
        }
    });
    $input.addEventListener("input", handleValueChange, false);
    

    Usage:

    $input.val = "new value";
    

    This works in all modern browsers, even old Android, and even IE8 (which supports defineProperty on DOM elements, but not JavaScript objects in general). Of course, you'd need to test it on your target browsers.

    But $input.val = ... looks like an error to anyone used to reading normal DOM code (or jQuery code).

    Before you ask: No, you can't use the above to replace the value property itself.

    Example:

    <div class="snippet" data-lang="js" data-hide="true" data-console="true" data-babel="false"> <div class="snippet-code snippet-currently-hidden">

    var $input = document.getElementById("$input");
    Object.defineProperty($input, "val", {
        get: function() {
            return this.value;
        },
        set: function(newValue) {
            this.value = newValue;
            handleValueChange();
        }
    });
    $input.addEventListener("input", handleValueChange, false);
    function handleValueChange() {
        console.log("$input's value changed: " + $input.value);
    }
    // Trigger a change
    setTimeout(function() {
        $input.val = "new value";
    }, 800);
    <input type="text" id="$input">
    </div> </div>
5
qo'shib qo'ydi

@ T-j-crowder va @ maciej-swist javoblarga asoslanib, ob'ektni qayta tanlanmasdan cheksiz pastadirni oldini olish uchun ".apply" funktsiyasini qo'shamiz.

 function customInputSetter(){

  var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
  var originalSet = descriptor.set;

 //define our own setter
  descriptor.set = function(val) {
    console.log("Value set", this, val);
    originalSet.apply(this,arguments);
  }

  Object.defineProperty(HTMLInputElement.prototype, "value", descriptor);
}
3
qo'shib qo'ydi

T.J.ga asoslangan 5-chi variantni qo'shaman. Crowder takliflari. Lekin yangi xususiyatni qo'shish o'rniga siz aniq "input" funktsiyasini ma'lum kirish elementi yoki barcha kirish moslamalari uchun o'rnatilganida qo'shimcha harakatni tetiklash uchun o'zgartirishingiz mumkin:

//First store the initial descriptor of the "value" property:

var descriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");
var inputSetter = descriptor.set;

//Then modify the "setter" of the value to notify when the value is changed:

descriptor.set = function(val) {

    //changing to native setter to prevent the loop while setting the value
    Object.defineProperty(this, "value", {set:inputSetter});
    this.value = val;

    //Custom code triggered when $input.value is set
    console.log("Value set: "+val);

    //changing back to custom setter
    Object.defineProperty(this, "value", descriptor);   
}

//Last add the new "value" descriptor to the $input element
Object.defineProperty($input, "value", descriptor);

Muayyan kirish elementi uchun "qiymat" xususiyatini o'zgartirish o'rniga, uni barcha kiritish elementlari uchun umumiy tarzda o'zgartirishi mumkin:

Object.defineProperty(HTMLInputElement.prototype, "value", descriptor);

Ushbu usul faqat JavaScript bilan o'zgarish uchun ishlaydi, masalan. input.value = "yangi qiymat". Kirish oynasidagi yangi qiymatni kiritishda ishlamaydi.

3
qo'shib qo'ydi
Men buni hali tekshirmayman, lekin juda aqlli. rahmat
qo'shib qo'ydi muallif pery mimon, manba

Bu erda barcha kirishlar uchun o'zgartirilgan qiymat xususiyatini bog'lash uchun yechim mavjud:

var valueDescriptor = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value");

HTMLInputElement.prototype.addInputChangedByJsListener = function(cb) {
    if(!this.hasOwnProperty("_inputChangedByJSListeners")) {
        this._inputChangedByJSListeners = [];
    }
    this._inputChangedByJSListeners.push(cb);
}

Object.defineProperty(HTMLInputElement.prototype, "value", {
    get: function() {
        return valueDescriptor.get.apply(this, arguments);
    },
    set: function() {
        var self = this;
        valueDescriptor.set.apply(self, arguments);
        if(this.hasOwnProperty("_inputChangedByJSListeners")){
            this._inputChangedByJSListeners.forEach(function(cb) {
                cb.apply(self);
            })
        }
    }
});

Foydalanish misoli:

document.getElementById("myInput").addInputChangedByJsListener(function() {
    console.log("Input changed to \"" + this.value + "\"");
});
2
qo'shib qo'ydi
Yaxshi tushunishga yordam bergan to'liq misol uchun rahmat
qo'shib qo'ydi muallif sairfan, manba

enter link description hereOne possible strategy is to use a mutationObserver to detect changes in attributes as follows:

var observer = new MutationObserver(function(mutations) {
          mutations.forEach(function(){
                 console.log('hello')});
          });

          observer.observe($input, {
                 attributes: true
          });

Bu o'z-o'zidan shunday o'zgarishlarni aniqlay olmasa ham:

$input.value = 12

Haqiqiy qiymat xususiyati o'zgarishini aniqlaydi:

$input.setAttribute('value', 12)

Ya'ni, siz dasturiy jihatdan qiymatni o'rnatayotgan bo'lsangiz, unda value = 12 iborasi bilan birga xususiyatni o'zgartirganingizga ishonch hosil qiling va siz xohlagan natijaga erishishingiz mumkin.

1
qo'shib qo'ydi
bu juda xushchaqchaq yechim. aslida tashqi o'zgarishlarni aks ettiraman, shuning uchun menga yordam bermayman. ammo u hali ham juda yaxshi yechim
qo'shib qo'ydi muallif pery mimon, manba

Kirish uchun barcha dasturiy ajratilgan stsenariylarni qamrab oladigan hodisa mavjud deb o'ylamayman. Lekin, sizlarga aytib qo'yay, dasturiy jihatdan "hodisani" o'chirib qo'yishingiz mumkin (maxsus voqea, muntazam hodisalar yoki voqea-hodisani [t] ishlating)

Menimcha, siz jQuery dan foydalanmoqdasiz, shuning uchun siz foydalanishingiz mumkin:

$('input#inputId').val('my new value...').triggerHandler('change');

Ushbu misolda siz "value" hodisasi bilan bog'langan ishlovchilarga (yoki ishlovchilarga) qo'ng'iroq qilishni taklif qilyapsiz.

0
qo'shib qo'ydi
Javascript UZB
Javascript UZB
99 ishtirokchilar

@js_uzb @vuejs_uz @react_uz @nodejs_uz @angular_uz @ngTashkent @yiiframework_uz @laravel_uz @linux_uzbek @python_uz @swift_uzb —————— @uzdevgroup @UzGeeksGroup ——— @UzDev_Jobs @jobs_uzb