viewer.js 显示图片名称和照片属性
显示效果:
中间显示照片名称,右侧显示照片属性。
图片名称是保存在数据库里的,照片属性是相机或手机拍照时就存储于照片格式中的。
手机照片甚至保存了经纬度等详细信息(这也是QQ能实现旅游相册的原因)。
ADO.net MVC 部分视图 ViewPhotoWithAttr,也就是功能模块化。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 | <link href= "~/Scripts/viewer/viewer.min.css?v=20190612" rel= "stylesheet" /> <script src= "~/Scripts/viewer/viewer.min.js?v=20190612" ></script> <style type= "text/css" > .photo-with-attr-container { position: fixed ; bottom: 0; left: 0; right: 0; top: 0; z-index: 999999; background-color: rgba(0, 0, 0, 0.7); } .photo-with-attr-container .photo-container { float : left; height: 100%; width: calc(100% - 300px); } .photo-with-attr-container .attr-container { float : right; height: 100%; width: 300px; background: white; } .photo-with-attr-container .attr-container .image-attr-title span { margin: 10px; } .photo-with-attr-container .attr-container .image-attr-title { padding:16px; border-bottom: 1px solid #ebeef5; } .photo-with-attr-container .attr-container .image-attr-content { padding: 10px; height: calc(100% - 50px); width: 300px; position: absolute; } .photo-with-attr-container .attr-container .el-scrollbar__wrap { overflow-x: hidden; } .image-attr-content .ivu-form-item{ margin-bottom: 0px; } </style> <script type= "text/x-template" id= "viewerTemplate" > <div style= "visibility:hidden" > <div ref = "left" > <div role= "button" class = "viewer-button viewer-close" data-viewer-action= "mix" @@click= "hide" /> <div class = "image-attr-title" > <label>照片属性</label> </div> <div class = "image-attr-content" > <div style= "height:100%;" > <card v- for = "item in currentAttr" v-bind:key= "item.Name" style= "margin-bottom:8px;width:100%;" > <div slot= "title" class = "clearfix" > <span>{{ item.Name }}</span> </div> <div> <i-form label-width= "90" size= "mini" > <form-item v- for = "imageAttr in item.AttrList" v-bind:key= "imageAttr.Name" v-bind:label= "imageAttr.Name" > <label> {{ imageAttr.Value }}</label> </form-item> </i-form> </div> </card> </div> </div> </div> </div> </script> <script type= "text/javascript" > Vue.component( "ViewPhotoWithAttr" ,{ template: "#viewerTemplate" , name: 'ViewPhotoWithAttr' , props: { imageList: { type: Array, default : null } }, data() { return { viewer: null , containerEl: null , visible: false , currentImage: {}, currentAttr: [] } }, watch: { imageList() { }, 'currentImage.id' (id) { var that = this var srcPart = '@Url.Action("ImageAttr", "Image")' + '/' ; this .$http({ url: srcPart + id, method: 'get' }).then(function (response) { if (response.data.success) { that.currentAttr = response.data.data } }) }, visible(val) { var el = this .containerEl if (el) { el.style.visibility = val ? 'visible' : 'hidden' } } }, mounted() { // 'viewer-title' }, destroyed() { this .destroy() }, methods: { init() { var body = document.body this .destroy() var container = document.createElement( 'div' ) container.className = 'photo-with-attr-container' container.style.visibility = 'hidden' var imageContainer = document.createElement( 'div' ) imageContainer.className = 'photo-container' var imagesEl = document.createElement( 'div' ) imagesEl.style.display = 'none' for ( var item of this .imageList) { var image = document.createElement( 'img' ) image.src = item.imageUrlSmall image.alt = item.picName; imagesEl.appendChild(image) } imageContainer.appendChild(imagesEl) container.appendChild(imageContainer) var attrContainer = document.createElement( 'div' ) attrContainer.className = 'attr-container' attrContainer.appendChild( this .$refs.left) container.appendChild(attrContainer) body.appendChild(container) // var el = this.$refs.images var that = this var viewer = new Viewer(imagesEl, { fullscreen: true , inline: true , title: function (img, obj) { return img.getAttribute( "alt" ); }, container: imageContainer, url(image) { var src = image.getAttribute( "src" ); var item = that.imageList.filter(d => d.imageUrlSmall === src)[0] return item.imageUrl }, hide() { that.visible = false }, hidden() { that.visible = false }, view(image) { var src = image.detail.image.getAttribute( "src" ); var item = that.imageList.filter(d => d.imageUrl === src)[0] that.currentImage = item console.log(that.currentImage) } }) this .viewer = viewer this .containerEl = container }, destroy() { if ( this .viewer) { this .viewer.destroy() } var body = document.body var container = document.getElementsByClassName( 'photo-with-attr-container' ) if (container && container.length > 0) { for ( var item of container) { body.removeChild(item) } } this .containerEl = null this .viewer = null }, hide() { // this.viewer.exit() this .destroy() var that = this this .$nextTick(function() { that.visible = false }) }, view(index) { this .visible = true if (! this .viewer) { this .init() } var that = this this .$nextTick(function(){ that.viewer.view(index) }) } } }) </script> |
图片名称显示部分代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | imageList: { type: Array, default : null } for ( var item of this .imageList) { var image = document.createElement( 'img' ) image.src = item.imageUrlSmall image.alt = item.picName; //对alt属性赋值 imagesEl.appendChild(image) } title: function (img, obj) { // 这里实现显示图片名称 return img.getAttribute( "alt" ); }, |
在另一个页面中使用,仅用于示意,并非完整代码,实现了iview轮播图上点击后出现viewer大图轮播图。感觉有点重复,但确实有这个需求。

<style> .carousel-text{ position: relative; bottom: 25px; width: 100%; font-size:13px; /*width: auto;*/ /*也可以*/ text-align: center; color: white; background-color: rgba(0,0,0,0.3); } </style> <div class="container"> <div id="dowebok_qm"> <Carousel v-bind:radius-dot="carouselDot_qm" dots="outside" v-bind:height="imgHeight2+'px'" v-model="carouselValue_qm" style="text-align:center;"> <div v-for="item in imgData_qm" v-on:click="handleView_qm(item)"> <Carousel-Item> <img v-bind:src="item.src" style="height:inherit;width:auto;cursor:pointer;" /> <div><span class="carousel-text"> {{item.textName}}</span></div> </Carousel-Item> </div> </Carousel> </div> </div> <ViewPhotoWithAttr ref="viewerYd_qm" v-bind:image-list="imgData_qm" /> var vm = new Vue({ template: "#viewTemplate", el: '#app', data: { imgHeight2:600, carouselDot_qm: false, carouselValue_qm: 0, imgData_qm: [], } methods: { handleView_qm: function (info) { //用于点击时定位 console.log('handleViewYd', info.id); var index = 0 for (var i = 0; i < this.imgData_qm.length; i++) { if (this.imgData_qm[i].id === info.id) { index = i break } } console.log('index', index); this.$refs.viewerYd_qm.view(index) }, getImageListByID: function (dataID) { var that=this; //由于ajax中的this不等于vue的this,所以赋值为that; that.imgData_qm = []; $.ajax({ url: url, type: 'POST', data: { dataID: dataID.toString() }, success: function (result) { let imageList = result.rows; var srcPart=“url前缀”; that.imgData_qm.push({ id: imageList[i].ImageID, src: srcPart + imageList[i].ImageID + part, name: imageList[i].FileName, textName: picName, imageUrlSmall: srcPart + imageList[i].ImageID + part, imageUrl: srcPart + imageList[i].ImageID }) }}) } } })
相关文章:
1 官方文档: https://github.com/fengyuanchen/viewerjs
2 viewer 简单用法:
viewer 图片点击放大 用法汇总
https://www.cnblogs.com/hao-1234-1234/p/11011249.html
viewer与 iview Carousel(走马灯) 结合使用,图片无法显示
https://www.cnblogs.com/hao-1234-1234/p/11252183.html
树立目标,保持活力,gogogo!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2019-01-09 ABP框架 sql语句(转载)