Форум АНТИЧАТ

Форум АНТИЧАТ (https://forum.antichat.xyz/index.php)
-   PHP, PERL, MySQL, JavaScript (https://forum.antichat.xyz/forumdisplay.php?f=37)
-   -   ATS - движок для сайта на javascript =) (https://forum.antichat.xyz/showthread.php?t=73521)

Дикс 12.06.2008 14:09

ATS - движок для сайта на javascript =)
 
писал из спортивного интереса, но очень хочу найти и исправить все косяки, чтобы можно было использовать, поэтому выкладываю чтобы потестили.

онлайн-версия здесь: http://litprom.890m.com/ast/

сорцы здесь: http://up.giga.su/738058803/ (6.35 кб)

Назначение:
создание в максимально сжатые сроки статичного сайта с удобной поддержкой и расширением.
Альтернатива серверным модульным движкам, SSI, dreamweaver templates.

Суть проекта:
На страницу цепляется основной скрипт.
Появляется возможность создавать простые ссылки, которые заполняют контент страницы содержимым файлов, лежащих на сервере в текстовом формате.

Дикс 12.06.2008 15:26

я вот че думаю - можно сделать кэширование текстов - сохраняя их в переменные, а затем проверяя их наличие.
как вы считаете - стоит?

DIAgen 12.06.2008 15:32

Цитата:

Сообщение от Дикс
я вот че думаю - можно сделать кэширование текстов - сохраняя их в переменные, а затем проверяя их наличие.
как вы считаете - стоит?

Попробуй это использовать
http://forum.antichat.ru/thread72316.html

astrologer 12.06.2008 20:05

  1. В функции «ajax» логика получения экземпляра XMLHttpRequest воспроизводится каждый раз.
  2. В переменной contentDiv можно сохранить готовую ссылку на объект ( который <div id="corpse" /> ) вместо строки "corpse".
  3. Имеет смысл навешивать обработчики событий в js коде, а не в html.
  4. Чтобы свести к минимуму вероятность перезаписи переменных, можно создать объект, например, «AST» и хранить их там:
    Код:

    var AST =
    {
      folder: 'pages/',
      ext: 'txt',
      load: function(){ /* код */ }
    };

  5. corpse
Цитата:

Сообщение от Дикс
я вот че думаю - можно сделать кэширование текстов - сохраняя их в переменные, а затем проверяя их наличие.
как вы считаете - стоит?

По-моему, нет.

Дикс 12.06.2008 21:22

1, 2 - сделал

Цитата:

3. Имеет смысл навешивать обработчики событий в js коде, а не в html.
не совсем понял.
если у меня будет меню из одних спанов, без онклика и вызова функции,
как я тогда укажу - какой пункт меню, какую страницу открывает?

4 - буду учиться работать с массивами и тоже реализую

5 - ясно. может попробую вот эти способы:
http://forum.antichat.ru/thread72316.html

а ты можешь привести доводы, почему кешировать не стоит?

ПС я знаю что corpse - 'труп'.
это мой маленький кулинарный изыск :)

astrologer 12.06.2008 23:09

Цитата:

а ты можешь привести доводы, почему кешировать не стоит?
Потому, что браузер кэширует страницы самостоятельно, в том числе те, которые получены "Ajax'ом". Воспроизводить эту логику на JS - задача нетривиальная, если подойти к задаче серьёзно.

lazy-реализация первого пункта. Несколько объёмно:
Код:

function XHR()
{
  var ms =
  [
    'Microsoft.XMLHTTP',
    'MSXML2.XMLHTTP',
    'MSXML2.XMLHTTP.3.0',
    'MSXML2.XMLHTTP.4.0',
    'MSXML2.XMLHTTP.5.0'
  ], i = ms.length, nop = function(){};
 
  if(window.XMLHttpRequest)
  {
    return (XHR = function()
    {
      return new XMLHttpRequest();
    })();
  }
  else if(window.ActiveXObject)
  {
    while(i--)
    {
      try
      {
        return (XHR = function()
        {
          return new ActiveXObject(ms[i]);
        })();
      } catch(e) {}
    }
  }
 
  return (XHR = function(){
    return {
      open: nop,
      send: function()
      {
        this.onreadystatechange();
      },
      readyState: 4,
      onreadystatechange: nop,
      responseText: 'XMLHttpRequest instantiation error'
    };
  })();
};

Цитата:

