Почему я не могу нажимать на ссылки на мобильном устройстве?

Я занимаюсь разработкой сайта ( http://www.saulesinterjerai.lt/). Теперь все работает, за исключением того, что на мобильном устройстве ссылки не кликабельны, а переходят на другие слои.

Как отключить это поведение из кода? (не в браузере)

Код, который я написал, находится здесь, однако некоторые части кода, которые я скопировал из Интернета (все находится в папке "dep", если вы знаете, как использовать инструменты dev). Я также подозреваю, что это может быть проблема с pjax или запатентованный "масштабируемый" модуль, но я не могу найти, почему..:

var pjax = new Pjax({ selectors: ["head title", "body"] })
var Site;

var attach_menu_control = function() {
  var $sidebar = document.querySelector('.sidebar')
  var $sidebar_content = $sidebar.querySelector('.content')
  var $menu_opener = $sidebar.querySelector('.menu-closed')

  var hide_menu = function() {
    $sidebar_content.style.display = 'none'
    $menu_opener.style.display = 'block'
    $sidebar.style.width = '40px'
  }

  var show_menu = function() {
    $sidebar_content.style.display = 'block'
    $menu_opener.style.display = 'none'
    $sidebar.style.width = '270px'
  }

  var click_handler = function(e){
    // e.preventDefault()
    var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
    if ($sidebar_content.style.display == 'none') {
      show_menu()
    } else if (width <= 724) {
      hide_menu()
    }
  }

  if ( !is_touch_device() ) $sidebar.addEventListener('click', click_handler)
  $sidebar.addEventListener('touchend', click_handler)
  var event = new Event('click');
  $sidebar.dispatchEvent(event)
}
attach_menu_control()

document.addEventListener('DOMContentLoaded', reloadCarbon)
document.addEventListener('pjax:complete', reloadCarbon)
document.addEventListener('pjax:send', resetCarbon)

// Animations

document.addEventListener('pjax:send', function(){
  var $main = document.querySelector('main')
  $main.style.opacity = 0
})

document.addEventListener('pjax:complete', function(){
  var $main = document.querySelector('main')
  $main.style.visibility = 'hidden'
  $main.style.opacity = 0
  setTimeout(function(){
    document.querySelector('main').style.visibility = 'visible'
    document.querySelector('main').style.opacity = 1
    attach_menu_control()
  }, 10)
})

function hasClass(element, cls) {
    return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1;
}

function is_touch_device() {
  return 'ontouchstart' in window        // works on most browsers 
      || navigator.maxTouchPoints;       // works on IE10/11 and Surface
}

CSS:

    .menu-closed {
        font-size: 30px;
      position: absolute;
      writing-mode: vertical-lr;
      top: 50%;
      padding-left: 14px;
      cursor: pointer;
    }

    .sidebar {
        transition: width 0.2s;
        overflow-x: hidden;
        z-index: 10000;
        backface-visibility: hidden;
    }

    .sidebar .content {
        width: 270px;
    }


    @media only screen and (max-width: 724px) {
        .sidebar {
            background-color: rgba(245, 245, 245, 0.87);
        }

        .sidebar h1 {
            font-size: 36px;
        }

        .sidebar header h2 {
            font-size: 28px;
        }

        .language {
            font-size: 16px;
        }

        .sidebar nav > ul > li {
            line-height: 36px;
        }

        .sidebar nav > ul.siteLinks a, 
        .sidebar nav > ul > li > a {
            font-size: 36px;
            line-height: 36px;
        }

        main {
            padding-left: 40px;
        }

        /* Force sideback to be in closed mode when new page is opened */
        .sidebar {
            width: 40px;
        }

        .sidebar .content {
            display: none;
        }
    }

    /* Emulate fixed positionin */

    html {
        position: absolute;
        height: 100%;
        width: 100%;
        overflow: hidden;
    }

    body {
        height: 100%;
        overflow: auto;
    }

    .fixed {
        position: absolute;
    }

1 ответ

Решение

Я думаю, что это связано с этой функцией, которая вызывается:

 var click_handler = function(e){
    e.preventDefault()
    var width = (window.innerWidth > 0) ? window.innerWidth : screen.width;
    if ($sidebar_content.style.display == 'none') {
      show_menu()
    } else if (width <= 724) {
      hide_menu()
    }
  }

e.preventDefault() запрещает браузеру выполнять действия по умолчанию, здесь: для переключения страниц и перехода по URL-адресу в ссылке.

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

Это было подчеркнуто предупреждениями консоли Chrome:

Ignored attempt to cancel a touchend event with cancelable=false, for example because scrolling is in progress and cannot be interrupted.
click_handler @ app.js:34

РЕДАКТИРОВАТЬ

Я вижу много обработчиков, прикрепленных к вашим элементам, и я не понимаю роли каждого из них (например, я не знаю pjax lib), я думаю, что каждый ответственен за потерю ожидаемого поведения. На вашем месте, возможно, я бы попытался упростить систему и переписать систему меню и ее интеграцию на веб-странице.

Если вы не можете (или не хотите) реорганизовать страницу, возможно, не пытайтесь ее исправить, а попробуйте обходной путь.

Я хотел бы добавить прозрачный серый фон, когда меню открыто, чтобы показать пользователю, что остальная часть экрана отключена (или полностью прозрачна, и когда пользователь щелкает / нажимает на него, он закрывает меню, чтобы вернуться к основное содержание). Когда меню открыто, вы устанавливаете на основном контенте следующее css:

pointer-events: none

Это будет препятствовать тому, чтобы изображения / контент под меню принимали события, и только меню должно получать события щелчка / касания. Надеюсь это поможет!

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