2017-01-18 4 views
1

Я хотел бы расширить интерфейс HTMLElement с помощью настраиваемого объекта в настраиваемом свойстве. Возможно ли это?Расширение интерфейса HTMLElement с классами

Это то, что я получил:

if (typeof HTMLElement.prototype.classList === "undefined") { 
    HTMLElement.prototype.classList = function ClassList() { return this.className.split(' '); }; 
    HTMLElement.classList.prototype.add = function(name) { 
     if (classList.indexOf(name) !== -1) { 
      return; 
     } 
     classList[classList.length] = name; 
     this.className = classList.join(' '); 
    }; 
    HTMLElement.classList.prototype.remove = function(name) { 
     var index = classList.indexOf(name); 
     if (index !== -1) { 
      this.className = classList.splice(index + 1, 1).join(' '); 
     } 
    } 
} 

Это должно дать вам хорошее представление о том, что мне нужно.

Я хочу реализовать свои собственные функции classList для IE9. В IE это приведет к неопределенности и вызовет ошибку.

element.classList.add('fadeIn'); 

Есть ли простой способ реализовать это?

EDIT

Я играл вокруг с этим на некоторое время, но мои знания не достаточно хорошо еще, чтобы понять, что именно происходит. Мне еще нужно позвонить document.getElementById('whatever').classList(), чтобы избежать получения «неопределенного». Я бы хотел, чтобы иметь возможность вызвать classList без брекетов (если браузер не поддерживает классList, конечно)

+0

Вы проверяете 'classlist', но реализуете' classList'. Это не одно и то же. – Xufox

+0

Правильно ... это была просто опечатка, исходный вопрос остается таковым :) – DerpyNerd

ответ

1

Для определения поглотителя (функция, которая может быть вызвана без скобок), используйте Object.defineProperty. Работает в IE9.

function getClassList() 
{ 
    var element = this; 
    var classList = this.className.split(' '); 
    classList.add = function(name) { 
     if (classList.indexOf(name) !== -1) { 
      return; 
     } 
     classList.push(name); 
     element.className = classList.join(' '); 
    }; 
    classList.remove = function(name) { 
     var index = classList.indexOf(name); 
     if (index !== -1) { 
      classList.splice(index, 1); 
      element.className = classList.join(' '); 
     } 
    }; 
    return classList; 
} 

Object.defineProperty(HTMLElement.prototype, 'classList', { get: getClassList }); 
+0

Я проверю, когда вернусь домой, но это, вероятно, Это. Я сейчас работаю, и следующая команда работает в IE9: 'Object.defineProperty (HTMLElement.prototype, 'classList', {value: {}});' – DerpyNerd

+0

@RobbieVercammen Я протестировал это и исправил его. В частности, поскольку 'classList' является массивом, не удобно добавлять методы' add' и 'remove' непосредственно к прототипу (который является' Array.prototype'). Существуют, однако, [polyfills] (https://github.com/remy/polyfills), которые используют пользовательские объекты, а не массив для 'classList' (не тестируются). –

+0

Я попробую ваше новое предложение, спасибо – DerpyNerd

1

Я думаю, что вы настроили прототип неправильно.

Вы должны назначать classList до HTMLElement.prototype, а не непосредственно на HTMLElement.

Чтобы получить доступ к нему, как он работает изначально, вы можете настроить его, как так ...

HTMLElement.prototype.classList = function() 
    // ... 
}; 

HTMLElement.prototype.classList.add = function() 
    // ... 
}; 

HTMLElement.prototype.classList.remove = function() 
    // ... 
}; 
+0

Вы правы, но это не решает вопрос. Мне все еще нужно вызвать 'document.getElementById ('whatever'). ClassList()', чтобы избежать получения "undefined". Я хотел бы иметь возможность вызвать classList без брекетов. – DerpyNerd

+0

@RobbieVercammen Назначьте их непосредственно этой функции, а не ее прототипу. например 'HTMLElement.prototype.classList.add =/* ваша функция * /' – alex

+0

Я думаю, что я, возможно, пробовал это раньше, я попробую ваше предложение, когда вернусь домой – DerpyNerd

Смежные вопросы