Советы и хитрости jQuery

Синтаксис

Хранение данных

Оптимизация

Разное

Ответ 1

Создание элемента 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");
});

Ответ 2

jQuery data() метод полезен и не известен. Это позволяет вам привязывать данные к элементам DOM без изменения DOM.

Ответ 4

Я действительно не поклонник ярлыка $(document).ready(fn). Конечно, он сокращает код, но также сокращает читаемость кода. Когда вы видите $(document).ready(...), вы знаете, на что вы смотрите. $(...) используется слишком многими другими способами, чтобы сразу иметь смысл.

Если у вас несколько фреймворков, вы можете использовать jQuery.noConflict();, как вы говорите, но вы также можете назначить для него другую переменную следующим образом:

var $j = jQuery.noConflict();

$j("#myDiv").hide();

Очень полезно, если у вас есть несколько фреймворков, которые можно скрыть до $x(...) -типов вызовов.

Ответ 5

Оооо, не забывай метаданные 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>

Ответ 6

Обработчики событий в реальном времени

Установите обработчик события для любого элемента, который соответствует селектору, даже если он добавлен в DOM после начальной загрузки страницы:

$('button.someClass').live('click', someFunction);

Это позволяет загружать контент через ajax или добавлять их через javascript и автоматически обрабатывать обработчики событий для этих элементов.

Аналогично, чтобы остановить обработку живых событий:

$('button.someClass').die('click', someFunction);

У этих живых обработчиков событий есть несколько ограничений по сравнению с обычными событиями, но они отлично работают в большинстве случаев.

Для получения дополнительной информации см. jQuery Documentation.

UPDATE: 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);.

Ответ 7

Заменить анонимные функции именованными функциями. Это действительно отменяет контекст 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 );

Ответ 8

Определение свойств при создании элемента

В jQuery 1.4 вы можете использовать литерал объекта для определения свойств при создании элемента:

var e = $("<a />", { href: "#", class: "a-class another-class", title: "..." });

... Вы даже можете добавлять стили:

$("<a />", {
    ...
    css: {
        color: "#FF0000",
        display: "block"
    }
});

Здесь ссылка на документацию.

Ответ 9

вместо использования другого псевдонима для объекта 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);

Я считаю, что это самый портативный. Я работал над сайтом, который одновременно использует как Prototype, так и jQuery, и эти методы избегают всех конфликтов.

Ответ 10

Проверить индекс

jQuery имеет .index, но это больно использовать, поскольку вам нужен список элементов, и передать в элемент, который вам нужен:

var index = e.g $('#ul>li').index( liDomObject );

Далее намного проще:

Если вы хотите узнать индекс элемента в наборе (например, элементы списка) в неупорядоченном списке:

$("ul > li").click(function () {
    var index = $(this).prevAll().length;
});

Ответ 11

Сокращение для готового события

Явный и подробный способ:

$(document).ready(function ()
{
    // ...
});

Сокращение:

$(function ()
{
    // ...
});

Ответ 12

В основной функции jQuery укажите параметр контекста в дополнение к параметру селектора. Указание параметра context позволяет jQuery начинать с более глубокой ветки в DOM, а не из корня DOM. Учитывая достаточно большой DOM, указание параметра контекста должно привести к повышению производительности.

Пример: поиск всех входов типа радио в первой форме в документе.

$("input:radio", document.forms[0]);

Ссылка: http://docs.jquery.com/Core/jQuery#expressioncontext

Ответ 13

Не совсем 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 внутри вашей клиентской реализации управления.

Ответ 14

Оптимизация производительности сложных селекторов

Запросить подмножество DOM при использовании сложных селекторов резко повышает производительность:

var subset = $("");

$("input[value^='']", subset);

Ответ 15

Говоря о советах и ​​трюках, а также о некоторых учебниках. Я нашел эти серии обучающих программ ( "Серия видео jQuery для абсолютных начинающих" Jeffery Way ОЧЕНЬ ПОЛЕЗНАЯ.

Он предназначен для тех разработчиков, которые являются новыми для jQuery. Он показывает, как создавать много классных вещей с помощью jQuery, например, анимация, создание и удаление элементов и многое другое...

Я многому научился у него. Он показывает, как легко использовать jQuery. Теперь мне это нравится, и я могу читать и понимать любой jQuery script, даже если он сложный.

Вот один пример, который мне нравится: Изменить размер текста "

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 Styling...

<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/

Ответ 16

Асинхронная функция each()

Если у вас действительно сложные документы, где запуск функции jquery each() блокирует браузер во время итерации, и/или Internet Explorer выдает сообщение "вы хотите продолжить выполнение этого сообщения script, это решение сохранит этот день.

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
};


