如何实施上下投票?

时间:2011-06-09 06:32:48

标签: javascript php post

如果你已经使用Stack Overflow一段时间,你肯定已经使用了问答的投票功能。我注意到Stack Overflow使用<a>锚点。但我不知道如何将数据发布到服务器。我认为这是与<a>相关的JavaScript,但我找不到它。我该如何实施呢?

5 个答案:

答案 0 :(得分:11)

是的,涉及JavaScript。有两个部分:为投票“按钮”上的点击事件挂钩处理程序,并将数据发送到服务器。

在其他地方很好地讨论这些事件,我不会在这里讨论。

将数据发送到服务器,您可以使用ajax。 DIY方式看起来大致如此(但实际上并没有使用此代码,见下文):

var xhr = new XMLHttpRequest();
xhr.open("POST", "/path/to/server/destination");
xhr.onreadystatechange = handleStateChange;
xhr.send("id=" + encodeURIComponent(id) +
         "&user=" + encodeURIComponent(userId) +
         "&vote=up");
function handleStateChange() {
    if (xhr.readyState === 4) {
        // POST complete and we have response, check it
        if (xhr.responseText !== "ok") { // Or whatever you want it to be
            // Report problem
        }
    }
}

上述new XMLHttpRequest部分仅适用于现代浏览器;对于早期版本的IE,您必须使用new ActiveXObjectSee examples here(虽然我一直认为这很复杂)。

这是一个例子,说明浏览器与浏览器的不同之处。在进行丰富的Web编程时,有一些很多这些小的浏览器差异(包括挂钩事件处理程序!),所以我建议使用一个好的,支持良好的库来平滑那些提供很多实用功能。您有很多选择:jQueryPrototypeYUIClosureany of several others

以上是使用jQuery:

$.ajax({
    url:  "/path/to/server/destination",
    type: "POST",
    data: {id: id, userId: userId, vote: "up"},
    success: function(response) {
        if (response !== "ok") { // Or whatever you want it to be
            // Report problem
        }
    }
});

......其他库将提供类似的帮助功能。

(这两个例子 - 无论是DIY方式还是jQuery方式 - 都没有正确处理HTTP错误,这自然是你想做的,但这会给你一个想法。)


<强>更新

