2009-07-08 6 views
9

Размер моего JavaScript-файла выходит из-под контроля, потому что у меня есть сотни ссылок, и каждый из них имеет свою функцию jQuery, хотя все они в основном выполняют одну и ту же задачу.Как я могу уменьшить избыточность в моем коде jQuery?

Вот небольшой отрывок:

$("#link1").click(function() 
{ 
    $(".myDiv").hide(); 
    $("#myDiv1").toggle(); 
}); 

$("#link2").click(function() 
{ 
    $(".myDiv").hide(); 
    $("#myDiv2").toggle(); 
}); 

$("#link3").click(function() 
{ 
    $(".myDiv").hide(); 
    $("#myDiv3").toggle(); 
}); 

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

+0

Святой FSM. Я просто устаю от JQuery, и я работал над этой _exact_ проблемой с обеда, и пришел сюда, чтобы сделать переполнение стека! – aape

ответ

12

Вы можете добавить класс ко всем ссылкам, которые делают то же самое, и действовать с помощью jQuery в этом классе.

<a href='whatever' id='link_1' class='toggler'>text</a> 
<a href='whatever' id='link_2' class='toggler'>text</a> 

JQuery код будет:

$(".toggler").click(function(){ 
    // toggle the divs 
    var number = $(this).attr("id").split('_')[1]; 
    $(".myDiv").hide(); 
    $("#myDiv"+ number).toggle(); 
}); 
+0

IMHO, это лучший подход, потому что, когда вы добавляете больше« ссылок »и« div »в свой HTML, код автоматически позаботится о том, чтобы обрабатывать поведение переключения для вас. BTW, Elzo, вам нужно чтобы указать, откуда приходит переменная 'number'. Что-то вроде var id = $ (this) .attr ('id'); var number = id.substr (id.indexOf ('_')); – SolutionYogi

+0

Предпочитаю используя механизмы обхода, а не в зависимости от форматов/значений id. Если элементы связаны друг с другом, они, как правило, тесно выровнены в DOM, и их можно легко найти, используя следующий/prev/find/closeest и т. Д. – tvanfosson

+0

Это очень хорошее предложение tvanfossaon. Но иногда невозможно объединить эти элементы в DOM на основе макета страницы. Мне также нравится идея Солдарна использовать атрибут href для переноса этой информации. http://stackoverflow.com/questions/1100026/how-can-i-reduce-the-redundancies-in-my-jquery-code/1100078#1100078 – SolutionYogi

1

Вы можете просто вызвать каждый вызов по вызову внешней функции и передать параметр для числовой строки.

Ex:

$("#link1").click(toggle("1")); 
$("#link2").click(toggle("2")); 

function toggle(number) { 
    $(".myDiv").hide(); 
    $("#myDiv"+number).toggle(); 
} 
+0

Мне нравится этот метод больше всего, потому что вы можете добавить любой элемент в любой другой элемент. то есть. '$ (" coolLink "). click (" 1 ");' – MitMaro

+0

Как написано, ваш код будет вызывать 'toggle()', когда применяется метод '.click()', а не когда пользователь на самом деле нажимает на ссылку , –

0

Я думаю, что это просто рефакторинга

вы могли бы определить функцию как таковой

function doSomethingTo(thisDiv) 
{ 
    $(".myDiv").hide(); 
    $(thisDiv).toggle(); 
} 

, а затем просто использовать его там, где нужно

