За последние 24 часа нас посетили 17500 программистов и 1713 роботов. Сейчас ищет 1561 программист ...

Система голосования на AJAX (+/-)

Тема в разделе "JavaScript и AJAX", создана пользователем Vantedur, 9 июл 2010.

  1. phpdude

    phpdude Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    697
    Симпатии:
    0
    Vantedur
    20 часов :D

    это же надо подписывать, это же песня, ее надо слушать, а не читать!
     
  2. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
    =) уже 40 за плечами, нервы сдают.
     
  3. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    свою песню быстрее написать, пусть и не такую гибкую =)
     
  4. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
    ну не знаю, мне кажется что человеку который реально хорошо знает JS и тд, будет очень легко такой скрипт вставить куда угодно, исполнен отличным мастером который как профессор раскрывал инсайд тему скрипта. прекрасно осознавая что кто-то потом еще будет его читать и возможно многое оттуда узнает.

    Однако у скрипта не хватает нескольких компонентов, а именно обработки и бд =)
     
  5. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    это про скрипт с лепры или про звезды?
     
  6. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
    у скрипта со звездами не одной строки не подписано =)
     
  7. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
  8. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
    Vantedur
    начните лучше писать свой, если что не будет получаться, то сюда с вопросами...
     
  9. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
    Да я уже попытался свою написать, видать не давно.

    я хочу попробывать лепровский освоить =)

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

    лучше давайте попробуем вместе раскрыть тему голосовалки лепры
     
  10. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
    Появился первый вопрос, WTF?

    <script type="text/javascript">
    mythingsHandler.wtf = '25818f734a3eb6d259cc4ed92675ffc4';
    </script>
     
  11. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
    вроде обкарнал лепровский код, осталось
    <script src="http://vtrigazety.ru/golosovanie/common.js?rev=127" type="text/javascript" charset="UTF-8"></script>
    <script src="http://vtrigazety.ru/golosovanie/voting.js?rev=121" type="text/javascript" charset="UTF-8"></script>

    не могу понять что за запрос такой посылает код с скрипту что ответом идет "нет такого действия"

    PHP:
    1. <?php
    2. define('INCLUDE_CHECK',true);
    3. require 'connect.php';
    4.     if ($_GET['value']=='-1'){
    5.     $safe_topic=mysql_escape_string($_POST['moto_cutnum']);
    6.     $sSQL="UPDATE blogposts SET
    7.     ball= ball -1 WHERE id=".$_GET['id'];
    8.     mysql_query($sSQL) or die(mysql_error());
    9.     }
    10.     elseif ($_GET['value']=='1'){
    11.     $safe_topic=mysql_escape_string($_POST['moto_cutnum']);
    12.     $sSQL="UPDATE blogposts SET
    13.     ball= ball +1 WHERE id=".$_GET['id'];
    14.     mysql_query($sSQL) or die(mysql_error());
    15.     }
    16.     else {
    17.         echo "нет такого действия";
    18. }
    19.    
    20. ?>
    21.  
    из подгруженный скриптов
    common
    [js]/*****************************
    ** Misc functions
    ******************************/
    function $(id){
    return document.getElementById(id);
    }
    function addStyleProperties(cssStr){
    var head = document.getElementsByTagName('head')[0];
    var styleSheets = head.getElementsByTagName('style');
    var styleSheet = null;
    if (styleSheets.length){
    styleSheet = styleSheets[styleSheets.length-1];
    } else {
    styleSheet = document.createElement("style");
    styleSheet.setAttribute("type", "text/css");
    head.appendChild(styleSheet);
    }

    if(styleSheet.styleSheet){ // IE
    styleSheet.styleSheet.cssText += cssStr;
    } else { // w3c
    styleSheet.appendChild(document.createTextNode(cssStr));
    }
    }
    /*****************************
    ** Event listeners
    ******************************/

    function checkEvent(oEvt){
    oEvt=(oEvt) ? oEvt : ( (window.event) ? window.event : null );
    if(oEvt && oEvt.srcElement && !window.opera)
    oEvt.target=oEvt.srcElement;
    return oEvt;
    }

    function addEvent(objElement, strEventType, ptrEventFunc) {
    if (objElement.addEventListener)
    objElement.addEventListener(strEventType, ptrEventFunc, false);
    else if (objElement.attachEvent)
    objElement.attachEvent('on' + strEventType, ptrEventFunc);
    }

    function removeEvent(objElement, strEventType, ptrEventFunc) {
    if (objElement.removeEventListener) objElement.removeEventListener(strEventType, ptrEventFunc, false);
    else if (objElement.detachEvent) objElement.detachEvent('on' + strEventType, ptrEventFunc);
    }

    /*****************************
    ** Common class methods
    ******************************/

    function switchClass( objNode, strCurrClass, strNewClass ) {
    if ( matchClass( objNode, strNewClass ) ) replaceClass( objNode, strCurrClass, strNewClass );
    else replaceClass( objNode, strNewClass, strCurrClass );
    }

    function removeClass( objNode, strCurrClass ) {
    replaceClass( objNode, '', strCurrClass );
    }

    function addClass( objNode, strNewClass ) {
    replaceClass( objNode, strNewClass, '' );
    }

    function replaceClass( objNode, strNewClass, strCurrClass ) {
    var strOldClass = strNewClass;
    if ( strCurrClass && strCurrClass.length ){
    strCurrClass = strCurrClass.replace( /\s+(\S)/g, '|$1' );
    if ( strOldClass.length ) strOldClass += '|';
    strOldClass += strCurrClass;
    }
    objNode.className = objNode.className.replace( new RegExp('(^|\\s+)(' + strOldClass + ')($|\\s+)', 'g'), '$1' );
    objNode.className += ( (objNode.className.length)? ' ' : '' ) + strNewClass;
    }

    function matchClass( objNode, strCurrClass ) {
    return ( objNode && objNode.className.length && objNode.className.match( new RegExp('(^|\\s+)(' + strCurrClass + ')($|\\s+)') ) );
    }

    function getAncestorByClassName( oCurrentElement, sClassName, sTagName ) {
    var oCurrent = oCurrentElement.parentNode;
    while ( oCurrent.parentNode ) {
    if ( matchClass( oCurrent, sClassName ) && ( !sTagName || oCurrent.tagName.toLowerCase() == sTagName.toLowerCase() ) ) return oCurrent;
    oCurrent = oCurrent.parentNode;
    }
    }

    function getElementsByClassName(objParentNode, strNodeName, strClassName){
    var nodes = objParentNode.getElementsByTagName(strNodeName);
    if(!strClassName){
    return nodes;
    }
    var nodesWithClassName = [];
    for(var i=0; i<nodes.length; i++){
    if(matchClass( nodes, strClassName )){
    //nodesWithClassName.push(nodes);
    nodesWithClassName[nodesWithClassName.length] = nodes;
    }
    }
    return nodesWithClassName;
    }

    function getElementsByClassNameFirstLevel(objParentNode, strNodeName, strClassName){
    var nodes = objParentNode.getElementsByTagName(strNodeName);

    if(!strClassName){
    nodesFirstLevel = [];
    for(var i=0; i<nodes.length; i++){
    if(nodes.parentNode.parentNode == objParentNode){
    nodesFirstLevel.push(nodes);
    }
    }
    return nodesFirstLevel;
    }
    var nodesWithClassNameFirstLevel = [];
    for(var i=0; i<nodes.length; i++){
    if(matchClass(nodes, strClassName) && nodes.parentNode.parentNode == objParentNode){
    nodesWithClassNameFirstLevel.push(nodes);
    }
    }
    return nodesWithClassNameFirstLevel;
    }

    /*****************************
    ** Some other methods
    ******************************/

    function getPageY( oElement ) {
    var iPosY = oElement.offsetTop;
    while ( oElement.offsetParent != null ) {
    oElement = oElement.offsetParent;
    iPosY += oElement.offsetTop;
    if (oElement.tagName == 'BODY') break;
    }
    return iPosY;
    }

    function getPageX( oElement ) {
    var iPosX = oElement.offsetLeft;
    while ( oElement.offsetParent != null ) {
    oElement = oElement.offsetParent;
    iPosX += oElement.offsetLeft;
    if (oElement.tagName == 'BODY') break;
    }
    return iPosX;
    }

    function getMousePosition(e) {
    if (e.pageX || e.pageY){
    var posX = e.pageX;
    var posY = e.pageY;
    }else if (e.clientX || e.clientY) {
    var posX = e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft;
    var posY = e.clientY + document.body.scrollTop + document.documentElement.scrollTop;
    }
    return {x:posX, y:posY}
    }



    /*****************************
    ** AJAX
    ******************************/

    /*
    url - откуда загружаем
    ajaxCallBackFunction - что вызываем по завершении загрузки
    callObject - методом какого объекта является ajaxCallBackFunction (если это метод, а не глобальная фунция)
    params - параметры в виде объекта или массива
    ajaxCallBackErrorFunction - необязательная функция, обрабатывающая ошибки соединения
    */

    function ajaxLoad(url, ajaxCallBackFunction, callObject, params, ajaxCallBackErrorFunction) {
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
    var ajaxObject = new XMLHttpRequest();
    ajaxObject.onreadystatechange = function(){
    ajaxLoadHandler(ajaxObject, ajaxCallBackFunction, callObject, params, ajaxCallBackErrorFunction);
    }
    ajaxObject.open("GET", url, true);
    ajaxObject.send(null);
    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
    var ajaxObject = new ActiveXObject("Microsoft.XMLHTTP");
    if (ajaxObject) {
    ajaxObject.onreadystatechange = function(){
    ajaxLoadHandler(ajaxObject, ajaxCallBackFunction, callObject, params, ajaxCallBackErrorFunction);
    }
    ajaxObject.open("GET", url, true);
    ajaxObject.send();
    }
    }
    }

    function ajaxLoadHandler(ajaxObject, ajaxCallBackFunction, callObject, params, ajaxCallBackErrorFunction){
    // only if req shows "complete"

    if (ajaxObject.readyState == 4) {
    // only if "OK"
    if (ajaxObject.status == 200) {
    // ...processing statements go here...
    ajaxCallBackFunction.call(callObject, ajaxObject, params);
    } else {
    $A(document.getElements('.js-loading')).each(function (loading_el) {
    $(loading_el).removeClass('js-loading');
    });
    if ($('reply_form')) {
    if ($('comments-form') && $('comments-form').elements['i']) {
    $('comments-form').elements['i'].value = '0';
    }
    if ($('comment_textarea')) {
    $('comment_textarea').set({'readonly':''});
    }
    if ($('reply_form').getElement('.comments_form_loading')) {
    $('reply_form').getElement('.comments_form_loading').addClass('hidden');
    }
    }
    if(ajaxCallBackErrorFunction){
    ajaxCallBackErrorFunction.call(callObject, ajaxObject, params);
    } else {
    try {
    alert("There was a problem retrieving the data:\n" + ajaxObject.statusText);
    } catch(err) {
    alert("There was a problem retrieving the data.");
    }
    }
    }
    }
    }

    function ajaxLoadPost(url, data, ajaxCallBackFunction, callObject, params, ajaxCallBackErrorFunction) {
    var ajaxObject = null;

    if (window.XMLHttpRequest) { // branch for native XMLHttpRequest object
    ajaxObject = new XMLHttpRequest();
    } else if (window.ActiveXObject) { // branch for IE/Windows ActiveX version
    var ajaxObject = new ActiveXObject("Microsoft.XMLHTTP");
    }
    if(ajaxObject){
    ajaxObject.onreadystatechange = function(){
    ajaxLoadHandler(ajaxObject, ajaxCallBackFunction, callObject, params, ajaxCallBackErrorFunction);
    }
    ajaxObject.open("POST", url, true);
    ajaxObject.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    ajaxObject.setRequestHeader("Content-length", data.length);
    ajaxObject.setRequestHeader("Connection", "close");
    ajaxObject.send(data);
    }
    }


    /* Class inheritance */
    Function.prototype.inheritFrom = function(BaseClass) { // thanks to Kevin Lindsey for this idea
    var Inheritance = function() {};
    Inheritance.prototype = BaseClass.prototype;

    this.prototype = new Inheritance();
    this.prototype.constructor = this;
    this.baseConstructor = BaseClass;
    this.superClass = BaseClass.prototype;
    }


    if(!Function.prototype.call) { // emulating 'call' function for browsers not supporting it (IE5)
    Function.prototype.call = function() {
    var oObject = arguments[0];
    var aArguments = [];
    var oResult;
    oObject.fFunction = this;
    for (var i = 1; i < arguments.length; i++) {
    aArguments[aArguments.length] = 'arguments[' + i + ']';
    }
    eval('oResult = oObject.fFunction(' + aArguments.join(',') + ')');
    oObject.fFunction = null;
    return oResult;
    }
    };[/js]



    и voting.js


    [js]function initVoting(type, parentElementId){
    var voteBlocks = getElementsByClassName($(parentElementId), 'div', 'vote');
    if(voteBlocks.length == 0) return;

    switch (type){
    case "posts":
    VoteBlock.type = VoteBlock.typePost;
    VoteBlock.theChoiceElement = $('vote_choice');
    VoteBlock.initChoiceElements();
    for (var i=0; i<voteBlocks.length; i++){
    new VoteBlock(voteBlocks);
    }
    break;
    case "comments":
    VoteBlock.type = VoteBlock.typeComment;
    for (var i=0; i<voteBlocks.length; i++){
    new VoteBlockComments(voteBlocks);
    //initShrink(voteBlocks.parentNode);
    }
    break;
    case "lepraposts":
    VoteBlock.type = VoteBlock.typePost;
    for (var i=0; i<voteBlocks.length; i++){
    new VoteBlockComments(voteBlocks);
    }
    break;
    default:
    break;
    }
    }


    function initShrink(parent){
    if(getElementsByClassName(parent, 'a', 'show_link').length == 0) return;

    var showLink = getElementsByClassName(parent, 'a', 'show_link')[0];
    showLink.onclick = function (){
    removeClass(this.parentNode.parentNode.parentNode, 'shrinked');
    return false;
    }
    }


    /* Класс VoteBlock (для голосования с плюсом и лопатой)
    ***************************************************************/
    function VoteBlock(htmlObj){
    this.htmlObj = htmlObj; // контейнер, содержащий все элементы голосования
    if (getElementsByClassName(this.htmlObj, 'a', 'plus').length == 0){
    return;
    }
    this.htmlObjChildren = this.htmlObj.getElementsByTagName('*');

    this.htmlGlobalParent = htmlObj.parentNode.parentNode; // родительский контейнер всего поста
    //this.htmlGlobalParent = htmlObj.parentNode; // родительский контейнер
    this.plusBtn = getElementsByClassName(this.htmlObj, 'a', 'plus')[0]; // контейнер с кнопкой +
    this.minusBtn = getElementsByClassName(this.htmlObj, 'a', 'minus')[0]; // контейнер с кнопкой -
    this.rating = getElementsByClassName(this.htmlObj, 'span', 'rating')[0].firstChild; // контейнер с рейтингом


    this.htmlObj.obj = this;
    this.plusBtn.obj = this;
    this.minusBtn.obj = this;
    this.rating.obj = this;

    this.voteType = VoteBlock.type;

    this.initChoiceEvents();

    }

    // Статическое свойство VoteBlock.theChoiceElement
    VoteBlock.theChoiceElement = {}; // html контейнер с элементами выбора, перемещаемый по дереву документа (всегда имеет родителем this.htmlGlobalParent)
    VoteBlock.theChoiceElement.elements = []; // массив всех элементов списка VoteBlock.theChoiceElement
    VoteBlock.theChoiceElement.currentObj = {}; // ссылка на объект класса VoteBlock, внутри которого сейчас находится VoteBlock.theChoiceElement
    VoteBlock.urlVoting = "http://vtrigazety.ru/post.php"; // url при голосовании + -
    VoteBlock.type = "";
    VoteBlock.typeComment = 0; // для указания, что голосуем по комментам
    VoteBlock.typePost = 1; // для указания, что голосуем по постам
    VoteBlock.wtf = ""; //

    // Статический метод, инициализирующий объект VoteBlock.theChoiceElement и все его элементы
    VoteBlock.initChoiceElements = function(){
    VoteBlock.theChoiceElement.elements = VoteBlock.theChoiceElement.getElementsByTagName('a');
    for (var i=0; i<VoteBlock.theChoiceElement.elements.length; i++){
    VoteBlock.theChoiceElement.elements.onclick = function(){
    if(matchClass(this, 'voted')){
    return false;
    } else {
    var currentObj = VoteBlock.theChoiceElement.currentObj;
    var postId = currentObj.htmlGlobalParent.getAttribute('id').substring(1);
    var choiceValue = this.getAttribute('choiceValue');
    var url = VoteBlock.urlVoting + "&type=" + this.obj.voteType + "&id=" + postId + "&value=" + choiceValue;

    currentObj.setChoiceVoted(choiceValue); // отрисовываем выбранный элемент
    addClass(currentObj.htmlGlobalParent, 'loading'); // ставим прелоадер
    ajaxLoad(url, currentObj.onLoad, currentObj); // отправляем/получаем данные
    return false;
    }
    }
    }
    }

    VoteBlock.prototype.initChoiceEvents = function (){
    this.htmlObj.onmouseout = function(e){
    if(!e) e = window.event;
    this.obj.hideChoice(e);
    }

    // Кнопка +
    this.plusBtn.onmouseover = function(e){
    if(!e) e = window.event;
    this.obj.hideChoice(e, this);
    }

    this.plusBtn.onclick = function(){
    this.blur();
    if(matchClass(this, 'voted')){
    return false;
    } else {
    var postId = this.obj.htmlGlobalParent.getAttribute('id').substring(1);
    var choiceValue = 1;
    var url = VoteBlock.urlVoting + "&type=" + this.obj.voteType + "&id=" + postId + "&value=" + choiceValue;

    this.obj.setChoiceVoted(null);
    addClass(this, 'voted'); // отмечаем сделанный выбор
    addClass(this.obj.htmlGlobalParent, 'loading'); // ставим прелоадер
    ajaxLoad(url, this.obj.onLoad, this.obj); // отправляем/получаем данные
    return false;
    }
    }

    // Кнопка -
    this.minusBtn.onmouseover = function(){
    this.obj.showChoice();

    // отвратительный хак против IE6- (заставляет не скакать правую колонку)
    if(typeof document.body.style.maxWidth == 'undefined' && $('content_right_inner')){
    $('content_right_inner').style.display = "none";
    $('content_right_inner').style.display = "block";
    }
    }

    this.minusBtn.onclick = function(){
    this.blur();
    return false;
    }
    }

    // Отрисовка блока VoteBlock.theChoiceElement
    VoteBlock.prototype.showChoice = function(){
    if (typeof VoteBlock.theChoiceElement == 'undefined') return;

    VoteBlock.theChoiceElement.currentObj = this; // создаем ссылку на новый родительский объект у VoteBlock.theChoiceElement
    addClass(VoteBlock.theChoiceElement.currentObj.htmlGlobalParent, 'inuse'); // располагаем htmlGlobalParent поверх отсальных

    this.showChoiceVoted(); // отрисовываем текущий голосованный элемент

    this.htmlObj.appendChild(VoteBlock.theChoiceElement);
    VoteBlock.theChoiceElement.style.display = 'block';
    }

    VoteBlock.prototype.hideChoice = function(e, obj){
    if (typeof VoteBlock.theChoiceElement == 'undefined') return;

    // если mouseover на кнопке "плюс", скрываем чойс бокс
    if(obj && matchClass(obj, "plus")){
    addClass(this.htmlGlobalParent, 'inuse'); // располагаем htmlGlobalParent поверх отсальных
    VoteBlock.theChoiceElement.style.display = 'none';
    return;
    }

    // если элемент, на который передвигаем мышь, лежит внутри чойс блока, выходим
    if (e.relatedTarget) {
    var where = e.relatedTarget;
    if (where == this.htmlObj) return;
    if (where.nodeType == 3) where = where.parentNode;
    for(var i=0; i<this.htmlObjChildren.length; i++){
    if (where == this.htmlObjChildren) {
    return;
    }
    }
    } else if (e.toElement && this.htmlObj.contains(e.toElement)) {
    return;
    }

    removeClass(this.htmlGlobalParent, 'inuse'); // снимаем свойство с htmlGlobalParent лежать поверх отсальных
    VoteBlock.theChoiceElement.style.display = 'none';
    }

    // Отрисовка пункта, за который проголосовали, в списке элементов VoteBlock.theChoiceElement
    VoteBlock.prototype.showChoiceVoted = function (){
    var currentChoiceValue = this.minusBtn.getAttribute('choiceValue');
    for (var i=0; i<VoteBlock.theChoiceElement.elements.length; i++){
    var currentElement = VoteBlock.theChoiceElement.elements;
    if (currentElement.getAttribute('choiceValue') == currentChoiceValue){
    addClass(currentElement, 'voted');
    } else {
    removeClass(currentElement, 'voted');
    }
    }
    }

    // Установка нового выбранного значения в списке элементов VoteBlock.theChoiceElement
    VoteBlock.prototype.setChoiceVoted = function(choiceMinusValue){
    this.minusBtn.setAttribute('choiceValue', choiceMinusValue);
    if(matchClass(this.plusBtn, 'voted')) {
    removeClass(this.plusBtn, 'voted');
    }
    this.showChoiceVoted();
    }

    VoteBlock.prototype.onLoad = function (ajaxObj){
    var newRating = ajaxObj.responseText;
    this.rating.innerHTML = newRating;
    removeClass(this.htmlGlobalParent, 'loading'); // убираем прелоадер
    }




    /* Подкласс VoteBlockComments (для голосования с плюсом и минусом)
    *************************************************************************/
    function VoteBlockComments (htmlObj){
    VoteBlockComments.baseConstructor.call(this, htmlObj);
    }
    VoteBlockComments.inheritFrom(VoteBlock);

    VoteBlockComments.prototype.initChoiceEvents = function (){

    this.htmlObj.onmouseout = function(e){
    if(!e) e = window.event;
    this.obj.hideChoice(e);
    }

    // Кнопка +
    this.plusBtn.onmouseover = function(e){
    return false;
    }

    this.plusBtn.onclick = function(){
    this.blur();
    if(matchClass(this, 'voted')){
    return false;
    } else {
    var postId = this.obj.htmlGlobalParent.getAttribute('id');
    var choiceValue = 1;
    var url = VoteBlock.urlVoting + "&type=" + this.obj.voteType + "&id=" + postId + "&value=" + choiceValue;

    addClass(this, 'voted'); // отмечаем сделанный выбор
    removeClass(this.obj.minusBtn, 'voted') // снимаем отметку о противоположном голосовании
    addClass(this.obj.htmlGlobalParent, 'loading'); // ставим прелоадер

    ajaxLoad(url, this.obj.onLoad, this.obj); // отправляем/получаем данные

    return false;
    }
    }

    // Кнопка -
    this.minusBtn.onmouseover = function(){
    return false;
    }

    this.minusBtn.onclick = function(){
    this.blur();
    if(matchClass(this, 'voted')){
    return false;
    } else {
    var postId = this.obj.htmlGlobalParent.getAttribute('id');
    var choiceValue = -1;
    var url = VoteBlock.urlVoting + "wtf=" + VoteBlock.wtf + "&type=" + this.obj.voteType + "&id=" + postId + "&value=" + choiceValue;

    addClass(this, 'voted'); // отмечаем сделанный выбор
    removeClass(this.obj.plusBtn, 'voted') // снимаем отметку о противоположном голосовании
    addClass(this.obj.htmlGlobalParent, 'loading'); // ставим прелоадер
    addClass(this.obj.htmlGlobalParent, 'shrinked');

    ajaxLoad(url, this.obj.onLoad, this.obj); // отправляем/получаем данные
    return false;
    }
    return false;
    }

    this.rating.onmouseover = function(){
    this.obj.showChoice();
    }
    }

    VoteBlockComments.prototype.showChoice = function(){
    addClass(this.htmlGlobalParent, 'inuse');
    }

    VoteBlockComments.prototype.hideChoice = function(e, obj){

    // если элемент, на который передвигаем мышь, лежит внутри чойс блока, выходим
    if (e.relatedTarget) {
    var where = e.relatedTarget;
    if (where == this.htmlObj) return;
    if (where.nodeType == 3) where = where.parentNode;
    for(var i=0; i<this.htmlObjChildren.length; i++){
    if (where == this.htmlObjChildren) {
    return;
    }
    }
    //e.relatedTarget.style.border = "none"; // странно, но это побороло баг в Opere :/
    } else if (e.toElement && this.htmlObj.contains(e.toElement)) {
    return;
    }

    removeClass(this.htmlGlobalParent, 'inuse');
    }



    /* Класс VoteBlockUser (для голосования с 2 плюсами и 2 минусами по юзеру)
    *************************************************************************/
    function initVotingUser (parentObjId){
    var parentObj = $(parentObjId);
    var voteBlocks = parentObj.getElementsByTagName('strong');
    if(voteBlocks.length == 0) return;

    var ratingBlock = getElementsByClassName(parentObj, 'span', 'rating')[0].firstChild; // контейнер с рейтингом

    for (var i=0; i<voteBlocks.length; i++){
    new VoteBlockUser(voteBlocks, ratingBlock);
    }
    }


    function VoteBlockUser(htmlObj, ratingBlock){
    this.htmlObj = htmlObj;

    this.htmlGlobalParent = htmlObj.parentNode.parentNode; // родительский контейнер всего поста
    this.plusBtn = getElementsByClassName(this.htmlObj, 'a', 'plus')[0]; // контейнер с кнопкой +
    this.minusBtn = getElementsByClassName(this.htmlObj, 'a', 'minus')[0]; // контейнер с кнопкой -
    this.rating = ratingBlock;

    this.htmlObj.obj = this;
    this.plusBtn.obj = this;
    this.minusBtn.obj = this;
    this.rating.obj = this;

    this.initChoiceEvents();
    }

    VoteBlockUser.urlVoting = "/karma/"; // url при голосовании + -
    VoteBlockUser.wtf = ""; //

    VoteBlockUser.prototype.initChoiceEvents = function (){
    this.plusBtn.onclick = function(){
    this.blur();
    if(matchClass(this, 'voted')){
    return false;
    } else {
    var userId = this.obj.htmlGlobalParent.getAttribute('uid');
    var choiceValue = this.getAttribute('choiceValue');
    var url = VoteBlockUser.urlVoting;
    var data = "wtf=" + VoteBlockUser.wtf + "&u_id=" + userId + "&value=" + choiceValue;

    addClass(this, 'voted'); // отмечаем сделанный выбор
    removeClass(this.obj.minusBtn, 'voted') // снимаем отметку о противоположном голосовании
    addClass(this.obj.htmlGlobalParent, 'loading'); // ставим прелоадер

    ajaxLoadPost(url, data, this.obj.onLoad, this.obj); // отправляем/получаем данные
    return false;
    }
    }

    this.minusBtn.onclick = function(){
    this.blur();
    if(matchClass(this, 'voted')){
    return false;
    } else {
    var userId = this.obj.htmlGlobalParent.getAttribute('uid');
    var choiceValue = this.getAttribute('choiceValue');
    var url = VoteBlockUser.urlVoting;
    var data = "wtf=" + VoteBlockUser.wtf + "&u_id=" + userId + "&value=" + choiceValue;

    addClass(this, 'voted'); // отмечаем сделанный выбор
    removeClass(this.obj.plusBtn, 'voted') // снимаем отметку о противоположном голосовании
    addClass(this.obj.htmlGlobalParent, 'loading'); // ставим прелоадер

    ajaxLoadPost(url, data, this.obj.onLoad, this.obj); // отправляем/получаем данные
    return false;
    }
    return false;
    }

    }

    VoteBlockUser.prototype.onLoad = function (ajaxObj){
    var newRating = ajaxObj.responseText;
    this.rating.innerHTML = newRating;
    removeClass(this.htmlGlobalParent, 'loading'); // убираем прелоадер
    }



    /* Альтернативные функции */
    var wtf_vote = null;

    function vote (linkBtn, post_id){
    linkBtn.blur();
    if(matchClass(linkBtn, 'voted')) return false;

    var linkGlobalParent = linkBtn.parentNode.parentNode.parentNode.parentNode;
    var id = linkGlobalParent.id;
    var linkParent = linkBtn.parentNode;
    var rating = getElementsByClassName(linkParent, 'span', 'rating')[0].firstChild; // контейнер с рейтингом
    var value;
    var oppositeBtn;
    var showLink = getElementsByClassName(linkGlobalParent, 'a', 'show_link')[0];

    if (matchClass(linkBtn, 'plus')){
    value = 1;
    oppositeBtn = getElementsByClassName(linkParent, 'a', 'minus')[0];
    } else {
    value = -1;
    oppositeBtn = getElementsByClassName(linkParent, 'a', 'plus')[0];

    if(typeof noShrink != 'undefined'){
    noShrink(showLink);
    }
    //addClass(linkGlobalParent, 'shrinked');
    }

    addClass(linkBtn, 'voted'); // отмечаем сделанный выбор
    removeClass(oppositeBtn, 'voted') // снимаем отметку о противоположном голосовании
    addClass(linkGlobalParent, 'loading'); // ставим прелоадер

    var url = "http://vtrigazety.ru/post.php";
    var data = "type=0&wtf=" + wtf_vote + "&id=" + id + "&value=" + value + "&post_id=" + post_id;
    var params = {r:rating, gp:linkGlobalParent};

    ajaxLoadPost(url, data, voteOnLoad, window, params, votePostOnError); // отправляем/получаем данные
    return false;
    }

    function voteOnLoad(ajaxObj, params){
    var rating = params.r;
    var linkGlobalParent = params.gp;
    var newRating = ajaxObj.responseText;

    rating.innerHTML = newRating;
    removeClass(linkGlobalParent, 'loading'); // убираем прелоадер
    }

    function showChoice(link){
    var linkGlobalParent = link.parentNode.parentNode.parentNode.parentNode;
    addClass(linkGlobalParent, 'inuse');
    }

    function hideChoice(e, obj){
    var objChildren = obj.getElementsByTagName('*');
    var objGlobalParent = obj.parentNode.parentNode;

    // если элемент, на который передвигаем мышь, лежит внутри чойс блока, выходим
    if (e.relatedTarget) {
    var where = e.relatedTarget;
    if (where == obj) return;
    if (where.nodeType == 3) where = where.parentNode;
    for(var i=0; i<objChildren.length; i++){
    if (where == objChildren) {
    return;
    }
    }

    //e.relatedTarget.style.border = "none"; // странно, но это побороло баг в Opere :/
    } else if (e.toElement && obj.contains(e.toElement)) {
    return;
    }

    removeClass(objGlobalParent, 'inuse');
    }

    function votePost(linkBtn){
    linkBtn.blur();
    if(matchClass(linkBtn, 'voted')) return false;

    var linkGlobalParent = linkBtn.parentNode.parentNode.parentNode.parentNode;
    var id = linkGlobalParent.id;
    var linkParent = linkBtn.parentNode;
    var rating = getElementsByClassName(linkParent, 'span', 'rating')[0].firstChild; // контейнер с рейтингом


    if (matchClass(linkBtn, 'plus')){
    value = 1;
    oppositeBtn = getElementsByClassName(linkParent, 'a', 'minus')[0];
    } else {
    value = -1;
    oppositeBtn = getElementsByClassName(linkParent, 'a', 'plus')[0];
    }

    addClass(linkBtn, 'voted'); // отмечаем сделанный выбор
    removeClass(oppositeBtn, 'voted');
    addClass(linkGlobalParent, 'loading'); // ставим прелоадер

    var url = "http://vtrigazety.ru/post.php";
    var data = "type=1&wtf=" + wtf_vote + "&id=" + id + "&value=" + value;
    var params = {r:rating, gp:linkGlobalParent};

    ajaxLoadPost(url, data, votePostOnLoad, window, params, votePostOnError); // отправляем/получаем данные
    return false;
    }

    function votePostOnLoad(ajaxObj, params) {
    var rating = params.r;
    var linkGlobalParent = params.gp;
    var newRating = ajaxObj.responseText;

    rating.innerHTML = newRating;
    removeClass(linkGlobalParent, 'loading'); // убираем прелоадер
    removeClass(rating.parentNode, 'js-loading_error');
    }

    function votePostOnError(ajaxObj, params) {
    alert(ajaxObj.statusText);
    if (ajaxObj.statusText) {
    var errorText = (ajaxObj.statusText) ? ' ' + ajaxObj.statusText : '';
    } else {
    var errorText = '';
    }
    addClass(params.r.parentNode, 'js-loading_error');
    params.r.title = 'Ошибка в получении данных.' + errorText;
    removeClass(params.gp, 'loading');
    }[/js]


    дэмо http://vtrigazety.ru/?blog=jquery&novost=1&id=1
     
  12. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    в этом коде чего только нету. даже позиция мышки засекается...

    Давай придумаем структуру БД и дело в шляпе. Останется только накодить. ты точно не хочешь, чтобы были баллы?
     
  13. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
    вобще конечно хочу чтобы они сразу обновлялись но не думаю что я сам скоро разберусь как это реализовать, я привык действовать поступательно, по порядку, сперва первое, потом второе и тд

    вот структура бд

    votings
    Код (Text):
    1. id - порядковый номер
    2. position - во что балл записан
    3. number - номер поста или коммента
    4. point - балл
    5. ouner - владелец балла
    6. autor - кто поставил балл
    post
    Код (Text):
    1. id  - порядковый номер
    2. blog - имя блога поста
    3. autor   - автор поста
    4. ball     - сколько балов у поста
    5. description - описание поста
    6. data    - дата публикации
    7. up  - дата подёма поста
    8. title   - заголовок поста
    9. content - содержимое поста
    10. keywords    - ключевые слова
    11. comments    - комментариев
    12. vews    - просмотров
    13. moderation - модерация
    14. cat - категория
    15. ip - ип
    comments
    Код (Text):
    1. id   - номерация
    2. postnumb    - номер коммента
    3. autor   - авторк оммента
    4. unswer  - чилд(ответ на коммент)
    5. ball     - балл
    6. data    - дата
    7. ip  - ип
    8. comment - сам коммент
    9. vew - вид коммента
    user
    Код (Text):
    1. id - номер юзера
    2. login - логин
    3. mail - почта
    4. password - пароль
    5. regip - ип при реге
    6. dt - дата рега
    7. name - ФИО/имя
    8. karma - карма
    9. posts - число постов
    10. comments - число комментов
    11. status - статус аккаунда
     
  14. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    как обновляться? смотрим на jquery.com аякс в примерах. там есть suxess где ты можешь заменить содержимое голосовалки допустим количеством голосов

    вот примерно так

    1) рисуем из пхп блок голосовалки относящийся к этому посту
    HTML:
    1. <div id='golosovalka_134141414' class='golosovalka'>
    2.     <a onclick="vote(134141414,'+1');">[+]</a>
    3.     <a onclick="vote(134141414,'-1');">[-]</a>
    4. </div>
    id для отрисовки действий именно в этом диве. класс для раскрашивания и задания стилей один на все - очень удобно.

    2)Чел видит плюсик или минусик и клацает. (чтобы был пальчик над ссылками которые никуда не ведут, можно задать его из css принудительно. http://htmlbook.ru тебе в помощь. http://htmlbook.ru/css/cursor.html

    3) при нажатии вызывается процедура vote в которую передаем номер поста ( мы ж когда из пхп его рисовали, знали какой номер? вот и дело в шляпе) и желаемое действие. подчеркну, кто-то может и +100500 пожелать. на данном этапе нас это волновать не должно.

    4) в процедуре вызываем через метод jquery ajax (примеры на сайте есть) голосовательный скрипт пхп. для невъебенной крутости предварительно перед этим можно запустить гифчик с бегающими кружочками. взять можно где угодно в этих ваших интернетах.

    5) в суксесе аякса мы радостно получаем ответ от вызванного скрипта пхп. Ответ удобно если будет готовым уже к вмонтированию в div golosovalka_134141414. Например такой
    HTML:
    1. <img src="images/палецвверх.png"><span class='green'>112</span>
    2. &nbsp;
    3. <img src="images/палецвниз.png"><span class='red'>73</span>
    В итоге волшебным образом получаем красивую картинку и количество голосов за и против - это круче чем общий балл. Короче как на ютубе.

    Единственное что осталось - накодить это. И накодить голосовательный скрипт. Предлагаю тебе сделать сначала его без всяких проверок на повторные голосования и вобще без заморочек. Когда будет работать так - будешь дальше его защищать уже от террористов.
     
  15. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    по базе.

    в таблице вотингс:
    что такое позишн? нипанятна
    что такое овнер и автор? почему разные? зачем это.

    Давай проще.

    id, Date, voter - голосующий, vote - signed tinyint, id поста
    первые два в принципе нах не нужны, но в 2010 году можно не жадничать память в угоду комфорту.
    Хранить автора поста в голосовалке в принципе не нужно, но можно. Но не нужно. Но можно.

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

    Собственно скрипт пхп голосования при получении запроса на изменение баллов такого-то поста на такое-то колличество баллов чешет репу, решает можно ли или нельзя этому юзеру - можно проверить по вотингс запросив такой-то пост, такого-то голосующего и если он есть - то уже не дать. По хорошему при отрисовке страницы этот же код лезет и если находит запись на такую пару - рисует сразу не голосовалку соотв. а результат. Десяток постов на страницу - это десяток запросов на проверку и десяток запросов на колличество баллов. Ну... Норм. Жить можно. В принципе их можно спихать в один запрос.
     
  16. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
    ну вот смотри какой камень преткновения
    <a onclick="vote(134141414,'pluspost');">[+]</a>
    <a onclick="vote(134141414,'minuspost');">[-]</a>
    это ничто иное как
    <a onclick="vote(порядковый номер самого поста или комментария,'реализуемое действие');">[+]</a>
    что надо написать в


    <script type="text/javascript">

    </script>
    чтобы данные в script.php можно было получить в виде параметров
    $_GET['id']
    $_GET['action']

    где
    id - порядковый номер самого поста или комментария
    action - реализуемое действие
    ?
     
  17. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    как что? я ж писал в самом начале топика пример из жукувери

    смотри блин примеры на сайте жукувери уже. там все элементарно =) чего ты боишься. пробуй больше. спрашивай, когда затык, а не когда нечего пробовать.
    http://api.jquery.com/jQuery.ajax/
    http://api.jquery.com/category/ajax/
     
  18. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    мне кажется это подойдет
    [js]bodyContent = $.ajax({
    url: "script.php",
    global: false,
    type: "POST",
    data: ({id : this.getAttribute('id')}),
    dataType: "html",
    async:false,
    success: function(msg){
    alert(msg);
    }
    }
    ).responseText;[/js]
     
  19. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    вот тебе еще в помощь:

    PHP:
    1. <pre>
    2. <?php
    3. //начни с такого сприпта
    4. print_r($_GET);
    5. print_r($_POST);
    6. ?>
    7. </pre>
     
  20. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
    да пхп у меня все прекрасно кушает
    <?php
    if ($_GET['action']=='minuspost'){
    $safe_topic=mysql_escape_string($_POST['moto_cutnum']);
    $sSQL="UPDATE blogposts SET
    ball= ball -1 WHERE id=".$_GET['id'];
    mysql_query($sSQL) or die(mysql_error());
    }
    elseif ($_GET['action']=='pluspost'){
    $safe_topic=mysql_escape_string($_POST['moto_cutnum']);
    $sSQL="UPDATE blogposts SET
    ball= ball +1 WHERE id=".$_GET['id'];
    mysql_query($sSQL) or die(mysql_error());
    }
    else {
    echo "нет такого действия";
    }
    ?>
    сейчас поставил <script src="http://code.jquery.com/jquery-latest.min.js"></script>

    вывожу кнопку
    PHP:
    1. <a onclick="vote(<?php echo $line[0];?>,'minuspost');">-</a>
    сюда что только не вписывал в ответ никакого результата, ребят ну не мучайте меня дайте цельный ответ на такой простой вопрос
    [js]<script>
    ?????????????????????????????
    </script>[/js]

    урл скрипта обработчика
    http://vtrigazety.ru/post.php?id=1&action=minuspost

    получаемые скриптом параметры
    $_GET['action']
    $_GET['id']
     
  21. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    test.php:
    PHP:
    1. <?php
    2. if (isset ($_GET['id']) AND isset ($_GET['action'])) {
    3.   $id = intval($_GET['id']);
    4.   switch ($_GET['action']) {
    5.     case 'pluspost':
    6.       $action = 1;
    7.       break;
    8.     case 'minuspost':
    9.       $action = -1;
    10.       break;
    11.     default:
    12.       $action = intval($_GET['action']);
    13.   }
    14.   $_SESSION['votes'][$id] += $action;
    15.   echo $_SESSION['votes'][$id];
    16.  
    17. } else {
    18.  
    19.   echo "
    20. <html>
    21.  <head>
    22.    <script language='javascript' type='text/javascript' src='http://code.jquery.com/jquery-latest.min.js'></script>
    23.  </head>
    24.  <body>
    25.    <div id='vote_1' style='border: 1px solid blue;'>
    26.      <a onclick=\"vote(1,'minuspost');\" href='#'>[-]</a> <a onclick=\"vote(1,'pluspost');\" href='#'>[+]</a>
    27.    </div><br>
    28.    <div id='vote_2' style='border: 1px solid red;'>
    29.      <a onclick=\"vote(2,'minuspost');\" href='#'>[-]</a> <a onclick=\"vote(2,'pluspost');\" href='#'>[+]</a>
    30.      <a onclick=\"vote(2,'-100');\" href='#'>[-100]</a> <a onclick=\"vote(2,'100');\" href='#'>[+100]</a>
    31.    </div><br>
    32.    <div id='vote_3' style='border: 1px solid green;'>
    33.      <a onclick=\"vote(3,'minuspost');\" href='#'>[-]</a> <a onclick=\"vote(3,'pluspost');\" href='#'>[+]</a>
    34.    </div><br>
    35.    <script language='JavaScript'  type='text/javascript'>
    36.      function vote (id, action) {
    37.      $('#vote_'+id).hide('slow',  function () {
    38.  
    39.        var html = jQuery.ajax({
    40.          url: 'test.php',
    41.          type: 'GET',
    42.          data: ({id : id, action : action}),
    43.          async: false
    44.        }).responseText;
    45.        $('#vote_'+id).html(html);
    46.        $('#vote_'+id).show('slow');
    47.  
    48.      }
    49.    );
    50.    }
    51.    </script>
    52.  </body>
    53. </html>
    54. ";
    55. }
    56. ?>
    57.  
     
  22. Padaboo

    Padaboo Старожил
    Команда форума Модератор

    С нами с:
    26 окт 2009
    Сообщения:
    5.242
    Симпатии:
    1
  23. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
    Что-то начало получаться
    [js]<script src="http://code.jquery.com/jquery-latest.min.js"></script>
    <script type="text/javascript">
    $(document).ready(function() {

    });
    function votepost(id, action) {
    $.getJSON('http://vtrigazety.ru/post.php?id='+id+'&action='+action, {}, function(json) {
    $("#a_ball").html(json.ball);
    });
    }
    </script>[/js]


    код кнопок
    PHP:
    1. <div class="blogpostsminus"><a href="#" onclick="votepost(<?php echo $line[0];?>,'minuspost'); return false;">-</a></div>
    2. <div class="blogpostsplus" ><a href="#" onclick="votepost(<?php echo $line[0];?>,'pluspost'); return false;">+</a></div>
    3. <div class="blogpostsball" ><a href="#" id="a_ball"><?php echo $line[3];?></a></div>

    скрипт post.php
    PHP:
    1. <?php
    2.     if ($_GET['action']=='minuspost'){
    3.     $safe_topic=mysql_escape_string($_POST['cutnum']);
    4.     $sSQL="UPDATE blogposts SET
    5.     ball= ball -1 WHERE id=".$_GET['id'];
    6.     mysql_query($sSQL) or die(mysql_error());
    7.      echo '{
    8. "ball": "100000"
    9. }';
    10.     }
    11.     elseif ($_GET['action']=='pluspost'){
    12.     $safe_topic=mysql_escape_string($_POST['cutnum']);
    13.     $sSQL="UPDATE blogposts SET
    14.     ball= ball +1 WHERE id=".$_GET['id'];
    15.     mysql_query($sSQL) or die(mysql_error());
    16.         echo "ball";
    17.     }
    18.     else {
    19.         echo "нет такого действия";
    20. }
    21.    
    22. ?>
    не могу понять как выводить получившийся бал без обновления страницы?
     
  24. igordata

    igordata Суперстар
    Команда форума Модератор

    С нами с:
    18 мар 2010
    Сообщения:
    32.408
    Симпатии:
    1.768
    ой, ну нахрена тут джисон.

    ладно. у вас есть два работающих варианта. вперед! =)

    Vantedur
    не могу понять как выводить получившийся бал без обновления страницы?

    В моем примере это есть. Удачи. =)

    11 строк уж найдите силы разобрать. с 38 по 47
     
  25. Vantedur

    Vantedur Активный пользователь

    С нами с:
    9 июл 2010
    Сообщения:
    779
    Симпатии:
    2
    вот тут почему то отлично все работает
    http://vtrigazety.ru/?blog=jquery&novost=1

    но стоит мне попробовать этим воспрозоваться на http://jquery.vtrigazety.ru/&novost=1

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

    сейчас js
    [js]<script type="text/javascript">
    $(document).ready(function() {

    });
    function votepost(id, action) {
    $.getJSON('http://vtrigazety.ru/post.php?id='+id+'&action='+action, {}, function(json) {
    $("#a_ball").html(json.ball);
    });
    }
    </script>[/js]

    поддомен генерится через аксесс
    Код (Text):
    1. RewriteEngine On
    2. RewriteCond %{HTTP_HOST} ^(.{3,})\.vtrigazety\.ru$
    3. RewriteRule (.*) http://vtrigazety.ru/index.php?blog=%1&uri=%{REQUEST_URI} [P,L]