65.9K
CodeProject 正在变化。 阅读更多。
Home

使用 JavaScript 拖放产品到购物篮

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.93/5 (35投票s)

2007 年 3 月 13 日

CPOL

5分钟阅读

viewsIcon

208877

downloadIcon

4073

创建可拖动的对象并将它们放入购物车。

引言

前段时间我访问了一个网站,它有一个拖放购物车功能。用户可以简单地将他们想购买的商品拖放到购物车中,购物车就会更新显示新的商品。我对这个功能印象深刻,于是决定创建一个小型应用程序来实现同样的功能。

在本文中,我将实现一个页面,允许用户将他们想购买的商品拖放到购物车中。购物车中的商品和价格将得到更新。本文提供的代码是跨浏览器兼容的。

注意:在阅读本文之前,我强烈建议您阅读文章 使用 JavaScript 进行拖放

数据库设计

我使用 SQL SERVER 2005 Express 创建了一个名为“ToyShopDatabase”的简单数据库。该数据库包含一个名为“tblToys”的表,其中包含四个列。

  • ToyID:标识列用作主键。
  • Title:玩具的名称。
  • ImageUrl:玩具的图片 URL。
  • Price:玩具的价格。

我已经用一些虚拟数据填充了数据库。下面我们来看看如何在页面上显示数据。

在页面上显示数据

我使用了 DataList 控件来在页面上显示数据。请查看下面的 BindData 方法,该方法用于从数据库检索数据。

private void BindData() 
{ 
    string connectionString = ConfigurationManager.ConnectionStrings _
        ["ConnectionString"].ConnectionString; 
    SqlConnection myConnection = new SqlConnection(connectionString); 

    SqlDataAdapter ad = new SqlDataAdapter("SELECT * FROM tblToys",_ 
        myConnection); 
    DataSet ds = new DataSet(); 
    ad.Fill(ds); 

    dlToys.DataSource = ds; 
    dlToys.DataBind(); 
}

您可以在下面的屏幕截图中看到页面上显示的项目

您还可以看到屏幕左侧显示的购物车。购物车显示 $0.00,因为还没有商品添加到购物车中。

有趣的是 DataList 的 HTML 代码。让我们来看看。

<asp:DataList Height="100%" Width="100%" ID="dlToys" runat="server" 
              RepeatColumns="3" CellPadding="20" CellSpacing="20"> 
<ItemTemplate> 
    <div ID="a" runat = "server" class="dragElement"> 
        <asp:Label ID="lblTitle" runat=
            "server" Text='<%# Eval("Title") %>' /> 
        <asp:Label ID="lblPrice" runat="server" Text = 
            '<%# Eval("Price") %>' /> 
        <asp:Image ID="imgPicture" runat="server" ImageUrl=
           '<%# Eval("ImageUrl") %>' /> 
    </div> 
</ItemTemplate> 
</asp:DataList>

如您在上面的代码中所见,我在 DataList 控件的 ItemTemplate 中添加了一个 <DIV> 元素。这意味着每个产品都包含在 <DIV> 元素内,该元素将作为可拖放对象。由于添加了 runat="server" 属性,<DIV> 控件将具有唯一的 ID。 ASP.NET 将在运行时分配唯一的 ID,如下所示

使元素可拖放

此时我们知道我们的 DIV 元素将充当可拖放对象。但是页面上可能有很多 DIV 控件不是此拖放功能的一部分。我们将使用正则表达式来过滤正确的 DIV 元素。

<script> 
var dragElementPattern = ".+_a$"; 
var divElements = document.getElementsByTagName("div"); 

for(i=0;i<divElements.length;i++) 
{ 
    if(IsMatch(divElements[i].id, dragElementPattern)) 
    { 
        MakeElementDraggable(divElements[i]); 
    } 
} 
</script>

首先,我检索页面上的所有 DIV 元素,然后使用正则表达式找到正确的元素。IsMatch 函数负责将元素的 ID 与模式进行匹配。

function IsMatch(id, pattern) 
{ 
    var regularExpresssion = new RegExp(pattern); 
    if(id.match(regularExpresssion)) return true; 
    else return false; 
} 

拖动克隆的元素

克隆拖动元素对于获得正确的视觉效果是必要的。如果您不克隆元素,您将移动实际元素本身,这看起来有点奇怪。看看我没有克隆就移动了实际元素的屏幕截图。

当克隆被创建时,效果如下。

这是启动拖动并创建克隆的代码。

