28.07.2012, 19:33
|
|
Новичок
|
|
Регистрация: 05.09.2010
Сообщений: 2,298
|
|
Повесить сеттер на input.value
Подскажите, как вызвать некую функцию не только при вызове события (keydown, select, change...), но и при обычном присваивании элементу формы некоегого значения:
input.value = 'blah'; // ← должна вызываться определенная функция
(на старые браузеры можно забить)
Обычный Object.defineProperty здесь, наверно, не прокатит, так как убивает стандартный геттер и сеттер.
Тот же вопрос интересен и касательно innerHTML.
Последний раз редактировалось FINoM, 28.07.2012 в 19:39.
|
|
28.07.2012, 19:38
|
что-то знаю
|
|
Регистрация: 24.05.2009
Сообщений: 5,176
|
|
<input id="lala" type="text" />
<script>
var inp = document.getElementById( 'lala' );
var descriptor = Object.getOwnPropertyDescriptor( inp, 'value' );
var oldSetter = descriptor.set;
descriptor.set = function( value ) {
alert( "Попытка назначить: " + value );
oldSetter.apply( this, arguments );
}
Object.defineProperty( inp, "value", descriptor );
inp.value = "test";;
</script>
|
|
28.07.2012, 19:41
|
|
Новичок
|
|
Регистрация: 05.09.2010
Сообщений: 2,298
|
|
devote,
Uncaught TypeError: Invalid property. A property cannot both have accessors and be writable or have a value, #<Object>
Object.getOwnPropertyDescriptor ( ROOT.name.field, 'value' )
→
configurable: true
enumerable: true
value: "Jubilee"
writable: true
Тут нет сеттера, как видно.
Последний раз редактировалось FINoM, 28.07.2012 в 19:46.
|
|
28.07.2012, 19:48
|
что-то знаю
|
|
Регистрация: 24.05.2009
Сообщений: 5,176
|
|
Я так понимаю это хром тупит с первым вариантом.
<input id="lala" type="text" />
<script>
var inp = document.getElementById( 'lala' );
Object.defineProperty( inp, "value", {
configurable: true,
enumerable: true,
set: function( value ) {
alert( "Попытка назначить: " + value );
this.setAttribute( "value", value );
},
get: function() {
return this.getAttribute( "value" );
}
});
inp.value = "test";
alert( inp.value );
</script>
|
|
28.07.2012, 19:50
|
|
Новичок
|
|
Регистрация: 05.09.2010
Сообщений: 2,298
|
|
devote, хм, как-то не догадался использовать атрибут. Спасибо.
|
|
28.07.2012, 19:51
|
|
Новичок
|
|
Регистрация: 05.09.2010
Сообщений: 2,298
|
|
Сообщение от devote
|
Я так понимаю это хром тупит с первым вариантом.
|
Он не тупит, просто дескриптор не содержит акцессоров.
|
|
28.07.2012, 19:54
|
что-то знаю
|
|
Регистрация: 24.05.2009
Сообщений: 5,176
|
|
Сообщение от FINoM
|
Он не тупит, просто дескриптор не содержит акцессоров.
|
это я понял, а опера содержит.
|
|
28.07.2012, 19:57
|
|
Новичок
|
|
Регистрация: 05.09.2010
Сообщений: 2,298
|
|
С innerHTML вопрос еще открыт. Здесь никак не заюзаешь атрибут.
Хотя, в принципе, можно погеморроиться: при срабатывании сеттера превращать полученную строку в DOM элементы, затем аппендить в искомый элемент, предварительно удалив каждый тег внутри.
При геттере преобразовывать элементы внутри в строку.
Но это уж слишком геморройно.
Последний раз редактировалось FINoM, 28.07.2012 в 20:02.
|
|
28.07.2012, 20:18
|
|
Новичок
|
|
Регистрация: 05.09.2010
Сообщений: 2,298
|
|
Вот она, рыба:
<div>Blah</div>
<span></span>
<script>
var div = document.querySelector( 'div' ),
span = document.querySelector( 'span' );
div.addEventListener( 'DOMSubtreeModified', function() {
span.innerHTML = 'fuck yea';
});
div.innerHTML = 'New HTML';
</script>
|
|
28.07.2012, 20:18
|
что-то знаю
|
|
Регистрация: 24.05.2009
Сообщений: 5,176
|
|
Сообщение от FINoM
|
Но это уж слишком геморройно.
|
ну почему геморойно, не так и геморно:
<div id="lala"></div>
<script>
var div = document.getElementById( 'lala' );
(function( div ) {
var currentInnerHTML = div.innerHTML;
Object.defineProperty( div, "innerHTML", {
configurable: true,
enumerable: true,
set: function( value ) {
alert( "Попытка назначить: " + value );
var div = document.createElement("DIV");
div.innerHTML = value;
currentInnerHTML = div.innerHTML;
// очищаем от всего что есть сейчас
while( this.firstChild ) {
this.removeChild( this.firstChild );
}
// добавляем новое
while( div.firstChild ) {
this.appendChild( div.firstChild );
}
},
get: function() {
return currentInnerHTML;
}
});
})( div );
div.innerHTML = "<b>test</b> <i>italic</i>";
alert( div.innerHTML );
</script>
|
|
|
|