Нажмите «Вся строка» (сохранение среднего щелчка и Ctrl + щелчок) - PullRequest
33 голосов
/ 21 мая 2009

У меня есть HTML-таблица со ссылкой в ​​первом столбце. Я хочу позволить пользователю щелкнуть в любом месте строки, чтобы активировать эту ссылку. В то же время, я хотел бы сохранить функциональность среднего щелчка и Ctrl + клик для открытия новой вкладки / окна. Вот пример таблицы:

<table id="row_link"> 
  <tbody> 
    <tr>
      <td><a href="link1.html">link</a></td> 
      <td>info 1</td> 
    </tr>       
    <tr>
      <td><a href="link2.html">link</a></td> 
      <td>info 2</td> 
    </tr>       
  </tbody> 
</table> 

Используя jQuery, я могу позволить пользователю щелкнуть левой кнопкой мыши в любом месте строки:

$("table#row_link tbody tr").click(function () {
    window.location = $(this).find("a:first").attr("href");
});

Это, конечно, отключает стандартный щелчок средней кнопкой мыши и Ctrl + щелчок при открытии новой вкладки. Есть ли лучший способ позволить пользователям щелкать по всей строке, сохраняя при этом стандартное нажатие средней кнопкой мыши и поведение ctrl + clcik?

Ответы [ 10 ]

35 голосов
/ 25 мая 2009

К сожалению, в любом браузере нет способа симулировать ссылку и все связанное с ней поведение. Следовательно, единственный способ добиться того, чего вы хотите - это иметь ссылку, которая следует за курсором вокруг элемента <tr>; эта ссылка была бы невидимой, поэтому для пользователя это выглядит так, как будто они нажимают на <tr>, но фактически нажимают на скрытую ссылку. Используя этот метод, средняя кнопка, Ctrl + Click и любые другие варианты поведения остаются без изменений!

Вот ДЕМО: http://jsbin.com/ufugo

А вот код:

$("table tr").each(function(){

    var $link = $('a:first', this).clone(true),
        dim = {
            x: [
                $(this).offset().left,
                $(this).offset().left + $(this).outerWidth()
            ],
            y: [
                $(this).offset().top,
                $(this).offset().top + $(this).outerHeight()
            ]
        }

    $link
        .click(function(){
            $(this).blur();
        })
        .css({
            position: 'absolute',
            display: 'none',
            // Opacity:0  means it's invisible
            opacity: 0
        })
        .appendTo('body');

    $(this).mouseover(function(){
        $link.show();
    });

    $(document).mousemove(function(e){
        var y = e.pageY,
            x = e.pageX;
        // Check to see if cursor is outside of <tr>
        // If it is then hide the cloned link (display:none;)
        if (x < dim.x[0] || x > dim.x[1] || y < dim.y[0] || y > dim.y[1]) {  
            return $link.hide();
        }
        $link.css({
            top: e.pageY - 5,
            left: e.pageX - 5
        })
    });

});

EDIT:

Я создал плагин jQuery, используя немного лучший подход, чем выше: http://james.padolsey.com/javascript/table-rows-as-clickable-anchors/

12 голосов
/ 24 мая 2009

EDIT

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

Сначала вот демо

Вдохновленный решением @ Ник для очень похожей проблемы, я предлагаю простое решение css + jquery.

Во-первых, вот мини-плагин, который я написал. Плагин обернет каждую ячейку ссылкой:

jQuery.fn.linker = function(selector) {
    $(this).each(function() {
        var href = $(selector, this).attr('href');
        if (href) {
            var link = $('<a href="' + $(selector, this).attr('href') + '"></a>').css({
                'text-decoration': 'none',
                'display': 'block',
                'padding': '0px',
                'color': $(this).css('color')
            })
            $(this).children()
                   .css('padding', '0')
                   .wrapInner(link);
        }
    });
};

А вот пример использования:

$('table.collection tr').linker('a:first');

И все CSS вам нужно:

table.collection {
    border-collapse:collapse;
}

Это так просто.


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

В любом случае, вот как это сделать:

$("table#row_link tbody tr").click(function () {

    if((!$.browser.msie && e.button == 0) || ($.browser.msie && e.button == 1)){
        if (!e.ctrlKey) {
            // Left mouse button was clicked without ctrl
            window.location = $(this).find("a:first").attr("href");
        }
    }
});
7 голосов
/ 28 мая 2009

Я бы атаковал это со стороны HTML / CSS. Раньше это было распространенной проблемой, когда большинство сайтов делали все макеты в таблицах.

Сначала сделайте содержимое всех ячеек таблицы в ссылки. Если вы не хотите, чтобы они выглядели как ссылки, вы можете использовать CSS, чтобы удалить подчеркивание из ячеек «без ссылки». Но они будут ссылками, что в любом случае семантически то, что вы хотите.

Далее вы хотите, чтобы ссылка расширялась, чтобы заполнить всю ячейку. StackOverflow уже знает ответ на этот :

td a { display: block; width: 100%; height: 100%; line-height: 100%; }

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

6 голосов
/ 24 мая 2009

Вы хотите это:

$('table#row_link tbody tr').mousedown( function(e){
    if(e.ctrlKey || (!$.browser.msie && e.button == 1) || ($.browser.msie && e.button == 4)){
        //middle mouse button or ctrl+click
    } else {
        //normal left click
    }
});

Это проверено в FF3.0.10, Chrome 1.0 и IE6. Я использую событие mousedown, потому что ни firefox, ни IE не передают щелчок средней кнопки мыши событию .click (fn).

1 голос
/ 25 мая 2009

Вы можете сделать ссылку и позволить ей плавать в вашем tr, привязывая к событию mouveover, обновляя href и позицию

создать ссылку на один пиксель

<table id="row_link">....</table>
<a id="onepixel" style="position:absolute;z-index:1000;width:1px;height:1px;"></a>

обновить href и положение при наведении мыши на

$("#row_link tr").mouseover(
   function(event){
      //update href
      $("#onepixel").attr("href",$(this).find("a:first").attr("href"));
      //update position, just move to current mouse position
      $("#onepixel").css("top",event.pageY).css("left",event.pageX);
   }
);
1 голос
/ 23 мая 2009

Вот что должно работать: вместо использования window.location, мы используем .click () для эмуляции щелчка по первому внутри элемента. Также используйте условное выражение для проверки на CTRL + Click.

Должно выглядеть так:

$("table#row_link tbody tr").click(function (e) {
    if(e.ctrlKey) { 
        // Run Ctl+Click Code Here
    } else { 
        $(this).children('a').eq(0).click(); 
    }
}

Надеюсь, это поможет!

Дейв Ромеро

1 голос
/ 21 мая 2009

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

0 голосов
/ 24 мая 2009

Я думаю, что плагин largelink сделает то, что вы просите. Вот

0 голосов
/ 24 мая 2009

Попытайтесь поместить a вокруг td, а затем примените элемент CSS display: block к td.

Это должно сделать всю область тд кликабельной со всеми кнопками в качестве «нормальной» ссылки.

Пример, вероятно, лучше:

<table id="row_link"> 
  <tbody> 
    <tr>
      <a href="link1.html"><td style="display: block;">link</td></a> 
      <td>info 1</td> 
    </tr>       
    <tr>
      <a href="link2.html"><td style="display: block;">link</td></a>
      <td>info 2</td> 
    </tr>       
  </tbody> 
</table>

Подобный подход работал в прошлом для меня, хотя это было не совсем для элементов таблицы. Не проверено с таблицами, поэтому попробуйте.

0 голосов
/ 21 мая 2009
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...