#javascript #jquery #html #css
#javascript #jquery #HTML #css
Вопрос:
Я не знаю, с чего начать, но то, что мне нужно или нужно, — это функция-оболочка для HTMLElement, поэтому я не расширяю класс HTMLElement, а создаю свой собственный объект, а затем проверяю has class, Чтобы узнать, есть ли у элемента класс и т. Д. И т. Д. Но мой код вообще не работает, в нем написано $ (…).hasClass не является функцией
$ = function(a, b) {
this.$el = document.querySelector(a);
return this;
}
Object.assign($.prototype, {
hasClass: function(selector) {
return this.$el.classList.contains(selector);
}
})
console.log($('#list').hasClass('list'));
Ответ №1:
Вы почти на месте — проблема в том, что автономное выражение
$('#list')
будет иметь контекст вызова по умолчанию window
( this
значение внутри $
функции). Если вы хотите создать экземпляр, который может использовать методы-прототипы, поместите new
перед вызовом $
:
const $ = function(a, b) {
this.$el = document.querySelector(a);
}
Object.assign($.prototype, {
hasClass: function(selector) {
return this.$el.classList.contains(selector);
}
})
console.log(new $('#list').hasClass('list'));
console.log(new $('#list2').hasClass('foo'));
<div id="list"></div>
<div id="list2" class="foo"></div>
Если вы не хотите ставить new
перед каждым вызовом, вы можете использовать Object.create
inside $
:
const $ = function(a, b) {
const $obj = Object.create(proto);
$obj.$el = document.querySelector(a);
return $obj;
}
const proto = {
hasClass: function(selector) {
return this.$el.classList.contains(selector);
}
};
console.log($('#list').hasClass('list'));
console.log($('#list2').hasClass('foo'));
<div id="list"></div>
<div id="list2" class="foo"></div>
Я думаю, что способ, которым это делает jQuery, заключается в том, что внутренний прототип возвращаемого объекта $.fn
, например:
const $ = function(a, b) {
const $obj = Object.create($.fn);
$obj.$el = document.querySelector(a);
return $obj;
};
$.fn = {
hasClass: function(selector) {
return this.$el.classList.contains(selector);
}
};
console.log($('#list').hasClass('list'));
console.log($('#list2').hasClass('foo'));
<div id="list"></div>
<div id="list2" class="foo"></div>
Комментарии:
1. Хорошо, но я не хочу каждый раз вставлять ключевое слово «new» перед $(«), так что для этого нужно что-то делать
2. Используйте
Object.create
, как во втором фрагменте3. в нем говорится, что proto не определено
4. Нажмите кнопку «Выполнить фрагмент кода» в ответе, чтобы увидеть его в действии — здесь он работает просто отлично. Вы уверены, что вы определили
proto
в своем коде?5. Одним из моих пунктов было использование Object.assign($.prototype, {}); а теперь вы его убрали
Ответ №2:
Альтернативный метод, выполняемый с функцией возврата внутри функции
const $ = function(a, b) {
var elem = document.querySelector(a);
return {
hasClass: function(selector) {
return elem.classList.contains(selector);
},
addClass:function(cls){
elem.classList.add(cls)
}
}
};
console.log($('#list').hasClass('list'));
console.log($('#list2').hasClass('foo'));
$('#list2').addClass('color_red');
.color_red{
color:red
}
<div id="list"></div>
<div id="list2" class="foo">hello</div>