


![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я действительно не фанат ярлыка $(document).ready(fn). Конечно, это сокращает код, но также снижает читаемость кода. Когда вы видите $(document).ready(...), вы знаете, на что смотрите. $(...) используется слишком многими другими способами, чтобы сразу иметь смысл.
Если у вас несколько фреймворков, вы можете использовать jQuery.noConflict();, как вы говорите, но вы также можете назначить для него другую переменную, например:
var $j = jQuery.noConflict();
$j("#myDiv").hide();
Очень полезно, если у вас есть несколько фреймворков, которые можно свести к вызовам в стиле $x(...).
Каждый день я пробираюсь через бессмысленные XML / XLS / XLST сайты, написанные со слишком большим количеством уровней абстракции, сложные системы аварийного переключения на сайтах, которые никогда не перерастут самые скромные серверы ... и все еще люди жалуются на разницу между $ ( <строка>) & $ (<функция>). Мне хочется плакать :)
Когда я вижу $ (function () {...}), я понимаю, что происходит. Более обычные вещи должны быть короче. Поэтому мы превращаем часто вызываемые фрагменты кода в функции.
Разумное использование сторонних скриптов jQuery, таких как проверка полей формы или анализ URL. Стоит посмотреть, о чем идет речь, чтобы вы знали, когда в следующий раз столкнетесь с требованием JavaScript.
Мне нравится объявлять переменную $this в начале анонимных функций, поэтому я знаю, что могу ссылаться на jQueried this.
Вот так:
$('a').each(function() {
var $this = $(this);
// Other code
});
РОА: Да, это будет кислота :) Вы также можете использовать arguments.callee, чтобы анонимная функция могла ссылаться на себя
Джо, предупреждаем: вызываемый абонент перестанет работать с ECMAScript 5 и строгим режимом. См .: ejohn.org/blog/ecmascript-5-strict-mode-json-and-more
@Joe Вы могли бы дать ему имя, только остерегайтесь Причуды IE.
Отличный пример использования символа $ в начале имени переменной для обозначения объектной переменной jQuery по сравнению со стандартной переменной. Добавляя это в начало любой переменной, которая кэширует объект jQuery, вы сразу узнаете, глядя на него, что можете выполнять функции jQuery с переменной. Сразу делает код более читабельным.
Не совсем jQuery, но я сделал симпатичный мостик для jQuery и MS AJAX:
Sys.UI.Control.prototype.j = function Sys$UI$Control$j(){
return $('#' + this.get_id());
}
Это действительно хорошо, если вы много используете ASP.NET AJAX, поскольку jQuery поддерживается MS, теперь наличие хорошего моста означает, что операции jQuery действительно просты:
$get('#myControl').j().hide();
Таким образом, приведенный выше пример не очень хорош, но если вы пишете серверные элементы управления ASP.NET AJAX, это упрощает использование jQuery внутри реализации элемента управления на стороне клиента.
Предоставляет ли клиентская библиотека ajax способ поиска элемента управления оригиналом, если вы назначили (в коде позади)
this.get_id () вернет вам идентификатор элемента управления в клиентской области. Идентификатор, указанный сервером, не имеет значения, поскольку идентификатор клиента создается в зависимости от родительской иерархии cotrol.
Метод jQuery data() полезен и малоизвестен. Он позволяет привязывать данные к элементам DOM без изменения DOM.
data () действительно очень помогает.
Я заметил, что это не работает с элементами без установленного идентификатора.
Используйте data () вместо объявления глобальных переменных js, imo.
вместо того, чтобы использовать другой псевдоним для объекта jQuery (при использовании noConflict), я всегда пишу свой код jQuery, заключая его в закрытие. Это можно сделать в функции document.ready:
var $ = someOtherFunction(); // from a different library
jQuery(function($) {
if ($ instanceOf jQuery) {
alert("$ is the jQuery object!");
}
});
в качестве альтернативы вы можете сделать это так:
(function($) {
$('...').etc() // whatever jQuery code you want
})(jQuery);
Я считаю, что это самый портативный. Я работал над сайтом, который одновременно использует как прототип, так и jQuery, и эти методы позволили избежать всех конфликтов.
Второй пример хорош для глаз :)
Однако есть разница: первый пример будет ждать срабатывания события document.ready (), а второй - нет.
@SamBeran: Верно, сразу запустится второй пример; однако, если вы обертываете объектный литерал, вы можете использовать $ (document) .ready (...) внутри объектного литерала, что означает, что вы можете указать, когда вы хотите запустить каждый фрагмент кода.
instanceOf не подойдет, только instanceof. И все равно не получится, потому что jQuery instanceof jQuery вернет false. $ == jQuery - правильный способ сделать это.
@ Nyuszika7H: Да, вы правы, но не в этом суть примера кода.
Создание элемента HTML и сохранение ссылки
var newDiv = $("<div />");
newDiv.attr("id", "myNewDiv").appendTo("body");
/* Now whenever I want to append the new div I created,
I can just reference it from the "newDiv" variable */
Проверка наличия элемента
if ($("#someDiv").length)
{
// It exists...
}
Написание собственных селекторов
$.extend($.expr[":"], {
over100pixels: function (e)
{
return $(e).height() > 100;
}
});
$(".box:over100pixels").click(function ()
{
alert("The element you clicked is over 100 pixels height");
});
Написание собственных селекторов - это довольно гладко
Кроме того, если это поможет, вы действительно можете сделать $ ("<div />") и добиться того же, что и $ ("<div> </div>")
Мне нравится новая часть селектора, я не знал об этом.
Поскольку я еще не могу редактировать вики-сайты сообщества: объедините проверку назначения и существования с if ((var someDiv = $("#someDiv")).length) { /* do stuff with someDiv... */ }.
Добавление селекторов: потрясающе! Хотел бы я узнать это давным-давно!
@Ben: Причина, по которой я избегаю таких идиом в JavaScript, заключается в том, что я не хочу создавать иллюзию того, что someDiv имеет область видимости в операторе if, потому что это не так; JavaScript поддерживает только область действия
Вы можете вкладывать фильтры (как Никф показал здесь).
.filter(":not(:has(.selected))")
Хотя будьте осторожны с этим ...: has выполняет полный поиск, поэтому может оказаться довольно дорогим.
Сохранение объекта jQuery в переменной позволяет повторно использовать его без необходимости искать его в DOM.
(Как предложил @Louis, теперь я использую $, чтобы указать, что переменная содержит объект jQuery.)
// Bad: searching the DOM multiple times for the same elements
$('div.foo').each...
$('div.foo').each...
// Better: saving that search for re-use
var $foos = $('div.foo');
$foos.each...
$foos.each...
В качестве более сложного примера предположим, что у вас есть список продуктов в магазине, и вы хотите показать только те, которые соответствуют критериям пользователя. У вас есть форма с флажками, каждый из которых содержит критерий. Флажки имеют названия вроде organic и lowfat, а продукты имеют соответствующие классы - .organic и т. д.
var $allFoods, $matchingFoods;
$allFoods = $('div.food');
Теперь вы можете продолжить работу с этим объектом jQuery. Каждый раз, когда устанавливается флажок (чтобы установить или снять отметку), начните с основного списка продуктов и выполните фильтрацию на основе отмеченных флажков:
// Whenever a checkbox in the form is clicked (to check or uncheck)...
$someForm.find('input:checkbox').click(function(){
// Start out assuming all foods should be showing
// (in case a checkbox was just unchecked)
var $matchingFoods = $allFoods;
// Go through all the checked boxes and keep only the foods with
// a matching class
this.closest('form').find("input:checked").each(function() {
$matchingFoods = $matchingFoods.filter("." + $(this).attr("name"));
});
// Hide any foods that don't match the criteria
$allFoods.not($matchingFoods).hide();
});
Согласно моему соглашению об именах, спереди должен стоять $. например var $allItems = ...
@Lavinski - Думаю, идея в том, что $ указывает, что это объект jQuery, что упростит визуальное отличие от других переменных.
@Louis - С тех пор я принял ваше соглашение и соответствующим образом обновлю свой ответ. :)
jQuery имеет .index, но использовать его сложно, так как вам нужен список элементов и передать элемент, индекс которого вам нужен:
var index = e.g $('#ul>li').index( liDomObject );
Намного проще сделать следующее:
Если вы хотите узнать индекс элемента в наборе (например, элементы списка) в неупорядоченном списке:
$("ul > li").click(function () {
var index = $(this).prevAll().length;
});
Что не так с основным методом index ()? Он находится в ядре как минимум с версии 1.2. docs.jquery.com/Core/index
Хорошо, да, я немного играл в адвоката дьявола, потому что, просматривая jQuery index (), я понял, что это своего рода заноза в заднице. Благодарю за разъяснение!
Это круто, но важно знать, что это не сработает, если у вас были предыдущие братья и сестры, которые не были частью выбора.
Я почти уверен, что начиная с jQuery 1.4 вы можете просто использовать index() и получить индекс от его родителя.
@alex - конечно, но обратите внимание на дату этого поста - это было за 5 месяцев до выпуска 1.4!
В основной функции jQuery укажите параметр контекста в дополнение к параметру селектора. Указание параметра контекста позволяет jQuery начинать с более глубокой ветви в DOM, а не из корня DOM. Учитывая достаточно большой DOM, указание параметра контекста должно привести к увеличению производительности.
Пример: находит все входные данные типа "радио" в первой форме документа.
$("input:radio", document.forms[0]);
Ссылка: http://docs.jquery.com/Core/jQuery#expressioncontext
Примечание: $(document.forms[0]).find('input:radio') делает то же самое. Если вы посмотрите на исходный код jQuery, вы увидите: если вы передадите второй параметр в $, он фактически вызовет .find().
А что насчет ... $('form:first input:radio')?
Пол Айриш указал в paulirish.com/2009/perf (начиная со слайда 17), что делать это «наоборот» с точки зрения удобочитаемости. Как отметил @ Nyuszika7H, он использует .find () внутри, а $ (document.forms [0]). Find ('input: radio') очень легко читать, по сравнению с помещением контекста в начальный селектор.
Ооооо, давайте не будем забывать метаданные jQuery! Функция data () прекрасна, но ее нужно заполнять через вызовы jQuery.
Вместо того, чтобы нарушать совместимость W3C с такими атрибутами настраиваемых элементов, как:
<input
name = "email"
validation = "required"
validate = "email"
minLength = "7"
maxLength = "30"/>
Вместо этого используйте метаданные:
<input
name = "email"
class = "validation {validate: email, minLength: 2, maxLength: 50}" />
<script>
jQuery('*[class=validation]').each(function () {
var metadata = $(this).metadata();
// etc.
});
</script>
Атрибуты данных html5 делают это менее серьезной проблемой; идет обсуждение включения атрибута данных html5 в функцию jquery data (): forum.jquery.com/topic/…
@Oskar - да, это было реализовано в jQuery 1.4.3 - атрибуты data-* автоматически доступны через вызовы .data()
Синтаксическое сокращение-сахар-штука - Кэширует коллекцию объектов и выполняет команды в одной строке:
Вместо:
var jQueryCollection = $("");
jQueryCollection.command().command();
Я делаю:
var jQueryCollection = $("").command().command();
Отчасти «реальный» вариант использования может быть примерно таким:
var cache = $("#container div.usehovereffect").mouseover(function ()
{
cache.removeClass("hover").filter(this).addClass("hover");
});
лучше поместить ссылку $ (this) в локальную переменную, потому что здесь вы получите незначительное снижение производительности, потому что это займет немного больше времени ...
В этом случае (без каламбура) я использую «это» только один раз. Нет необходимости в кешировании.
Небольшая подсказка. Хотя в этом случае это может не иметь значения, вносить дополнительные изменения в DOM всегда - плохая идея. Скажем, например, элемент, над которым вы наводите курсор, уже имеет класс hover. Вы должны удалить этот класс и снова добавить его. Вы можете обойти это с помощью $(this).siblings().removeClass("hover"). Я знаю, что это звучит как мелочь, но каждый раз, когда вы меняете DOM, может запускаться другая перерисовка браузера. Другие возможности включают в себя события, прикрепленные к DOMAttrModified, или классы, изменяющие высоту элемента, которые могут запускать другие прослушиватели событий «изменения размера».
Если вы хотите использовать кеш и минимизировать изменения DOM, вы можете это сделать. cache.not(this).removeClass("hover")
@gradbot: Я не понимаю ваших последних двух комментариев. Не могли бы вы расшириться?
Замените анонимные функции именованными функциями. Это действительно заменяет контекст jQuery, но это больше похоже на использование jQuery из-за его зависимости от функций обратного вызова. Проблемы, с которыми я сталкиваюсь со встроенными анонимными функциями, заключаются в том, что их труднее отлаживать (гораздо легче смотреть на стек вызовов с четко обозначенными функциями, а не на 6 уровней «анонимности»), а также тот факт, что несколько анонимных функций внутри одного Цепочка jQuery может стать громоздкой для чтения и / или обслуживания. Кроме того, анонимные функции обычно не используются повторно; с другой стороны, объявление именованных функций побуждает меня писать код, который с большей вероятностью будет использоваться повторно.
Иллюстрация; вместо:
$('div').toggle(
function(){
// do something
},
function(){
// do something else
}
);
Я предпочитаю:
function onState(){
// do something
}
function offState(){
// do something else
}
$('div').toggle( offState, onState );
К сожалению, поскольку jQuery передает цель события как this, вы не можете получить «правильный» объектно-ориентированный объект без использования вложений. Я обычно иду на компромисс: $('div').click( function(e) { return self.onClick(e) } );
Извините, Бен, но я не понимаю, какое отношение ваш комментарий имеет к моему сообщению. Вы можете уточнить? Вы все еще можете использовать "self" (или любую другую переменную), используя мое предложение; это вообще ничего из этого не изменит.
Ага, Бен, что именно ты имеешь в виду !?
Я должен упомянуть: всегда меховая переменная и функции в пространстве имен не в корне !!
Установите обработчик событий для элемента Любые, который соответствует селектору, даже если он будет добавлен в DOM после начальной загрузки страницы:
$('button.someClass').live('click', someFunction);
Это позволяет загружать контент через ajax или добавлять его через javascript и автоматически настраивать обработчики событий для этих элементов.
Аналогичным образом, чтобы остановить обработку событий в реальном времени:
$('button.someClass').die('click', someFunction);
У этих обработчиков живых событий есть несколько ограничений по сравнению с обычными событиями, но они отлично работают в большинстве случаев.
Для получения дополнительной информации см. Документация jQuery.
ОБНОВЛЕНИЕ: live() и die() устарели в jQuery 1.7. См. http://api.jquery.com/on/ и http://api.jquery.com/off/ для аналогичных функций замены.
UPDATE2: live() давно устарел, даже до jQuery 1.7. Для версий jQuery 1.4.2+ до 1.7 используйте delegate() и undelegate(). Пример live() ($('button.someClass').live('click', someFunction);) можно переписать с использованием delegate() следующим образом: $(document).delegate('button.someClass', 'click', someFunction);.
Да, мне нравится новый концертный материал. Обратите внимание, что он работает только начиная с jQuery 1.3.
+1 .. вы избавили меня от боли в сердце .. Я просто случайно прочитал вашу запись, и пока я делал перерыв - устранение неполадок, почему мое мероприятие не запускалось. Спасибо
для всех, кто опоздал с этой статьей, вы можете также взглянуть на delegate (): api.jquery.com/delegate Подобно live, но более эффективно.
Просто помните, что .live поднимается до тела, чтобы связанное событие live могло быть запущено. Если что-то в процессе отменит это событие, прямая трансляция не сработает.
Не знал про die(). Спасибо!
live () и die () являются устаревшими методами, так как jQuery 1.7 выпущен 3 ноября. Заменено на on (), api.jquery.com/on и off (), api.jquery.com/off
Говоря о советах и хитростях, а также о некоторых руководствах. Я нашел эти серии руководств (Серия видео «jQuery для абсолютных новичков») от Джеффри Уэй ОЧЕНЬ ПОЛЕЗНЫ.
Он нацелен на тех разработчиков, которые плохо знакомы с jQuery. Он показывает, как создавать много интересных вещей с помощью jQuery, таких как анимация, создание и удаление элементов и многое другое ...
Я многому у него научился. Он показывает, как легко использовать jQuery. Теперь мне это нравится, и я могу читать и понимать любой сценарий jQuery, даже если он сложный.
Вот один пример, который мне нравится "Изменение размера текста"
1- jQuery ...
<script language = "javascript" type = "text/javascript">
$(function() {
$('a').click(function() {
var originalSize = $('p').css('font-size'); // get the font size
var number = parseFloat(originalSize, 10); // that method will chop off any integer from the specified variable "originalSize"
var unitOfMeasure = originalSize.slice(-2);// store the unit of measure, Pixle or Inch
$('p').css('font-size', number / 1.2 + unitOfMeasure);
if (this.id == 'larger'){$('p').css('font-size', number * 1.2 + unitOfMeasure);}// figure out which element is triggered
});
});
</script>
2- Стили CSS ...
<style type = "text/css" >
body{ margin-left:300px;text-align:center; width:700px; background-color:#666666;}
.box {width:500px; text-align:justify; padding:5px; font-family:verdana; font-size:11px; color:#0033FF; background-color:#FFFFCC;}
</style>
2- HTML ...
<div class = "box">
<a href = "#" id = "larger">Larger</a> |
<a href = "#" id = "Smaller">Smaller</a>
<p>
In today’s video tutorial, I’ll show you how to resize text every time an associated anchor tag is clicked. We’ll be examining the “slice”, “parseFloat”, and “CSS” Javascript/jQuery methods.
</p>
</div>
Настоятельно рекомендую эти уроки ...
http://blog.themeforest.net/screencasts/jquery-for-absolute-beginners-video-series/
Удалите элементы из коллекции и сохраните цепочку
Учтите следующее:
<ul>
<li>One</li>
<li>Two</li>
<li>Three</li>
<li>Four</li>
<li>Five</li>
</ul>
$("li").filter(function()
{
var text = $(this).text();
// return true: keep current element in the collection
if (text === "One" || text === "Two") return true;
// return false: remove current element from the collection
return false;
}).each(function ()
{
// this will alert: "One" and "Two"
alert($(this).text());
});
Функция filter() удаляет элементы из объекта jQuery. В этом случае: Все li-элементы, не содержащие текста «Один» или «Два», будут удалены.
Разве не проще просто использовать «каждый» и переместить изменение поля внутри переключателя?
Обновил свой ответ. Пожалуйста, дайте мне знать, если я ясно выражаюсь (э-э)
Действительно ли это УДАЛЯЕТ элементы li? Кажется, это предупреждение с отфильтрованным списком элементов.
Функция фильтра удаляет элементы из коллекции внутри объекта jQuery. Это не влияет на DOM.
В своей функции фильтрации вы можете просто написать: return !! $ (this) .text (). Match (/ One | Two /); ;)
Оптимизировать производительность сложных селекторов
Запрос к подмножеству DOM при использовании сложных селекторов значительно повышает производительность:
var subset = $("");
$("input[value^='']", subset);
Только если это подмножество кэшировано / сохранено.
Это не сильно отличается от $ (""). Find ("input [value ^ = '']")
@Dykam: что это такое в случае моего примера кода. Но ваша точка зрения по-прежнему актуальна.
@Chad, на самом деле он идентичен и соответствует функции, которую вы написали
(Это бессовестная вилка)
Вместо того, чтобы писать повторяющийся код обработки формы, вы можете попробовать этот плагин, который я написал, который добавляет к свободному API jQuery, добавляя методы, связанные с формой:
// elementExists is also added
if ($("#someid").elementExists())
alert("found it");
// Select box related
$("#mydropdown").isDropDownList();
// Can be any of the items from a list of radio boxes - it will use the name
$("#randomradioboxitem").isRadioBox("myvalue");
$("#radioboxitem").isSelected("myvalue");
// The value of the item selected. For multiple selects it's the first value
$("#radioboxitem").selectedValue();
// Various, others include password, hidden. Buttons also
$("#mytextbox").isTextBox();
$("#mycheck").isCheckBox();
$("#multi-select").isSelected("one", "two", "three");
// Returns the 'type' property or 'select-one' 'select-multiple'
var fieldType = $("#someid").formElementType();
вы знаете о .length и .is () (api.jquery.com/is), верно? if ($ ('# что угодно'). length) {/ * присутствует * /}, $ ('# myDropDown'). is ('select') ... вау. вау, вау, вау, вау (и не забывайте о $ .fn.val ...)
Да, @Dan, плагин разработан по контракту. is также не определяет, является ли это текстовым полем, скрытым полем и т. д. Вся суть плагина - это легко читаемые функции, которые легко тестируются (поэтому он поставляется с примерно 15 тестами с использованием qunit).
Этот идет на Коби.
Рассмотрим следующий фрагмент кода:
// hide all elements which contains the text "abc"
$("p").each(function ()
{
var that = $(this);
if (that.text().indexOf("abc") > -1) that.hide();
});
Вот сокращение ... что примерно в два раза быстрее:
$("p.value:contains('abc')").hide();
Кажется, что большинство интересных и важных советов уже упоминалось, так что это лишь небольшое дополнение.
Небольшой совет - функция jQuery.each (объект, обратный вызов). Вероятно, все используют функцию jQuery.each (обратный вызов) для перебора самого объекта jQuery, потому что это естественно. Служебная функция jQuery.each (объект, обратный вызов) выполняет итерацию по объектам и массивам. Долгое время я как-то не понимал, для чего это может быть, кроме другого синтаксиса (я не против писать все вылепленные циклы), и мне немного стыдно, что я только недавно осознал его главную силу.
Дело в том, что, начиная с тело цикла в jQuery.each (объект, обратный вызов) - это функция, вы получаете новый объем каждый раз в цикле, что особенно удобно, когда вы создаете закрытие в цикле.
Другими словами, типичная распространенная ошибка - делать что-то вроде:
var functions = [];
var someArray = [1, 2, 3];
for (var i = 0; i < someArray.length; i++) {
functions.push(function() { alert(someArray[i]) });
}
Теперь, когда вы вызываете функции в массиве functions, вы получите трехкратное предупреждение с содержимым undefined, которое, скорее всего, не то, что вы хотели. Проблема в том, что существует только одна переменная i, и все три замыкания ссылаются на нее. Когда цикл завершается, окончательное значение i равно 3, а someArrary[3] - undefined. Вы можете обойти это, вызвав другую функцию, которая создаст для вас закрытие. Или вы используете утилиту jQuery, которая в основном сделает это за вас:
var functions = [];
var someArray = [1, 2, 3];
$.each(someArray, function(item) {
functions.push(function() { alert(item) });
});
Теперь, когда вы вызываете функции, вы получаете три предупреждения с содержанием 1, 2 и 3, как и ожидалось.
В общем, ничего такого, что ты не мог бы сделать сам, но приятно иметь.
Обновлять:
Просто включите этот скрипт на сайт, и вы получите консоль Firebug, которая появится для отладки в любом браузере. Не так полнофункционально, но все же очень полезно! Не забудьте удалить его, когда закончите.
<script type='text/javascript' src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
Посмотрите эту ссылку:
Обновлять: Я нашел что-то новое; это JQuery Hotbox.
Google размещает несколько библиотек JavaScript в Google Code. Загрузка оттуда экономит пропускную способность и загружается быстро, потому что уже кэширована.
<script src = "http://www.google.com/jsapi"></script>
<script type = "text/javascript">
// Load jQuery
google.load("jquery", "1.2.6");
google.setOnLoadCallback(function() {
// Your code goes here.
});
</script>
Или же
<script src = "http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type = "text/javascript"></script>
Вы также можете использовать это, чтобы узнать, когда изображение полностью загружено.
$('#myImage').attr('src', 'image.jpg').load(function() {
alert('Image Loaded');
});
"Console.info" файла firebug, который можно использовать для вывода сообщений и переменных на экран без использования окон предупреждений. «console.time» позволяет вам легко настроить таймер, чтобы обернуть кучу кода и посмотреть, сколько времени это займет.
console.time('create list');
for (i = 0; i < 1000; i++) {
var myList = $('.myList');
myList.append('This is list item ' + i);
}
console.timeEnd('create list');
ppl в Иране не может видеть веб-страницы, загруженные с помощью google api. на самом деле Google ограничил иранцев доступ к коду Google. Таким образом, 1
Я только что узнал, что вы можете использовать firebug в любом браузере. Это потрясающе.
Определение свойств при создании элемента
В jQuery 1.4 вы можете использовать литерал объекта для определения свойств при создании элемента:
var e = $("<a />", { href: "#", class: "a-class another-class", title: "..." });
... Вы даже можете добавлять стили:
$("<a />", {
...
css: {
color: "#FF0000",
display: "block"
}
});
Бесконфликтный режим
jQuery.noConflict();
"Run this function to give control of the
$variable back to whichever library first implemented it. This helps to make sure that jQuery doesn't conflict with the$object of other libraries.By using this function, you will only be able to access jQuery using the
jQueryvariable. For example, where you used to do$("div p"), you now must dojQuery("div p")".
Сокращение для готового мероприятия
Ясный и подробный способ:
$(document).ready(function ()
{
// ...
});
Сокращение:
$(function ()
{
// ...
});
Переносы строк и цепочка
При объединении нескольких вызовов в коллекции ...
$("a").hide().addClass().fadeIn().hide();
Вы можете улучшить читаемость с помощью переносов строк. Нравится:
$("a")
.hide()
.addClass()
.fadeIn()
.hide();
В этом случае первый вариант более читабелен, но да, в некоторых случаях разрывы строк повышают читаемость.
Изменение типа элемента ввода
Я столкнулся с этой проблемой, когда пытался изменить тип элемента ввода, уже прикрепленного к DOM. Вам нужно клонировать существующий элемент, вставить его перед старым элементом, а затем удалить старый элемент. Иначе не сработает:
var oldButton = jQuery("#Submit");
var newButton = oldButton.clone();
newButton.attr("type", "button");
newButton.attr("id", "newSubmit");
newButton.insertBefore(oldButton);
oldButton.remove();
newButton.attr("id", "Submit");
Асинхронная функция each ()
Если у вас есть действительно сложные документы, где запуск функции jquery каждый() блокирует браузер во время итерации, и / или Internet Explorer выдает сообщение «вы хотите продолжить выполнение этого скрипта», это решение спасет положение.
jQuery.forEach = function (in_array, in_pause_ms, in_callback)
{
if (!in_array.length) return; // make sure array was sent
var i = 0; // starting index
bgEach(); // call the function
function bgEach()
{
if (in_callback.call(in_array[i], i, in_array[i]) !== false)
{
i++; // move to next item
if (i < in_array.length) setTimeout(bgEach, in_pause_ms);
}
}
return in_array; // returns array
};
jQuery.fn.forEach = function (in_callback, in_optional_pause_ms)
{
if (!in_optional_pause_ms) in_optional_pause_ms = 10; // default
return jQuery.forEach(this, in_optional_pause_ms, in_callback); // run it
};
Первый способ его использования такой же, как и each ():
$('your_selector').forEach( function() {} );
необязательный второй параметр позволяет указать скорость / задержку между итерациями, который может быть полезен для анимации (следующий пример будет ждать 1 секунду между итерациями):
$('your_selector').forEach( function() {}, 1000 );
Помните, что, поскольку это работает асинхронно, вы не можете рассчитывать на то, что итерации будут завершены до следующей строки кода, например:
$('your_selector').forEach( function() {}, 500 );
// next lines of code will run before above code is complete
Я написал это для внутреннего проекта, и хотя я уверен, что его можно улучшить, оно сработало для того, что нам было нужно, так что надеюсь, что некоторые из вас сочтут его полезным. Спасибо -
Используйте .stop (true, true), когда запуск анимации предотвращает повторение анимации. Это особенно полезно для анимации при наведении курсора.
$("#someElement").hover(function(){
$("div.desc", this).stop(true,true).fadeIn();
},function(){
$("div.desc", this).fadeOut();
});
Использование самоисполняющихся анонимных функций в вызове метода, такого как .append(), для перебора чего-либо. I.E .:
$("<ul>").append((function ()
{
var data = ["0", "1", "2", "3", "4", "5", "6"],
output = $("<div>"),
x = -1,
y = data.length;
while (++x < y) output.append("<li>" + info[x] + "</li>");
return output.children();
}()));
Я использую это, чтобы перебирать вещи, которые было бы неудобно и неудобно вырвать из моей цепочки для построения.
Вот изящный способ увеличить индекс строки клонированного элемента ввода, если имя вашего элемента ввода содержит индекс строки, такой как '0_row':
$(this).attr('name', $(this).attr('name').replace(/^\d+/, function(n){ return ++n; }));
Имя клонированного элемента теперь будет '1_row'.
Доступ к функциям jQuery, как к массиву
Добавить / удалить класс на основе логического ...
function changeState(b)
{
$("selector")[b ? "addClass" : "removeClass"]("name of the class");
}
Это более короткая версия ...
function changeState(b)
{
if (b)
{
$("selector").addClass("name of the class");
}
else
{
$("selector").removeClass("name of the class");
}
}
Не так много вариантов использования для этого. Тем не менее; Думаю аккуратно :)
Обновлять
На всякий случай, если вы не из тех, кто читает комментарии, ThiefMaster указывает на toggleClass принимает логическое значение, который определяет, следует ли добавить или удалить класс. Что касается моего примера кода выше, это был бы лучший подход ...
$('selector').toggleClass('name_of_the_class', true/false);
Это изящно и имеет несколько интересных применений, но в нем нет ничего специфического для jQuery ... это просто то, что вы можете сделать с любым объектом JavaScript.
Спасибо :) ... Это базовый JavaScript; да уж. Но я бы сказал, что jQuery - это JavaScript. Я не утверждаю, что это специфично для jQuery.
Однако в этом конкретном случае вы действительно хотите использовать $('selector').toggleClass('name_of_the_class', b);.
По возможности используйте методы фильтрации псевдоселекторов, чтобы jQuery мог использовать querySelectorAll (что намного быстрее, чем sizzle). Рассмотрим этот селектор:
$('.class:first')
Такой же выбор можно сделать, используя:
$('.class').eq(0)
Это должно быть быстрее, потому что первоначальный выбор '.class' совместим с QSA
@ Nyuszika7H Я думаю, вы упускаете суть. Дело в том, что QSA не может оптимизировать большинство псевдоселекторов, поэтому $ ('. Class: eq (0)') будет медленнее, чем $ ('. Class'). Eq (0).
Бесстыдная пробка ... Плагин шаблона jQuery: реализация сложной логики с помощью функций рендеринга
The new jQuery template plug-in is awesome. That being said, the double-curly brace template-tags are not exactly my cup of tea. In a more complex template the tags obscure the templates markup, and implementing logic past simple if/else statements is a pain.
After messing around with the plug-in for a few hours, my head began to hurt from trying to distinguish the markup in my template from the millions of double curly braces.
So I popped an aspirin and began work on an alternative
Посмотрите на JSRender. Я думаю, что двойная фигурная скобка становится чем-то вроде стандарта для шаблонов в шаблонах JavaScript.
$.extend($.expr[':'], {
"aboveFold": function(a, i, m) {
var container = m[3],
var fold;
if (typeof container === "undefined") {
fold = $(window).height() + $(window).scrollTop();
} else {
if ($(container).length == 0 || $(container).offset().top == null) return false;
fold = $(container).offset().top + $(container).height();
}
return fold >= $(a).offset().top;
}
});
$("p:aboveFold").css({color:"red"});
Спасибо Скоттимак
На более фундаментальной и высокоуровневой ноте вы можете попытаться эмулировать базовый механизм селектора jQuery, написав свой собственный небольшой фреймворк (это проще, чем кажется). Это не только бесконечно улучшит ваш Javascript, но и поможет вам понять, почему jQuery $ ("# elementId") во много раз быстрее, чем $ (". ElementClass"), а также быстрее, чем $ ("element # elementId ") (что, возможно, на первый взгляд противоречит интуиции).
Это также заставит вас узнать об объектно-ориентированном Javascript, который поможет вам организовать ваш код в более модульной форме, тем самым избегая природы спагетти-кода, которую могут принимать тяжелые блоки сценариев jQuery.
Доступ к элементам iFrame Iframe - не лучшее решение для большинства проблем, но когда вам все же нужно его использовать, очень удобно знать, как получить доступ к элементам внутри него с помощью Javascript. Метод content () jQuery упрощает эту задачу, позволяя загружать DOM iframe в одну строку, например:
$(function(){
var iFrameDOM = $("iframe#someID").contents();
//Now you can use <strong>find()</strong> to access any element in the iframe:
iFrameDOM.find(".message").slideUp();
//Slides up all elements classed 'message' in the iframe
});
Поддержка атрибутов данных HTML5 на стероидах!
функция данных упоминалось ранее. С его помощью вы можете связывать данные с элементами DOM.
Недавно команда jQuery добавила поддержку Пользовательские данные HTML5 - * атрибуты. И как будто этого было недостаточно; они принудительно загрузили функцию данных с помощью стероидов, что означает, что вы можете хранить сложные объекты в форме JSON прямо в вашей разметке.
HTML:
<p data-xyz = '{"str": "hi there", "int": 2, "obj": { "arr": [1, 2, 3] } }' />
JavaScript:
var data = $("p").data("xyz");
data.str // "hi there"
typeof data.str // "string"
data.int + 2 // 4
typeof data.int // "number"
data.obj.arr.join(" + ") + " = 6" // "1 + 2 + 3 = 6"
typeof data.obj.arr // "object" ... Gobbles! Errrghh!
Селектор элементов "заканчивается на" отлично подходит для разработки веб-форм ASP.NET, потому что вам не нужно беспокоиться о глупости добавленного ctl00:
$("[id$='txtFirstName']");
Как отмечено в комментариях, этот селектор (как и любой уровень абстракции) может работать медленно, если использовать его без осторожности. Предпочитайте ограничивать селектор некоторым содержащим элементом, например,
$(".container [id$='txtFirstName']");
для уменьшения количества требуемых элементов для перемещения.
Вы, вероятно, должны отметить / предупредить, что этот тип селектора невероятно медленный. Если вы не выбираете подмножество или кешированную коллекцию, этот селектор будет проходить все элементы в DOM и запускать регулярное выражение для свойства ID, чтобы определить совпадение.
Стивен, когда это действительно плохо, вы можете использовать этот, он ищет весь идентификатор $ ("input [id * = txtFirstName]"); // * поиск "по всем" В большинстве случаев я использую ClientID $ ('# <% = txtFirstName.ClientId%>');
Выполните привязку к событию и немедленно выполните обработчик событий:
$('selector').bind('change now', function () { // bind to two events: 'change' and 'now'
// update other portions of the UI
}).trigger('now'); // 'now' is a custom event
Это похоже на
function update() {
// update other portions of the UI
}
$('selector').change(update);
update();
но без необходимости создавать отдельную именованную функцию.
@Oli: О готовом стенографическом документе; у вас есть точка. Но тем не менее: это подсказка / уловка. Тот, который я использую во всем своем коде, просто потому, что считаю, что он «выглядит» лучше. Думаю, дело личных предпочтений :)