现在一直使用vue写项目,发现之前的js都很生疏了,写个小demo练下手,看一下最终效果展示
功能点:点击添加图片随机添加一张图片,图片可以拖动,可以点击删除
技能点: 主要使用了jQuery的一些方法
下面就一步一步来实现它吧
一开始我想做一个按钮可以让用户自己上传图片,结果写了之后发现没有图片上传的服务接口,也懒得去找了,就直接使用本地的图片了,这里也把图片上传的功能写一下,如果你有图片上传的api可以直接使用
 
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="./sass/index.css">
<script src="https://code.jquery.com/jquery-3.4.1.min.js"></script>
</head> <body>
<div class="meaasge_contanier">
<ul class="picture_list">
<div class="upload">
<div class="plus">添加照片</div>
<input id="filebtn" type="file" accept="image/gif, image/jpeg">
</div>
</ul>
</div>
</body>
<script type="text/javascript">
$(function () {
// 如果有后台图片接口,可以使用文件上传
$('.plus').on('click', function (e) {
// 点击添加照片,触发input上传事件
if ($('#filebtn')) {
$('#filebtn').click()
}
e.preventDefault()
})
$('#filebtn').change(function () {
// input内容改变时,拿到文件,传给后台获取线上图片地址
const file = $('#filebtn')[0].files
console.log(777, file)
$.ajax({
url: '',
.....
})
})
})
</script>
</html>
这里我用的是本地的图片,写了一个img.js,在里面放了一些图片,图片地址都是百度找的
img.js
  var list = [
{
"id": 0,
"name": "1",
"date": "2017-5-26",
"url": "http://img4.imgtn.bdimg.com/it/u=1433191751,1566568157&fm=26&gp=0.jpg"
},
...
]
 
接着写一个点击事件,点击添加照片的按钮网页面上加一张图片
html的写法不变,把input标签去掉,这里不需要用户上传
script写法
先把图片文件引入,这样可以拿到图片地址数组
<script src="./img.js"></script>
<script type="text/javascript">
$(function () {
// 添加图片
$('.plus').click(function () {
const liList = $('.picture_list .item')
// 限制图片不能多于30张
if (liList && liList.length > 30) {
window.alert('图片太多啦,先删掉一些图片')
return
} // 设置初始的top和left值
let liTop = 150
let liLeft = 100
if (liList && liList.length) {
// 获取最后一个li的位置
let lastLi = $('.picture_list li:last-child')
let t = Number(lastLi.css('top').replace('px', ''))
let l = Number(lastLi.css('left').replace('px', '')) // 图片心型排列方法
let length = liList.length
if (length < 9) { // 右下走向
liTop = t + 30
liLeft = l + 30
} else if (length > 8 && length < 17) { // 右上走向
liTop = t - 30
liLeft = l + 30
} else if (length > 16 && length < 23) { // 左下走向
if (length === 17) {
liLeft = l - 60
} else liLeft = l - 30
liTop = t + 30
} else if (length > 22) { // 左上走向
liTop = t - 30
liLeft = l - 30
}
}
// console.log(index, liList)
// 生成一个图片
// 准备了7张图片,这里生成0-6的随机数,用于取图
let index = Math.round(Math.random() * 10)
if (index > 6) {
index = Math.round(index * 0.6)
}
const url = list[index].url
// 添加到ul中
if (!liList || liList.length < 31) {
const li = $(`<li class="item"><div class="delete">x</div><img src="${url}" /></li>`).css({
'top': liTop,
'left': liLeft
})
$('.picture_list').append(li)
}
})
})
</script>
看一下效果:
 
现在加上图片的移动和删除看看,加了图片的移动后,图片的位置就发生改动,使用上面的排列方式就没有意义.添加图片时我就直接在最后一张图片后偏移一点.这里需要限制一下图片的top和left的最大最小值,以免超出墙壁范围
 
