Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > Отлов анкерных переходов


Автор: Cheba 28.1.2006, 17:41
Как можно отследить переход по анкерам (ссылкам внутри документа)?
Я имею в виду переходы с http://example.com/doc.html#anchor1 на http://example.com/doc.html#anchor2
Отлов кликов по ссылкам не предлагать. Это "самое простое решение" имеет громадную кучу недостатков.
Надо отлавливать не только переходы по ссылкам, но и по back/next, и по ручному воду адреса, и по переходу из истории или закладки. В общем, все возможные виды таких переходов.
Вся проблема состоит в том, что такие переходы не порождают событий типа load или unload...

Автор: Sardar 28.1.2006, 18:13
В заголовке документа пропиши:

if(location.hash != '') ....

location.hash содержит якорь.

Автор: Cheba 28.1.2006, 18:40
Где лежит якорь я знаю. Но мне надо обрабатывать переходы между якорями. Я не хочу постоянно опрашивать содержимое якоря - это очень напрягает. Я хочу получать уведомление в момент смены якоря.

Автор: Ciber SLasH 28.1.2006, 20:26
Код

<html>
<head>
<meta http-equiv="Content-Type" content='text/html; charset=windows-1251'>
<script type='text/javascript'>
if (location.hash != '') {
    alert('Страница загружена с якорем: ' + location.hash);
}
function init() {
var list = document.getElementsByTagName('A');
    for (var i = 0; i < list.length; i++) {
        var a = list[i];
        if (a.addEventListener) {
            a.addEventListener('click', filter, false);
        } else if (a.attachEvent) {
            a.attachEvent('onclick', filter);
        }
    }
}

function filter(ev) {
var evt = ev || window.event;
var a = (evt.srcElement) ? evt.srcElement : evt.target;
    if (a.href.indexOf('#') != -1) {
        alert( 'Ссылка с якорем: ' + a.href.substr(a.href.indexOf('#')) );
    }
return false;
}

window.onload = init;
</script>
</head>

<body>
<a href='#bottom'>Перейти вниз</a>
<br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br><br>
<a name="bottom"></a><br>
</body>
</html>

Автор: Cheba 28.1.2006, 21:37
Ну, и? Вот ежели я руками сбацаю в адресной строке анкер оно мне покажет его? Не покажет. А ежели я из букмарков перейду? тоже не покажет. А если по кнопке Back? Тоже не покажет. А меня интересуют как-раз эти случаи.

Автор: Sardar 28.1.2006, 23:56
Цитата(Cheba @ 28.1.2006, 17:40 Найти цитируемый пост)
Но мне надо обрабатывать переходы между якорями. Я не хочу постоянно опрашивать содержимое якоря - это очень напрягает.

Скажи мне как это тебя напрягает? Что бы узнать смену состояния нужно это состояние проверять, можно самому, можно железом (прерывания), но мы отклонились. Что есть обрабатывать переходы между якорями?

Разьясняю что подсказал я: загружаеться страница, ты читаешь якорь, если он изменился (следовательно хранишь ты его либо в куках, либо на сервере), то выполняешь что хочешь.

Дай больше инфы что ты делаешь, бдует менее пугающее решение.

Автор: Ciber SLasH 29.1.2006, 00:19
Можно ещё на window.onscroll повесить проверку location.hash

Автор: Cheba 29.1.2006, 01:39
Делаю AJAX сайт. Хоче чтобы у него была нормальная (привычная) обработка кнопок Вперед/Назад. Хочу чтобы нормально можно было букмарки создавать. Хочу чтобы история сохранялась. Для этого надо как-то модифицировать УРЛ, бо именно по нему идентифицируются "места, где побывал". Чтобы не перезагружалась страница можно менятьтолько хешевую часть УРЛа.
Далее. Подставлять хеши умею. Они сохраняются в истории и кнопки вперед-назад и букмарки начинают работать как надо. По онлоаду из хеша достаю состояние приложения и все прекрасно. Возникает следующая проблема когда УРЛы отличаются только хешами не происходит событие load (вернее в ИЕ оно происходит, а в Лисе - нет). Вот мне и надо отлавливать момент перехода между такими УРЛами, где только хеши рознятся.

