Как я могу уменьшить избыточность в моем коде jQuery? - PullRequest
9 голосов
/ 08 июля 2009

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

Вот краткая выдержка:

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

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

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

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

Ответы [ 9 ]

12 голосов
/ 08 июля 2009

Вы можете добавить класс ко всем ссылкам, которые делают то же самое и работают с 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();
});
3 голосов
/ 08 июля 2009

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

3 голосов
/ 08 июля 2009

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

Например, скажем, у меня есть серия ссылок, каждая из которых сопровождается 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();
});
1 голос
/ 08 июля 2009
function makeToggler(number) {
    $('#link' + number).click(function() {
        $('.myDiv').hide();
        $('#myDiv' + number).toggle();
    });
}

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

Вы можете адаптировать его для соответствия вашим стандартам именования.

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

1 голос
/ 08 июля 2009

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

Ex:

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

function toggle(number) {
    $(".myDiv").hide();
    $("#myDiv"+number).toggle();
}
0 голосов
/ 09 июля 2009

бросить свой 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;
}

credit: building on SLaCKSрешение

0 голосов
/ 08 июля 2009

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

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

$(document).ready(function(){
    $('.link').click(function(){
      $('.myDiv').hide();
      var id = $(this).attr('id'); // take the id
      $('#myDiv'+id).toggle(); 
    });
});
0 голосов
/ 08 июля 2009

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

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

function toggle(obj) {
    $(".myDiv").hide();
    $("#myDiv" + $(obj).attr("id").replace('link','')).toggle();
}
0 голосов
/ 08 июля 2009

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

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

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

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

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