只是为了好玩,这里有一个使用jQuery的完整示例(但我不是在推jQuery;你可以做一些非常相似的事情,可能就像我上面提到的任何其他库一样简单;它只是最简单的对我来说,使用jQuery示例,因为那是我目前使用的库:

HTML:

<div class="article" data-itemid="427">
<a href="voteup"   class="vote up"  >Up</a>
<a href="votedown" class="vote down">Down</a>
<!-- ...the contents of the item... -->
</div>

使用jQuery的JavaScript:

jQuery(function($) {

    // Hook up our vote handlers
    $("a.vote").live('click', voteClick);

    function voteClick(event) {
        var voteLink, voteType, item, itemId;

        // Regardless of the below, we handle the event, so "consume" it
        event.stopPropagation();
        event.preventDefault();

        // Get the anchor element, wrapped in a jQuery instance
        voteLink = $(this);

        // See if the vote has already been done or is in progress
        if (voteLink.hasClass('done') || voteLink.hasClass('inprogress')) {
            // Ignore the click, possibly tell the user why
            return;
        }

        // Get the vote type
        voteType = voteLink.hasClass('up') ? 'up' : 'down';

        // Get the item we're voting on
        item     = voteLink.closest('.article');

        // Get its ID
        itemId   = item.attr('data-itemid');

        // If we didn't get an ID...
        if (!itemId) {
            // ...report error
            return;
        }

        // Mark "in progress" and initiate the vote; action continues
        // in our callbacks below
        voteLink.addClass('inprogress');
        $.ajax({
            url:     'savevote',
            data:    {itemId: itemId, voteType: voteType},
            type:    'POST',
            success: votePostSuccess,
            error:   votePostError
        });

        // Called when the POST is successful
        function votePostSuccess(response) {
            // The POST worked
            voteLink.removeClass('inprogress');

            // Did things work on the server?
            if (response === "ok") { // Or whatever
                // Yes, the vote was successfully recorded
                voteLink.addClass('done');
            }
            else {
                // Report an error to the user, the server couldn't record the vote
            }
        }

        // Called when the POST fails for some reason (HTTP errors)
        function votePostError(xhr, statusText, err) {
            // Not in progress anymore
            voteLink.removeClass('inprogress');

            // Report error to user
        }
    }
});

一些注意事项:

  • 上面的所有代码都包含在我传递给jQuery函数的函数中。这告诉jQuery在DOM“准备好”(more)时运行代码。或者,只需将script标记放在body标记的底部(更多herehere)。
  • 我在链接上放置了href(StackOverflow没有),所以如果禁用JavaScript,我们可以回到我们允许用户使用表单投票的页面提交或某事。此外,浏览器(标签目标等)专门处理与href的链接,因此这对于辅助功能非常有用。 (要真的这样做,我可能不得不将文章ID放在href中。)
  • 我正在data- attribute
  • 中存储我们投票的项目的ID
  • 我们通过将“最近”的文章定位到点击的按钮来找到要投票的项目。 jQuery的closest函数以一个元素开始,然后检查该元素,然后检查它的父元素,然后它的父元素等,直到它找到你传入的CSS选择器的匹配为止。所以投票按钮通过包含与文章相关联;在上投票的文章包含投票按钮。
  • 我正在使用POST,因为调用会更改服务器状态,因此GET不合适
  • ajax帖子的回调是闭包(请注意它们是如何在 voteClick中定义并在其中使用voteLink,甚至虽然它是voteClick中的变量。 Closures are not complicated,但有一些事情对我们来说很重要,我试图在这篇链接文章中解决这些问题。
  • 我正在使用jQuery的live功能,这是一种执行事件委派的机制。这样,我可以动态地添加项目以对页面进行投票,而不用担心将处理程序连接到他们的投票按钮。

答案 1 :(得分:4)

查看Ajax

答案 2 :(得分:3)

您可以使用jquery来执行此操作。 只需在向上/向下箭头上应用click eventlisteners,它将使用ajax将数据发送到您的服务器。

服务器上的脚本将验证传入数据并更新数据库中的计数。 然后你可以发回一个回复,给出更新的上/下计数

注意:您还必须考虑用户只能喜欢或不喜欢一次。 您可以在服务器端处理它/或者为了简单起见将其存储在cookie中。

答案 3 :(得分:0)

Magic是正确的,您正在寻求使用AJAX,这是一种技术,允许您在不完全发布页面的情况下从页面来回发送数据到服务器。

如果您想要一篇好文章来帮助您入门,我会在Nettuts上查看这篇文章:5 ways to make ajax call with jquery

在我看来,使用jQuery是从javascript发布和获取数据的最简单方法。

干杯

答案 4 :(得分:0)

投票功能需要两部分:

  1. 客户端 这个处理投票的视觉部分。您有按钮,可以是跨度或链接或图像,或任何HTML元素。 Javascript用于向该元素注册一个动作,因此当有人向上或向下点击时,Javascript将知道点击了哪个按钮。

  2. 服务器端 在服务器端,您需要存储投票的逻辑。您将需要一个表来存储结果,并将投票连接到用户和数据库中的某个帖子。并且您将需要与此投票相关的一些功能,例如:

    function saveVote ($user_id, $post_id) {...}
    // or
    function getPostVotes ($post_id) {...}
    // or
    function getUserVotes ($user_id) {...}
    
  3. 连接这两部分的是Emil建议的Ajax。虽然这是当今最常见的形式,但您甚至可以使用简单的表单或iframe或其他技术将信息传递给服务器。它们都做同样的事情,即将投票参数(如post_id和user_id以及vote_result)传递给将保存到数据库中的php脚本。作为确认投票真实并保存后的额外步骤,您可以增加/减少页面中的投票数。