не совсем понял.
если у меня будет меню из одних спанов, без онклика и вызова функции,
как я тогда укажу - какой пункт меню, какую страницу открывает?
Меню обычно делается как список ссылок. Обработчик навешивается на родительский элемент. При щелчке на ссылке, если не работает js - происходит простой переход по ссылке. Если работает - js отменяет переход и подгружает данные. Техника довольно распространённая, называется event delegation.
Вот пример, не затрагивающий уже существующую разметку:
Код:

function init()
{
  /* ... */
 
  var m = document.getElementById('menu'),
  s = m.getElementsByTagName('span'),
     
  m.addEventListener('click', function(e)
  {
    var name = '';
    switch(e.target || e.srcElement)
    {
      case s[0]:
        name = 'home';
        break;
      case s[1]:
        name = 'installation';
        break;
      case s[2]:
        name = 'contacts';
        break;
      case s[3]:
        name = 'license';
        break;
      default: return true;
    }
   
    loadPage(name);
    (e.preventDefault || function(){ e.returnValue = false; })();
    return false;
  }, false);
};

Можно вместо конструкции switch использовать объект-хеш, в качестве ключей - текст пунктов меню.
P.S. для IE - attachEvent вместо addEventListener.

Дикс 21.06.2008 09:26

почти со всем справился, но вот этот код не отменяет перехода по ссылке ни в одном браузере:

Цитата:

(e.preventDefault || function(){ e.returnValue = false; })();
return false;
просто e.preventDefault () хорошо отменяет переход в ФФ и опере, а в ИЕ6 не работает.
как в ИЕ убить переход?
я повесил обработчик на теги A.

astrologer 21.06.2008 09:59

Цитата:

Сообщение от Дикс
почти со всем справился, но вот этот код не отменяет перехода по ссылке ни в одном браузере:



просто e.preventDefault () хорошо отменяет переход в ФФ и опере, а в ИЕ6 не работает.
как в ИЕ убить переход?
я повесил обработчик на теги A.

Это я перемудрил :)
Код:

if(e.preventDefault)
{
  e.preventDefault();
}
else
{
  e.returnValue = false;
}
return false;


Дикс 21.06.2008 10:30

http://up.giga.su/713746505/
вот сорцы
ИЕ на этот код ваще не реагирует

astrologer 21.06.2008 13:29

В IE события, вопреки стандарту, называются не 'click' или 'keyup', а 'onclick', 'onkeyup' и т.д.
В результате:
Код:

attachEvent('onclick', function(e){/*...*/});
Также [ Element ].attachEvent принимает только два параметра. Третий - булево значение - игнорируется.
Далее.
Функция attachEvent переписывает нативную в IE функцию window.attachEvent. Это не плохо, но нежелательно.

Код:

try          {window.xmlHttp=new XMLHttpRequest();}
  catch (e){ try{window.xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");}
  catch (e){ try{window.xmlHttp=new ActiveXObject("MSXML2.XMLHTTP");}
  catch (e){ try{window.xmlHttp=new ActiveXObject("MSXML2.XMLHTTP.3.0");}
  catch (e){ try{window.xmlHttp=new ActiveXObject("MSXML2.XMLHTTP.4.0");}
  catch (e){ try{window.xmlHttp=new ActiveXObject("MSXML2.XMLHTTP.5.0");}
  catch (e){return false;}}}}}}

Ааааа!

[Raz0r] 21.06.2008 14:46

Как вариант для attachEvent и addEventListener:
Код:

<a id=aid href=#>Click me!</a>
<script>
Array.prototype.append = function(obj, nodup) {
        if(!(nodup && this.contains(obj))) {
                this[this.length] = obj;
        }
}

EventRouter = function(el, eventType) {
        this.lsnrs = new Array();
        this.el = el;
        el.eventRouter = this;
        el[eventType] = EventRouter.callback;
}

EventRouter.prototype.addListener = function(lsnr) {
        this.lsnrs.append(lsnr);
}

EventRouter.prototype.notify = function(e) {
        var lsnrs = this.lsnrs;
        for(var i=0; i < lsnrs.length; i++) {
                var lsnr=lsnrs[i];
                lsnr.call(this, e);
        }
}

EventRouter.callback = function(event) {
        var e = event || window.event;
        var router = this.eventRouter;
        router.notify(e);
}
var aid = document.getElementById("aid");
var ev = new EventRouter(aid, "onclick");
ev.addListener(function(){alert("Click!");});
</script>


Дикс 21.06.2008 19:06

astrologer
событие исправил на onclick, спасибо
третий параметр уже убрал
аттачевент уже переименовал

ща имеем такой код:

PHP код:

if ((navigator.userAgent.indexOf('MSIE') != -1)
 && (
navigator.userAgent.indexOf('Win') != -1))
    
AST.menuId.attachEvent('onclick'addEvent);
else
    
AST.menuId.addEventListener('click', function(e){addEvent(e)}, false); 

PHP код:

function addEvent(e){
alert('ХУЙ');
 
AST.trgt = (e.target || e.srcElement);

    for(
i=0iAST.links.lengthi++)
        if(
AST.trgt == AST.links[i])
             
loadPage(AST.links[i].valueOf());

if(
e.preventDefault)
  
e.preventDefault();

e.returnValue false;

return  
false;


он отлично работает в опере, фф, сафари (для винды), но не работает в ие! орёт матерное слово и перебрасывает прямиком на блокнот

может проблема в том, что всё вынесено в отдельный скрипт?

ПС
Цитата:

Ааааа!
че? )))