function InitiateDrag(e) 
{ 
    mouseState = 'down'; 

    var evt = e || window.event; 

    startX = parseInt(evt.clientX); 
    startY = parseInt(evt.clientY); 

    clone = obj.cloneNode(true); 

    clone.style.position = 'absolute'; 
    clone.style.top = parseInt(startY) + 'px'; 
    clone.style.left = parseInt(startX) + 'px'; 

    document.body.appendChild(clone); 

    document.onmousemove = Drag; 
    document.onmouseup = Drop; 

    return false; 
}

将元素拖放到放置区域

我花费了一些时间来创建一个跨浏览器的放置区域事件。只有当产品被放置在放置区域内时,放置才算成功。在我的文章“使用 JavaScript 进行拖放”中,我使用了父级方法,根据鼠标位置找到元素。但不幸的是,该方法不跨浏览器兼容。这里讨论的方法是跨浏览器兼容的,并且基于鼠标位置和页面上的放置区域位置。看看下面的图表,它解释了如何获取放置区域的位置。

这是将产品放入放置区域的代码

function Drop(e) 
{ 
    var evt = e || window.event; 
    var evtTarget = evt.target || evt.srcElement; 

    var dZone = document.getElementById("dZone"); 

    if( evt.clientX > dZone.offsetLeft && 
        evt.clientX < (dZone.offsetLeft + dZone.offsetWidth) && 
        evt.clientY > dZone.offsetTop && 
        evt.clientY < (dZone.offsetTop + dZone.offsetHeight)) 
    { 
        AddPrice(); 
    } 

    document.onmouseup = null; 
    document.onmousemove = null; 

    document.body.removeChild(clone); 
    mouseState = 'up'; 
    ResetColor(); 
} 

如果产品不在放置区域内,则产品会消失。但是,如果产品在放置区域内,它将被添加到购物车中。

将产品添加到购物车

AddPrice 函数负责更新总价和购物车显示。每个产品都嵌入在 DIV 元素中,该 DIV 元素稍后将被添加到 DropZone DIV 容器中。

function AddPrice() 
{ 

    var title = GetProductTitle(); 
    var price = GetProductPrice(); 


    var dZone = document.getElementById("dZone"); 
    var textNode = document.createTextNode(title); 
    var priceNode = document.createTextNode(price); 

    var spaceNode = document.createTextNode(': $'); 
    var paragraphElement = document.createElement('p'); 

    // create the delete button 


    var deleteButton = document.createElement('button'); 
    deleteButton.value = 'Delete'; 
    deleteButton.innerHTML = 'Delete'; 
    deleteButton.onclick = DeleteItem; 

    var item = document.createElement('div'); 
    item.id = 'itemDiv' + uniqueNumber; 

    item.appendChild(paragraphElement); 
    item.appendChild(textNode); 
    item.appendChild(spaceNode); 
    item.appendChild(priceNode); 
    item.appendChild(spaceNode); 
    item.appendChild(deleteButton); 

    dZone.appendChild(item); 

    // increment the price 

    IncrementTotal(price); 
    uniqueNumber++; 

} 

GetProductTitleGetProductPrice 用于从可拖放产品中检索名称和价格。uniqueNumber 是一个全局变量,用于为新创建的 DIV 元素创建唯一的 ID。每次将新产品添加到放置区域时,uniqueNumber 都会递增。IncrementTotal 函数用于将产品的价格加到总价中。

看看下面的图片,它显示了两个添加到购物车中的产品。

从购物车中删除商品

一旦产品添加到购物车,它将显示一个删除按钮。删除按钮用于从购物车中移除产品并调整总金额。

function DeleteItem(e) 
{ 
    var evt = e || window.event; 
    var evtTarget = evt.target || evt.srcElement; 

    if(IsFireFox()) 
    { 
        price = evtTarget.parentNode.childNodes[2].nodeValue; 
        evtTarget.parentNode.parentNode.removeChild(evtTarget.parentNode); 
    } 
    else 
    { 
        price = evtTarget.parentElement.childNodes[2].nodeValue; 
        evtTarget.parentElement.parentElement.removeChild(
            evtTarget.parentElement); 
    } 

    DecrementTotal(price); 
} 

由于不同浏览器访问子节点的方式不同,我创建了一个 IsFireFox 函数,如果用户使用的是 FireFox 浏览器,则返回 true。首先,我们检索产品的价格,然后从购物车中删除该产品。最后,调用 DecrementTotal 来调整总金额。

改进

我在几个地方使用了常量索引来定位容器内的项目。这些应该被动态访问项目所取代。我包括了:一个结账功能,选择多个商品的能力,在购物车内查看商品图片的能力。

推荐阅读

  1. Mohammad Azam 的使用 JavaScript 进行拖放

结论

在本文中,我们学习了如何创建可拖放对象并将它们放入购物车。

希望您喜欢这篇文章,祝您编码愉快!

© . All rights reserved.