Jquery: проблемы с выбором элемента html, по которому щелкнули

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

вот мой шаблон:

<table id="this_week" width=88%>
    <tr id = "days">
        <th><p>Horaire</p></th>
        <th><p>lun.</p></th>
        <th><p>Mar.</p></th>
        <th><p>Mer.</p></th>
        <th><p>Jeu.</p></th>
        <th><p>Ven.</p></th>
        <th><p>Sam.</p></th>
        <th><p>Dim.</p></th>
    </tr>
    {% with hours="9h 9h30 10h 10h30 11h 11h30 12h 12h30 13h 13h30 14h 14h30 15h 15h30 16h 16h30 17h 17h30 18h 18h30 19h 19h30 20h 20h30 21h" %}
    {% for i in hours.split %}
        <tr id= "{{ i }}">
            <th><p>{{ i }}</p></th>
            <th id="{{ i }} lun" class="available" onclick='deliveryBooking()'></th>
            <th id="{{ i }} mar" class="available" onclick='deliveryBooking()'></th>
            <th id="{{ i }} mer" class="available" onclick='deliveryBooking()'></th>
            <th id="{{ i }} jeu" class="available" onclick='deliveryBooking()'></th>
            <th id="{{ i }} ven" class="available" onclick='deliveryBooking()'></th>
            <th id="{{ i }} sam" class="available" onclick='deliveryBooking()'></th>
            <th id="{{ i }} dim" class="available" onclick='deliveryBooking()'></th>
        </tr>
    {% endfor %}
    {% endwith %}
</table>
<script>
function deliveryBooking()
{
    if ($(this).hasClass('available')) {
        $(this).removeClass('available');
        $(this).addClass('unavailable');
        console.log($(this));
    };
};
</script>

Но этот сценарий ничего не делает, даже в журнале консоли ничего не отображается. Затем я попытался удалить атрибут «onclick» в ячейках и импортировал файл js с этим кодом (я пробовал следующие функции одну за другой), но безрезультатно:

$(document).ready(function() {

$("#this_week").children().find('.available').click(function(event){
    $(event.target).removeClass("available").addClass("unavailable");
    console.log($(event.target));
});

$("#this_week").children().find('.available').click(function(){
    $(this).removeClass("available").addClass("unavailable");
    console.log($(this));
});

});

Я также попытался удалить часть «children ()» и другие небольшие изменения, но я не знаю, что делать дальше. Есть идеи о том, что я делаю неправильно?

Пожалуйста, нажмите t <> snippet editor и добавьте RENDERED html и соответствующий скрипт. Нет причин размещать шаблон, так как это проблема JS

mplungjan 10.09.2018 11:15
$(".available").on("click",function() { $(this).toggleClass("available unavailable"); })
mplungjan 10.09.2018 11:18

@mplungjan теперь так лучше

Beginner 10.09.2018 11:19

@mplungjan, это, похоже, не работает для меня.

AlexMdg 10.09.2018 11:55

См. Мой ответ для примера

mplungjan 10.09.2018 12:04
1
5
62
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вам необходимо передать this в функции onclick, по умолчанию this относится к объекту window.

HTML

<th id="{{ i }} dim" class="available" onclick='deliveryBooking(this)'></th>

Js

<script>
function deliveryBooking(element)
{
    if ($(element).hasClass('available')) {
        $(element).removeClass('available');
        $(element).addClass('unavailable');
        console.log($(element));
    };
};
</script>

НАМНОГО лучше НЕ иметь встроенный код, но добавлять обработчики событий, которые работают

mplungjan 10.09.2018 11:16

Большое спасибо ! Это работает (но вы, наверное, уже знали об этом: p)!

AlexMdg 10.09.2018 11:20

Да, использование прослушивателя событий намного лучше, чем это и Cool @AlexMdg !.

Nishant Dixit 10.09.2018 11:22

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

AlexMdg 10.09.2018 11:26
Ответ принят как подходящий

Вот самый простой способ

Все, что я сделал, это удалил onclick и добавил

$(".available").on("click",function() { 
  $(this).toggleClass("available unavailable"); 
});

Создание таблицы не имеет значения, здесь я использую jQuery исключительно для создания ячеек для примера.