$("#link1).click(doSomethingTo(thisDiv)); 
$("#link2).click(doSomethingTo(thisDiv)); 
+0

Я думаю, вы имеете в виду «' $ («# link1) .click (doSomethingTo)». –

+0

Вы вроде правы $ ("# link1"). Click (doSomethingto ("# myDiv1")); – jgarcia

+0

Это все равно будет немедленно вызывать 'doSomethingTo()' ** **, а не назначать его как обработчик кликов. Я считаю, что вы думаете о '$ (« # link1 »). Click (function() {doSomethingTo (this) ;}) '. –

0

Опираясь на решение Крэйга:

$("#link1, #link2").click(toggle(this)); 

function toggle(obj) { 
    $(".myDiv").hide(); 
    $("#myDiv" + $(obj).attr("id").replace('link','')).toggle(); 
} 
+0

у них сто ссылок ..поэтому я не буду выглядеть хорошо, чтобы писать # link1 .. # link100 один за другим :) (также он добавит больше кодов) – nightingale2k1

+0

Упс - не читал * целую вещь. Типичный я. В этом случае решение Elzo выше лучше. –

0

изменить ссылку стать, как это (я переименовать идентификатор только номер)

<a href='#test1' id='1' class='link'> ... </a> 
<a href='#test2' id='2' class='link'> ... </a> 
<a href='#test3' id='3' class='link'> ... </a> 

, а затем на js:

3

Общий подход, который я использую, заключается в использовании методов обхода для поиска связанных элементов, а не с использованием абсолютных селекторов. Это позволит вам применять один и тот же код к элементам, которые аналогичным образом настроены без каких-либо сложных зависимостей от формата идентификаторов и т. Д. Правильно это сделано, он также достаточно устойчив к незначительным изменениям разметки.

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

<a href="#" class="linkClass">Toggle</a> 
<div> 
    Some content... 
</div> 

<a href="#" class="linkClass">Toggle</a> 
<div> 
    Other content 
</div> 

Я бы тогда найти все ссылки по классу, а затем использовать метод next, чтобы найти соответствующий DIV и переключить его видимость. Обратите внимание, что это простой пример. Возможно, вам придется использовать более сложные механизмы обхода и фильтровать по типу или классу элемента, в зависимости от вашей точной маркировки.

$('.linkClass').click(function() { 
    $(this).next().toggle(); 
}); 
+0

Если ваш макет страницы позволяет этот HTML, я бы предпочел этот подход. :) – SolutionYogi

+0

Мое понимание вашего примера состоит в том, что это делает много предположений о взаимосвязи элементов на странице. Я работаю на очень стилизованной странице, в которой «следующий» элемент не связан с ссылкой. (По крайней мере, я так думаю). –

+0

@ipso facto - как я уже сказал, этот пример относительно прост. Если верно, что между элементами нет различимых отношений DOM, вам нужно найти какой-то другой механизм. Типичным случаем является то, что они связаны между собой, и вы можете найти механизм, использующий обход, чтобы перейти к связанному элементу. Find/nextall + each и т. Д. – tvanfosson

1
function makeToggler(number) { 
    $('#link' + number).click(function() { 
     $('.myDiv').hide(); 
     $('#myDiv' + number).toggle(); 
    }); 
} 

makeToggler(1); 
makeToggler(2); 
makeToggler(3); 

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

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

+0

Я думаю, что это самый чистый подход до сих пор, также предпочтительнее, так как функция makeToggler() может быть проверена достаточно честно. –

3

Как насчет добавления идентификатора вашей цели в ссылку href ссылки?

<a id="link1" href="#myDiv1" class="toggle">Toggle 1</a><br/> 
<a id="link2" href="#myDiv2" class="toggle">Toggle 2</a><br/> 
<a id="link3" href="#myDiv3" class="toggle">Toggle 3</a><br/> 

Тогда вы могли бы написать одну функцию следующим образом:

$(".toggle").click(function(e) { 
    e.preventDefault(); 
    $(".myDiv").hide(); 
    $($(this).attr('href')).toggle(); 
}); 

Или другой подход, который я использовал:

$(".toggle").each(function(i) { 
    $(this).click(function(e) { 
     e.preventDefault(); 
     $(".myDiv").hide(); 
     $(".myDiv:eq("+i+")").toggle(); 
    }); 
}); 

Это один находится в том же ключе, tvanfosson, используя какое-то отношение DOM для связывания элементов, в этом случае, предположив, что элементы ссылки и элементы div находятся в t он же порядок на странице.

+0

Это хорошая идея. –

0

Бросьте свой makeToggle в петлю?

function makeToggler(number) { 
    $('#link' + number).click(function() { 
     $('.myDiv').hide(); 
     $('#myDiv' + number).toggle(); 
    }); 
} 

for(i=1;i>=#;i++) {makeToggler(i);} 

тогда вы могли бы даже это рассчитывать ваши ссылки для вас, что-то ссылку это ?:

function countElementsByClass(className){ 
    var count = 0; 
    var o = document.getElementsByTagName("a").className; 
    for(var i=0;i<o.length;i+){ 
     if(o[i].className == "accordion/whatever") 
      count ++; 
     } 

    return count; 
} 

кредита: строительство на слабины решения

+0

Или, '$ ('a.accordian'). Length' – SLaks