Допустим у нас есть такой код и допустим пользователь оказался хитрым. Он вставил некий скрипт в код который изменяет значение у select
при событии click
:
document.addEventListener('click',function(){document.querySelectorAll("select")[0].value=document.querySelectorAll("option")[2].value},false)
<select onchange="console.log(event.target.value)">
<option value="Firefox Best!!!" selected> Firefox Best!!! </option>
<option value="Firefox Very best!!!" > Firefox Very best!!!</option>
<option value="Chrome Best!!!" >Chrome Best!!!</option>
</select>
Теперь selectElement.value="Chrome Best!!!"
и так как отловить изменение value
у select
? Только не предлагать по таймингу.
Эта функциональность есть, но она находится в экспериментальной части на данный момент ECMAScript 7
Object.observe(obj, callback)
в вашем случае это должно работать так
var sel = document.getElementById("select1");
Object.observe(sel , () => console.log("changed"));
Документация - https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/observe
На данный момент эта функциональность почти не поддерживается браузерами.
Никак, пользователь вообще может даже не в скрипте это заменить а через f12
в режиме отладки страницы, кроме того он вообще может отключить все скрипты на странице, сделать любые замены через f12
и потом снова включить скрипты, и вы ничего не поделаете никакими "защитными" мерами.
Кроме того он может вообще получаемый от сервера html код перехватить например снифером или прокси и внедрить туда что угодно.
Есть и другие варианты, например использования эмуляции браузера, перекомпилированный браузер с дополнительным кодом или плагинами, и так далее.
В любом случае любой запрос от клиента на сервер надо валидировать, и вот это взломать уже мало реально, при учёте грамотного кода и надёжного сервера.
По сути варианта без валидации запросов на сервере в нормальном и защищённом коде быть не должно.
Вам необходимо использовать MutationObserver
.
function changeElement() {
document.getElementById("id1").value = "zzz";
}
var mo = new MutationObserver(observe);
var el = document.getElementById("id1");
var config = {
attributes: true,
childList: true,
subTree: true
};
mo.observe(el, config);
function observe() {
alert("change");
}
<select onchange="console.log(event.target.value)">
<option value="Firefox Best!!!" selected> Firefox Best!!! </option>
<option value="Firefox Very best!!!" > Firefox Very best!!!</option>
<option id="id1" value="Chrome Best!!!" >Chrome Best!!!</option>
</select>
<a href="#" onclick="changeElement(); return false;">изменить</a>
Документация - https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver
Как оказалось в комментариях, вопорс сводится к тому, как сделать, чтобы событие change
вызывалось при программном изменении значения в select'е.
Например, в следующем коде событие не возникает при нажатии кнопки:
document.querySelector("select").addEventListener('change', function (e) {
console.log("Changed to: " + e.target.value)
})
document.querySelector("button").addEventListener('click', function (e) {
console.log("Button clicked: enter")
document.querySelector("select").value = 2
console.log("Button clicked: leave")
})
<select>
<option value=1 selected>Option 1</option>
<option value=2>Option 2</option>
<option value=3>Option 3</option>
</select>
<button>#2</button>
Решением может быть перехват присваивания при помощи сеттера свойства.
Следующий код проверен в Chrome 43 (в IE надо будет поменять способ создания события):
var select = document.querySelector("select");
select.addEventListener('change', function (e) {
console.log("Changed to: " + e.target.value)
})
var original = Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype, 'value');
Object.defineProperty(select, 'value', {
get: original.get,
set(val) {
console.log("set value: " + val)
var old = this.value
var res = original.set.call(this, val)
if (old != val) this.dispatchEvent(new Event('change'))
return res
}
})
document.querySelector("button").addEventListener('click', function (e) {
console.log("Button clicked: enter")
document.querySelector("select").value = 2
console.log("Button clicked: leave")
})
<select>
<option value=1 selected>Option 1</option>
<option value=2>Option 2</option>
<option value=3>Option 3</option>
</select>
<button>#2</button>
Это же решение можно применить для всех select'ов:
document.querySelector("select").addEventListener('change', function (e) {
console.log("Changed to: " + e.target.value)
})
var original = Object.getOwnPropertyDescriptor(HTMLSelectElement.prototype, 'value');
Object.defineProperty(HTMLSelectElement.prototype, 'value', {
get: original.get,
set(val) {
console.log("set value: " + val)
var old = this.value
var res = original.set.call(this, val)
if (old != val) this.dispatchEvent(new Event('change'))
return res
}
})
document.querySelector("button").addEventListener('click', function (e) {
console.log("Button clicked: enter")
document.querySelector("select").value = 2
console.log("Button clicked: leave")
})
<select>
<option value=1 selected>Option 1</option>
<option value=2>Option 2</option>
<option value=3>Option 3</option>
</select>
<button>#2</button>
В любом случае, я бы не рекомендовал так поступать, потому что скрипты могут ожидать, что значение не изменится при присваивании. Портить стандартное поведение браузера - это, как правило, плохая идея.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Подскажите, возможно ли добавить пустое значение в уже сформированный список и чтобы оно выводилось первым на вью?