$.each("9h 9h30 10h 10h30 11h 11h30 12h 12h30 13h 13h30 14h 14h30 15h 15h30 16h 16h30 17h 17h30 18h 18h30 19h 19h30 20h 20h30 21h".split(" "),function(i,hour) {

        $("#hours").append(`<tr><th><p>${hour}</p></th>
            <th id="${i}lun" class="available"></th>
            <th id="${i}mar" class="available"></th>
            <th id="${i}mer" class="available"></th>
            <th id="${i}jeu" class="available"></th>
            <th id="${i}ven" class="available"></th>
            <th id="${i}sam" class="available"></th>
            <th id="${i}dim" class="available"></th></tr>`);
})
$(".available").on("click",function() { 
  $(this).toggleClass("available unavailable"); 
});
.available { background-color:green }
.unavailable { background-color:red }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<table id="this_week" width=88%>
    <tr id="days">
        <th><p>Horaire</p></th>
        <th><p>Lun.</p></th>
        <th><p>Mar.</p></th>
        <th><p>Mer.</p></th>
        <th><p>Jeu.</p></th>
        <th><p>Ven.</p></th>
        <th><p>Sam.</p></th>
        <th><p>Dim.</p></th>
    </tr>
    <tbody id="hours"></tbody>
</table>

Я вижу, вы написали таблицу с js вместо django. Я еще не знаю, облегчит ли это мою будущую работу над этой страницей или усложнит ее: мне придется работать с моделями, переменными и т. д. Django ... Я проголосовал за ответ, но сделаю окончательный выбор позже сегодня вернемся немного к бэкэнду. Тем временем я буду придерживаться ответа @Nishant_Dixit (меньше изменений) и посмотрю, как он пойдет. В любом случае спасибо за это, для меня это хороший урок.

AlexMdg 10.09.2018 12:25

Написание таблицы совершенно неактуально - делал, чтобы была рабочая версия. Единственное изменение заключалось в удалении onclick

mplungjan 10.09.2018 12:37

Вау, да, ты прав. Проблема заключалась в том, что я поместил <script src> слишком высоко на странице: мне пришлось поместить его в {% block content%} с таблицей. Блин, спасибо за ваше время, извините за то, что возился с ложными проблемами.

AlexMdg 10.09.2018 13:47

В качестве альтернативы поставьте $(function() { $(".available").on("click",function() { $(this).toggleClass("available unavailable"); }); }); в любом месте страницы

mplungjan 10.09.2018 14:28

Удалите onclick=deliveryBooking() и используйте этот код.

$('#this_week').on('click', '.available, .unavailable', function(){
    $(this).toggleClass('available unavailable')
})

В этом коде используется делегирование мероприятия. Пожалуйста, прочтите jQuery API, если вам нужно понять больше. .on / .toggleClass

Кстати, я думаю, что ваша разметка, вероятно, неверна. <th> используется для заголовков таблиц, а <td> - для ячеек, содержащих фактические данные. Я думаю, что весь <th> в вашем цикле for нужно заменить на <td>, кроме первого.

Нет необходимости в делегировании, поскольку таблица создается до скрипта. См. Мое решение для более простой версии

mplungjan 10.09.2018 12:51

Ты прав. В этом случае нет необходимости в делегировании. Но у меня уже есть предпочтительная привязка к родительскому элементу, а не к 10 отдельным элементам. Но только сейчас я прочитал этот делегат экономит CPU при привязке обработчиков событий; bind экономит CPU при срабатывании событий, который на самом деле имеет большой смысл. Итак, да, любой, кто это читает, см. Ответ @ mplungjan. Я оставлю это здесь для тех, у кого такая же дилемма связывания / делегирования и для td / th проблемы.

rmn 10.09.2018 12:58

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

mplungjan 10.09.2018 13:08

@mplungjan Верно, поэтому ваш код более элегантен. Это работает, потому что они являются настоящими привязками к элементам DOM независимо от изменений класса / идентификатора / атрибута. Хотя эти делегаты похожи на косвенные привязки, исходный селектор больше не соответствует и перестает работать. т.е. делегаты подобны символическим ссылкам привязок событий: p

rmn 10.09.2018 13:35

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

AlexMdg 10.09.2018 13:49

Другие вопросы по теме