Раньше метод узел.classList.toggle просто переключал наличие CSS-класса DOM-узла - есть класс/нет класса. То есть чтобы обеспечить какое-либо конкретное состояние, следовало сперва проконтролировать текущее. Неудобно. Разработчики стандарта
спохватились и поправили
спецификацию метода, добавив второй, булевский, параметр (собственно, желаемое наличие класса после применения метода) - то, что давно сделали во всяких там джейкуэри.
«Файерфокс»
собирается реализовать новую спецификацию, но пока необходим патч. Я написал вот такой:
let(oldToggle=DOMTokenList.prototype.toggle){
DOMTokenList.prototype.toggle=function(token, force){
if(arguments.length>=2 && typeof force !== "boolean")
console.warn("Ошибочный тип "+(typeof force)+" аргумента функции.");
let isInList=this.contains(token);
if(arguments.length<2 || isInList!==Boolean(force))
return oldToggle.call(this, token);
return isInList;
};
}
Поведение патча для метода DOMTokenList.prototype.toggle
Переменная isInListАргумент forceПрименять ли старый метод toggleВозврат метода
falseundefined✓true
falsefalse✗false
falsetrue✓true
trueundefined✓false
truefalse✓false
truetrue✗true
Дополнение от 6 ноября 2014 г.: только сейчас всплыло, что́ я упустил - второй параметр-то может быть передан не булевский! Пусть это и не бесспорная практика, но если её карать, нужно бросать исключение. При вызове нативной функции приведение произойдёт автоматически, а в моём полифилле его предусмотрено не было. И ещё надо предусмотреть, что второй параметр может быть вообще не передан, тогда в переменной force будет undefined и приведётся он к false, чего нам совершенно не надо. Дописал.