<script type="text/javascript">
$(function () {
// 添加图片
$('.plus').click(function () {
const liList = $('.picture_list .item')
if (liList && liList.length > 30) {
window.alert('图片太多啦,先删掉一些图片')
return
}
// 准备了7张图片,这里生成0-6的随机数,用于取图
let index = Math.round(Math.random() * 10)
if (index > 6) {
index = Math.round(index * 0.6)
}
// 设置初始的top和left值
let liTop = 150
let liLeft = 100
if (liList && liList.length) {
// 获取最后一个li的位置
let lastLi = $('.picture_list li:last-child')
let t = Number(lastLi.css('top').replace('px', ''))
let l = Number(lastLi.css('left').replace('px', ''))
console.log(lastLi, t, l)
// 图片边界判断,让生成的图片位置在一定范围
l = l < 100 ? 100 : l
l = l > contanier.width() - lastLi.width() - 100 ? 100 : l
t = t < 100 ? 100 : t
t = t > contanier.height() - lastLi.height() - 100 ? 100 : t
// 每次图片都在上一张的基础上排列
liTop = t + 30
liLeft = l + 30
}
// console.log(index, liList)
// 生成一个图片
const url = list[index].url
if (!liList || liList.length < 31) {
const li = $(`<li class="item"><div class="delete">x</div><img src="${url}" /></li>`).css({
'top': liTop,
'left': liLeft
})
$('.picture_list').append(li)
}
}) // 图片的盒子li标签是动态生成的,在绑定事件时不能直接绑定在li标签上,绑定在它的父元素上
// 图片移动
let pictureList = $('.picture_list')
let contanier = $('.meaasge_contanier')
pictureList.on('mousedown', '.item', function (e) {
e.preventDefault()
// 让点击的图片在第一层级
let arr = Array.from($('.item'))
arr.forEach(item => {
$(item).css({
zIndex: 0
})
})
let item = $(this)
$(item).css({
zIndex: 99
})
// 获取当前位置的clientX,和当前图片的top值,left值,得到它们相减部分的值
const disX = e.clientX - item[0].offsetLeft
const disY = e.clientY - item[0].offsetTop contanier.mousemove(function (event) {
event.preventDefault()
// 用移动时的位置的clientX减去初始的差值,就得到现在的top值与left值
let x = event.clientX - disX
let y = event.clientY - disY
x = x < 0 ? 0 : x
x = x > contanier.width() - item.width() ? contanier.width() - item.width() : x
y = y < 0 ? 0 : y
y = y > contanier.height() - item.height() ? contanier.height() - item.height() : y
item.css({
top: y,
left: x
})
})
// 鼠标移出盒子停止图片移动
contanier.mouseout(function () {
contanier.off('mousemove')
contanier.off('mouseup')
})
// 鼠标弹起停止图片移动
contanier.mouseup(function () {
contanier.off('mousemove')
contanier.off('mouseup')
})
}) // 图片删除
// 图片和删除按钮都是动态添加的,都需要用on绑定事件
pictureList.on('click', '.delete', function () {
// 删除当前点击的图片
$(this).parent('.item').remove()
})
// 鼠标移入,删除按钮展示
pictureList.on('mouseover', '.item', function () {
$(this).children('.delete').show()
})
// 鼠标移出,删除按钮隐藏
pictureList.on('mouseout', '.item', function () {
$(this).children('.delete').hide()
})
})
</script>

最终的效果:

css代码

li {
list-style: none;
}
.meaasge_contanier {
width: 800px;
height: 600px;
margin: 100px auto 0;
background-color: sienna;
position: relative;
background: url('../img/board.jpg');
border: 3px solid #a25124;
border-radius: 10px;
box-shadow: 3px 3px 5px #a25124;
}
.meaasge_contanier .upload {
width: 120px;
height: 40px;
position: absolute;
top: 5px;
left: 5px;
text-align: center;
}
.meaasge_contanier .upload .plus {
width: 100%;
height: 100%;
text-align: center;
line-height: 40px;
position: absolute;
background-color: #eee;
cursor: pointer;
border-radius: 5px;
}
.meaasge_contanier .upload input {
width: 150px;
overflow: hidden;
}
.meaasge_contanier .picture_list .item {
width: 100px;
position: absolute;
box-shadow: 2px 2px 3px rgba(0, 0, 0, 0.3);
}
.meaasge_contanier .picture_list .item img {
width: 100%;
}
.meaasge_contanier .picture_list .item .delete {
position: absolute;
width: 20px;
height: 20px;
line-height: 17px;
text-align: center;
border-radius: 50%;
background-color: #909399;
color: #fff;
font-size: 12px;
top: -5px;
right: -5px;
display: none;
cursor: default;
}