Первый способ, которым вы можете его использовать, аналогичен каждому():

$('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


Я написал это для внутреннего проекта, и, хотя я уверен, что его можно улучшить, он работал для того, что нам нужно, поэтому надеюсь, что некоторые из вас сочтут это полезным. Спасибо -

Ответ 17

Синтаксическая стенопись-сахар-вещь - Кэш коллекции объектов и выполнение команд в одной строке:

Вместо

var jQueryCollection = $("");

jQueryCollection.command().command();

Я делаю:

var jQueryCollection = $("").command().command();

Несколько "реальным" вариантом использования может быть что-то в этом роде:

var cache = $("#container div.usehovereffect").mouseover(function ()
{
    cache.removeClass("hover").filter(this).addClass("hover");
});

Ответ 18

Мне нравится объявлять переменную $this в начале анонимных функций, поэтому я знаю, что могу ссылаться на jQueried this.

Так же:

$('a').each(function() {
    var $this = $(this);

    // Other code
});

Ответ 19

Сохранить объекты jQuery в переменных для повторного использования

Сохранение объекта 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();
});

Ответ 20

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

Маленькая подсказка - это функция jQuery.each(object, callback). Вероятно, все используют функцию jQuery.each(callback) для итерации по самому объекту jQuery, потому что это естественно. Функция утилиты jQuery.each(object, callback) выполняет итерацию по объектам и массивам. Долгое время я почему-то не видел, что это может быть за исключением другого синтаксиса (я не против писать все модные циклы), и мне немного стыдно, что я осознал свою основную силу только недавно.

Дело в том, что поскольку тело цикла в jQuery.each(object, callback) является функцией, вы получаете новую область каждый раз в цикле что особенно удобно при создании замыканий в цикле.

Другими словами, типичная распространенная ошибка заключается в том, чтобы сделать что-то вроде:

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, как ожидалось.

В общем, это не то, что вы не могли сделать сами, но его приятно иметь.

Ответ 21

Доступ к функциям 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 принимает значение boolean, которое определяет, класс должен быть добавлен или удален. Так что, насколько мой примерный код выше, это будет лучший подход...

$('selector').toggleClass('name_of_the_class', true/false);

Ответ 22

Удалить элементы из коллекции и сохранить цепочку

Рассмотрим следующее:

<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. В этом случае: все ли-элементы, не содержащие текст "Один" или "Два", будут удалены.

Ответ 23

Update:

Просто включите этот script на сайт, и вы получите консоль Firebug, которая появляется для отладки в любом браузере. Не совсем так полно, но все еще очень полезно! Не забудьте удалить его, когда закончите.

<script type='text/javascript' src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>

Проверьте эту ссылку:

Из CSS-трюков

Обновление: Я нашел что-то новое; его JQuery Hotbox.

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');

Ответ 24

Используйте методы фильтрации по псевдоселекторам, когда это возможно, поэтому jQuery может использовать querySelectorAll (что намного быстрее, чем шипение). Рассмотрим этот селектор:

$('.class:first')

Тот же выбор можно сделать, используя:

$('.class').eq(0)

Что должно быть быстрее, потому что исходный выбор ".class" совместим с QSA

Ответ 25

Изменение типа элемента ввода

Я столкнулся с этой проблемой, когда пытался изменить тип элемента ввода, уже прикрепленного к 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");

Ответ 26

Разумное использование скриптов jQuery сторонних производителей, таких как проверка поля формы или разбор URL. Это стоит посмотреть, как вы узнаете, когда вы столкнетесь с требованиями JavaScript.

Ответ 27

Линейные разрывы и цепочки

При объединении нескольких вызовов в коллекции...

$("a").hide().addClass().fadeIn().hide();

Вы можете повысить удобочитаемость при разрыве строк. Вот так:

$("a")
.hide()
.addClass()
.fadeIn()
.hide();

Ответ 28

Используйте .stop(true, true), когда запуск анимации не позволяет повторить анимацию. Это особенно полезно для анимации опрокидывания.

$("#someElement").hover(function(){
    $("div.desc", this).stop(true,true).fadeIn();
},function(){
    $("div.desc", this).fadeOut();
});

Ответ 29

Использование самоисполняющихся анонимных функций в вызове метода, например .append(), чтобы перебрать что-то. То есть:.

$("<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();
}()));

Я использую это, чтобы перебирать вещи, которые были бы большими и неудобными, чтобы вырваться из моей цепочки для сборки.

Ответ 30

Этот параметр выходит Kobi.

Рассмотрим следующий фрагмент кода:

// 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();