В ИЕ можно вешать листенеры на хитрое событие onpropertychange.
Код
if (IE)
    if ("onpropertychange" in document && "attachEvent" in document) {
        document.attachEvent("onpropertychange", function () {
            if (event.propertyName == "location") {
                d(document.location.hash);
            }
        });
    }

Однако, у меня это свойстко почему-то никогда не меняется. Может, я не туда вешаю?

Но зато в ИЕ load происходит (хотя и не понятно почему) - тут, вроде проблем нет.

Для Лисы думал сделать следующее. Подменить геттер и сеттер для document.location.hash. Но там вылезает ошибка - redeclaration of getter hash.

Кому интересно, вот кусочек (нерабочего) кода для подмены геттеров и сеттеров.
Код
if (Mozilla)
{
    document.location._hash = document.hash;
    
    document.location.__defineGetter__('hash', function() {return document.location._hash});
    document.location.__defineSetter__('hash', function(newHash){
        if (newHash != document.location._hash)
            if (document.location.onHashChanged)
            {
                if (document.location.onHashChanged(newHash) !== false)
                    document.location._hash = newHash;
            }
            else
            {
                document.location._hash = newHash;
            }
        });

    document.location.onHashChanged = function(hash)
        {
            d(hash);
        }
}

Собственно, далее __defineGetter__ дело не идет из-за ошибки.

Вот такие вот идеи для реализации того, что в обчных условиях давно уже работает.

Автор: 12345c 31.1.2006, 03:40
Кстати, я попробовал половить переходы в IE между анкерами по onload - тоже не ловит. Ходил по локальным файлам, а не через веб-сервер, может в этом дело, отчего onload не срабатывало?

А знание переходов нужно же не сразу по переходу, а в какой-то процедуре? Поэтому анализ history и history.length в нужном месте мог бы дать кое-что.

Автор: Onis 2.6.2009, 22:45
Cheba, 
У меня такая же проблема. Вы нашли способ её решения?

Автор: Onis 3.6.2009, 17:28
Если кто-то знает решение проблемы без использования jquery и другой ереси, буду очень благодарен.

Автор: Nechto 9.1.2010, 12:06
У меня тоже такая же проблема. И она каким то способом решатся через iframe. Я в этом направлении напрягаюсь! кому интересно давайте вместе дробить эту тему!

в файле исходиники gmail они решили эту проблему!


Автор: Се ля ви 3.2.2010, 17:47
Цитата(Cheba @  29.1.2006,  01:39 Найти цитируемый пост)
Но зато в ИЕ load происходит (хотя и не понятно почему) - тут, вроде проблем нет.


Цитата(12345c @  31.1.2006,  03:40 Найти цитируемый пост)
Кстати, я попробовал половить переходы в IE между анкерами по onload - тоже не ловит. Ходил по локальным файлам, а не через веб-сервер, может в этом дело, отчего onload не срабатывало?

Народ, а может, в версии IE проблемко?..

Автор: Dubrov 6.6.2010, 00:42
Да, проблема действиетельно актуальная, я выкрутился установкой обработчика onclick всем ссылкам:

Код

        $("a").click(function(){
            location = $(this).attr("href");
            processLocation();
        });



А в функции processLocation(); обработка урла
ЗЫ, можно конечно и без ЖКвери обойтись, если кому он не симпатизирует.

Автор: ksnk 6.6.2010, 09:13
Dubrov, а кнопки "назад-вперед" броузера тоже ловишь?

Автор: ex3c 6.6.2010, 09:35
Есть такой вариант:

Код

function onHashChange(handler) {
    var current = location.hash;
    setInterval(function () {
        if (location.hash != current) {
            current = location.hash;
            handler();
        }
    },
    100);
}


Ловит

Цитата

переходы по ссылкам, но и по back/next, и по ручному воду адреса, и по переходу из истории или закладки

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)