jQuery实现照片墙,附步骤详解的更多相关文章

  1. vue-cli搭建项目引入jquery和jquery-weui步骤详解

    vue简介 Vue.js 是一套用于构建用户界面的渐进式框架.与其它大型框架不同的是,Vue 被设计为可以自底向上逐层应用. Vue 的核心库只关注视图层,不仅易于上手,还便于与第三方库或既有项目整合 ...

  2. jquery $.trim()去除字符串空格详解

    jquery $.trim()去除字符串空格详解 语法 jQuery.trim()函数用于去除字符串两端的空白字符. 作用 该函数可以去除字符串开始和末尾两端的空白字符(直到遇到第一个非空白字符串为止 ...

  3. ASP.NET连接Oracle数据库的步骤详解(转)

    ASP.NET连接Oracle数据库的步骤详解   本文我们主要介绍了ASP.NET连接Oracle数据库的步骤及每个步骤需要进行的设置,希望能够对您有所帮助.   在用ASP.NET开发应用程序时, ...

  4. Oracle 11g客户端在Linux系统上的配置步骤详解

    Oracle 11g客户端在Linux系统上的配置步骤详解 2011-07-26 10:47 newhappy2008 CSDN博客 字号:T | T 本文我们主要介绍了Oracle 11g客户端在L ...

  5. centos6.4安装配置vpn服务器步骤详解

      centos6.4安装配置vpn服务器步骤详解,从安装VPN到配置VPN服务器.配置VPN服务器的路由转发功能,每一步都很详细   一.VPN服务器环境说明 操作系统:CentOS release ...

  6. MD5算法步骤详解

    转自MD5算法步骤详解 之前要写一个MD5程序,但是从网络上看到的资料基本上一样,只是讲了一个大概.经过我自己的实践,我决定写一个心得,给需要实现MD5,但又不要求很高深的编程知识的童鞋参考.不多说了 ...

  7. EA创建用例图步骤详解

    EA创建用例图步骤详解 1 创建一个项目 2 选择需要的模型 3 新建模型包 4 新建图表 5 新建模型包 6 创建用户角色Actor 7 新建用例 8 关联用户和用例 9 最后整个项目浏览器目录结构 ...

  8. gcc/g++等编译器 编译原理: 预处理,编译,汇编,链接各步骤详解

    摘自http://blog.csdn.net/elfprincexu/article/details/45043971 gcc/g++等编译器 编译原理: 预处理,编译,汇编,链接各步骤详解 C和C+ ...

  9. CentOS7/RHEL7安装Redis步骤详解

    CentOS7/RHEL7安装Redis步骤详解 CentOS7/RHEL7安装Redis还是头一次测试安装了,因为centos7升级之后与centos6有比较大的区别了,下面我们就一起来看看Cent ...

随机推荐

  1. Selenium 2自动化测试实战36(更易读的测试报告)

    一.更易读的测试报告 1.知识点:python的注释. 1.一种叫comment,为普通的注释2.另一种叫doc string,用于函数,类和方法的描述.在类或方法的下方,通过三引号("&q ...

  2. hive简单学习---1

    ---------------------------------------------------------------------------------------------------- ...

  3. php获取服务器ip方法

    public static function getServerIp() { if(!empty($_SERVER['SERVER_ADDR'])) { return $_SERVER['SERVER ...

  4. Docker在PHP项目开发环境中的应用

    http://avnpc.com/pages/build-php-develop-env-by-docker

  5. Linux(centos)安装vim

    当在Linux环境下使用vim提示: vim command not found时,说明系统还没有安装vim. 安装步骤: 1.检查是否已安装 查看一下你本机已经存在的包,确认一下你的VIM是否已经安 ...

  6. What's binary search?

    Binary Search: Search a sorted array by repeatedly  dividing the search interval in half. Begin with ...

  7. 【使用新版mysql驱动的改变】---记忆犹新

    关于 版本的问题: 之前安装数据库的时候  安装的mysql 8.0  脚本文件来自5.7 的数据库 maven版本3.5.3 jdk1.8 tomcat 9 跑maven项目的时候  遇到各种问题 ...

  8. 【FIORI系列】SAP 一文读懂SAP Fiori是什么

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[FIORI系列]SAP 一文读懂SAP Fio ...

  9. Leetcode之动态规划(DP)专题-198. 打家劫舍(House Robber)

    Leetcode之动态规划(DP)专题-198. 打家劫舍(House Robber) 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互 ...

  10. 深入理解C语言-深入理解void

    void的字面意思是"无类型",void *则为"无类型指针",void *可以指向任何类型的数据 void含义 void几乎只有注释和限制程序的作用,定义一个 ...