Дикс 21.06.2008 20:24

вот снова залил сорцы (6 кб)
http://up.giga.su/643686467/

я там создал функцию тест.
она по сути дублирует функцию loadPage.

вот что она должна делать:
- создать пустой див (ок)
- очистить контейнер, куда будет помещаться контент новой страницы (ок)
- аяксом подгрузить новый контент
- приаттачить его к контейнеру

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

теперь осталось получить новые данные.

если раскомментировать строку - то ИЕ просто перейдёт по ссылке на текстовый файл. т.е. функция перестаёт работать.

Тем не менее в функции init() есть строки загружающие страницу по умолчанию.
они также используют loadPage(), ajax(), но у них всё работает нормально.
если поставить алерты - то видно, что аякс получает тело страницы.

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

добьём эту шнягу! чуток осталось :)

я вот тут ещё писал:
http://forum.ixbt.com/topic.cgi?id=26:38394
но там не особо почерпнул пока

astrologer 21.06.2008 22:42

Для начала:
Код:

function(msg){ alert(msg) } // это то же самое, что и просто alert
Далее. Заменяем это:
Код:

// ajaxTest("GET", e.srcElement.valueOf(), function(msg){ alert(msg) });
на это:
Код:

if(e.srcElement.href) ajax("GET", e.srcElement.href, alert);
Условие необходимо, поскольку объект, по которому щёлкнули, может быть любым из блока menu и самим menu в том числе. Вторым параметром функции, в принципе, можно передать и саму ссылку ( [ HTMLAnchorElement ] ).

А теперь немного уличной магии. В коде функции ajax:
Код:

function ajax(method, url, userFunc) {

window.xmlHttp.onreadystatechange=function() {
        if(window.xmlHttp.readyState==4)
                userFunc(window.xmlHttp.responseText);
}

window.xmlHttp.open(method,url,true);
window.xmlHttp.send(null);
}

нужно поменять местами определение [ object XMLHttpRequest ].onreadystatechange и вызов метода open()

P.S. Все рекомендации основаны на следующем правиле: переписывать код полностью нельзя.

asser 22.06.2008 00:08

А может туда какую-нить маленькую админку добавить стоит?!Руками конечно не впадлу, но тем не менее))

Дикс 22.06.2008 08:08

ур-ра-а!!
вот где оказываеца была зарыта эта побитая дождями сцобака!
теперь везде работает стабильно.

astrologer
жму руку! спасибо

Цитата:

P.S. Все рекомендации основаны на следующем правиле: переписывать код полностью нельзя.
а вот это не понял. поясни? :)

asser
какую админку? чтобы изменять меню? для этого нужны скрипты на сервере.
а это уже совершенно другая история..

Дикс 22.06.2008 08:13

Так. осталось выяснить, чем неугоден следующий код?
PHP код:

// new XHR
  
try           {window.xmlHttp=new XMLHttpRequest();}
  catch (
e){ try{window.xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");}
  catch (
e){ try{window.xmlHttp=new ActiveXObject("MSXML2.XMLHTTP");}
  catch (
e){ try{window.xmlHttp=new ActiveXObject("MSXML2.XMLHTTP.3.0");}
  catch (
e){ try{window.xmlHttp=new ActiveXObject("MSXML2.XMLHTTP.4.0");}
  catch (
e){ try{window.xmlHttp=new ActiveXObject("MSXML2.XMLHTTP.5.0");}
  catch (
e){return false;}}}}}} 

его можно как-то улучшить?


Время: 23:45