Discourse Sign Up перенаправление на URL вместо модального

1

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

Я пытаюсь через панель администратора в настройке Edit Html/css специально в разделе </head>, я также попытался поместить это в </body>

По какой-то причине этот код не останавливает действие по умолчанию или перенаправляет пользователя на клик

<script>
    var thingy = document.getElementsByClassName("sign-up-button")
    thingy.onclick ="return false;"
    thingy.onclick = function() {
        window.location.href = "https://join.domain.com";
    };
</script>

Когда я пытаюсь это сделать

<script>
    var thingy = document.getElementsByClassName("sign-up-button");
    console.log(thingy.length);
    console.log(thingy)
    for (var i = 0; i < thingy.length; i++) {
            console.log('print this');
    };
</script>

Он показывает длину thingy как 0, но затем он обрабатывает html-элемент, но никогда не выполняет итерацию, так как длина равна 0

Теги:
discourse

2 ответа

1
Лучший ответ

Проблема заключается в том, что Discourse использует Ember. С Ember ничего не стоит в качестве клиентской платформы, но, похоже, это добавление элементов в DOM после запуска вашего скрипта. Когда элемент добавляется после того, как ваш скрипт пытается добавить прослушиватель событий, ваш скрипт не будет делать много (как вы обнаружили).

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

Одна тактика заключается в том, чтобы сделать что-то, чтобы задержать ваш скрипт - например, async defer, requestAnimationFrame или setTimeout - чтобы этот элемент уже был вокруг, когда запускается ваш скрипт. Поскольку у меня нет отдельной страницы для тестирования, я не могу прокомментировать это.

Я собираюсь продемонстрировать, как присоединить обработчик событий, когда элемент добавлен в DOM. В старые времена вы использовали бы события мутации, как показано в большинстве ответов на этот вопрос. Поскольку эти события теперь устарели, вы должны использовать Mutation Observers (которые, как представляется, довольно хорошо поддерживаются).

MutationObserver.observe() имеет два аргумента: целевой элемент и объект опций. Целевой элемент - это элемент, в котором вы слушаете события мутации. Из использования источника просмотра на странице кажется, что с самого начала не так много полезного в body, поэтому мы уйдем с body. Что касается объекта options, нас интересуют мутации childList и subtree поскольку кнопка не является прямым потомком body.

Функция обратного вызова (только аргумент конструктора) будет срабатывать всякий раз, когда происходят события. Это тот момент, когда вы должны искать кнопку и присоединить обработчик события клика. Чтобы все было в порядке, вы можете проверить, действительно ли кнопка на самом деле, и отключить MutationObserver, если она есть. Не нужно продолжать прикреплять событие.

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

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

Вы также упомянули в комментарии что-то о том, что модальность все еще появляется после того, как вы подключили слушателя. Вы можете остановить это с помощью .stopPropagation().

Кстати, эта пропаганда несколько связана с тем, почему вы не могли сделать простую $(window).on('click', '.sign-up-button',...). Это работает для большинства динамически создаваемых элементов, но в этом случае основное приложение также прослушивает события щелчка и, по-видимому, останавливает событие от пузыря.

Мой код ниже. Я использую jQuery, потому что видел, что он присутствует на страницах Discourse.

var targetNode = $('body')[0];

var attachEvent = function () {
  var $button = $('.sign-up-button');

  $button.on('click', function (e) {
    e.stopPropagation();

    // Do the redirect here
    console.log('gotcha');
  });

  if ($button.length) {
    console.log('hit');
    observer.disconnect();
  }
};

var callback = function() {
  console.log('mutation');
  attachEvent();
};

var observer = new MutationObserver(callback);

observer.observe(targetNode, { childList: true, subtree: true });

// Just in case...
attachEvent();
  • 0
    Кажется, это работает, только если он загружен из внешнего файла.
1

getElementsByClassName извлекает набор из нуля для многих объектов. Вы захотите выбрать один, перебрать их или использовать jQuery.

Это работает, если вы хотите только вернуть первую кнопку. (thingy [0].)

<script>
    var thingy = document.getElementsByClassName("sign-up-button")
    //thingy.onclick ="return false;"
    thingy[0].onclick = function() {
        window.location.href = "https://www.google.com";
        //return false;
    };

</script>

"Return false" не требуется, поскольку вы заменяете событие onclick.

Лучший вариант - дать кнопке идентификатор, а затем использовать getElementById для его получения.

  • 0
    Что касается второго блока скрипта, он работает нормально для меня и возвращает 1, <HtmlCollection length = "1"> ... </ HtmlCollection> и «print this». Какой браузер вы используете?
  • 0
    Это не работает, когда развернуто в дискурсе. По какой-то причине модал все еще появляется, не уверен, что это что-то с тем, что ember перекрывает действие? Длина показывает 0, и консоль возвращает TypeError: thingy[0] is undefined
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню