首页 技术 正文
技术 2022年11月7日
0 收藏 567 点赞 775 浏览 17220 个字

最近公司做一个项目需要360度展示汽车的外观,就用到了threesixty.min.js,自己总结一下使用方法:

treesixty.min.js 源码:

/*! threesixty-slider 2015-01-06 verison 2.0.5 */
/* http://github.com/vml-webdev/threesixty-slider.git */
!function (a) {
"use strict";
a.ThreeSixty = function (b, c) {
var d, e = this, f = [];
e.$el = a(b), e.el = b, e.$el.data("ThreeSixty", e), e.init = function () {
d = a.extend({}, a.ThreeSixty.defaultOptions, c), d.disableSpin && (d.currentFrame = 1, d.endFrame = 1), e.initProgress(), e.loadImages()
}, e.resize = function () {
}, e.initProgress = function () {
e.$el.css({
width: d.width,
height: d.height,
"background-image": "none !important"
}), d.styles && e.$el.css(d.styles), e.responsive(), e.$el.find(d.progress).css({marginTop: d.height / 2 - 15 + "px"}), e.$el.find(d.progress).fadeIn("slow"), e.$el.find(d.imgList).hide()
}, e.loadImages = function () {
var b, c, g, h;
b = document.createElement("li"), h = d.zeroBased ? 0 : 1, c = d.imgArray ? d.imgArray[d.loadedImages] : d.domain + d.imagePath + d.filePrefix + e.zeroPad(d.loadedImages + h) + d.ext + (e.browser.isIE() ? "?" + (new Date).getTime() : ""), g = a("<img>").attr("src", c).addClass("previous-image").appendTo(b), f.push(g), e.$el.find(d.imgList).append(b), a(g).load(function () {
e.imageLoaded()
})
}, e.imageLoaded = function () {
d.loadedImages += 1, a(d.progress + " span").text(Math.floor(100 * (d.loadedImages / d.totalFrames)) + "%"), d.loadedImages >= d.totalFrames ? (d.disableSpin && f[0].removeClass("previous-image").addClass("current-image"), a(d.progress).fadeOut("slow", function () {
a(this).hide(), e.showImages(), e.showNavigation()
})) : e.loadImages()
}, e.showImages = function () {
e.$el.find(".txtC").fadeIn(), e.$el.find(d.imgList).fadeIn(), e.ready = !0, d.ready = !0, d.drag && e.initEvents(), e.refresh(), e.initPlugins(), d.onReady(), setTimeout(function () {
e.responsive()
}, 50)
}, e.initPlugins = function () {
a.each(d.plugins, function (b, c) {
if ("function" != typeof a[c])throw new Error(c + " not available.");
a[c].call(e, e.$el, d)
})
}, e.showNavigation = function () {
if (d.navigation && !d.navigation_init) {
var b, c, f, g;
b = a("<div/>").attr("class", "nav_bar"), c = a("<a/>").attr({
href: "#",
"class": "nav_bar_next"
}).html("next"), f = a("<a/>").attr({
href: "#",
"class": "nav_bar_previous"
}).html("previous"), g = a("<a/>").attr({
href: "#",
"class": "nav_bar_play"
}).html("play"), b.append(f), b.append(g), b.append(c), e.$el.prepend(b), c.bind("mousedown touchstart", e.next), f.bind("mousedown touchstart", e.previous), g.bind("mousedown touchstart", e.play_stop), d.navigation_init = !0
}
}, e.play_stop = function (b) {
b.preventDefault(), d.autoplay ? (d.autoplay = !1, a(b.currentTarget).removeClass("nav_bar_stop").addClass("nav_bar_play"), clearInterval(d.play), d.play = null) : (d.autoplay = !0, d.play = setInterval(e.moveToNextFrame, d.playSpeed), a(b.currentTarget).removeClass("nav_bar_play").addClass("nav_bar_stop"))
}, e.next = function (a) {
a && a.preventDefault(), d.endFrame -= 5, e.refresh()
}, e.previous = function (a) {
a && a.preventDefault(), d.endFrame += 5, e.refresh()
}, e.play = function (a) {
var b = a || d.playSpeed;
d.autoplay || (d.autoplay = !0, d.play = setInterval(e.moveToNextFrame, b))
}, e.stop = function () {
d.autoplay && (d.autoplay = !1, clearInterval(d.play), d.play = null)
}, e.moveToNextFrame = function () {
1 === d.autoplayDirection ? d.endFrame -= 1 : d.endFrame += 1, e.refresh()
}, e.gotoAndPlay = function (a) {
if (d.disableWrap)d.endFrame = a, e.refresh(); else {
var b = Math.ceil(d.endFrame / d.totalFrames);
0 === b && (b = 1);
var c = b > 1 ? d.endFrame - (b - 1) * d.totalFrames : d.endFrame, f = d.totalFrames - c, g = 0;
g = a - c > 0 ? a - c < c + (d.totalFrames - a) ? d.endFrame + (a - c) : d.endFrame - (c + (d.totalFrames - a)) : f + a > c - a ? d.endFrame - (c - a) : d.endFrame + (f + a), c !== a && (d.endFrame = g, e.refresh())
}
}, e.initEvents = function () {
e.$el.bind("mousedown touchstart touchmove touchend mousemove click", function (a) {
a.preventDefault(), "mousedown" === a.type && 1 === a.which || "touchstart" === a.type ? (d.pointerStartPosX = e.getPointerEvent(a).pageX, d.dragging = !0) : "touchmove" === a.type ? e.trackPointer(a) : "touchend" === a.type && (d.dragging = !1)
}), a(document).bind("mouseup", function () {
d.dragging = !1, a(this).css("cursor", "none")
}), a(window).bind("resize", function () {
e.responsive()
}), a(document).bind("mousemove", function (a) {
d.dragging ? (a.preventDefault(), !e.browser.isIE && d.showCursor && e.$el.css("cursor", "url(assets/images/hand_closed.png), auto")) : !e.browser.isIE && d.showCursor && e.$el.css("cursor", "url(assets/images/hand_open.png), auto"), e.trackPointer(a)
}), a(window).resize(function () {
e.resize()
})
}, e.getPointerEvent = function (a) {
return a.originalEvent.targetTouches ? a.originalEvent.targetTouches[0] : a
}, e.trackPointer = function (a) {
d.ready && d.dragging && (d.pointerEndPosX = e.getPointerEvent(a).pageX, d.monitorStartTime < (new Date).getTime() - d.monitorInt && (d.pointerDistance = d.pointerEndPosX - d.pointerStartPosX, d.endFrame = d.pointerDistance > 0 ? d.currentFrame + Math.ceil((d.totalFrames - 1) * d.speedMultiplier * (d.pointerDistance / e.$el.width())) : d.currentFrame + Math.floor((d.totalFrames - 1) * d.speedMultiplier * (d.pointerDistance / e.$el.width())), d.disableWrap && (d.endFrame = Math.min(d.totalFrames - (d.zeroBased ? 1 : 0), d.endFrame), d.endFrame = Math.max(d.zeroBased ? 0 : 1, d.endFrame)), e.refresh(), d.monitorStartTime = (new Date).getTime(), d.pointerStartPosX = e.getPointerEvent(a).pageX))
}, e.refresh = function () {
0 === d.ticker && (d.ticker = setInterval(e.render, Math.round(1e3 / d.framerate)))
}, e.render = function () {
var a;
d.currentFrame !== d.endFrame ? (a = d.endFrame < d.currentFrame ? Math.floor(.1 * (d.endFrame - d.currentFrame)) : Math.ceil(.1 * (d.endFrame - d.currentFrame)), e.hidePreviousFrame(), d.currentFrame += a, e.showCurrentFrame(), e.$el.trigger("frameIndexChanged", [e.getNormalizedCurrentFrame(), d.totalFrames])) : (window.clearInterval(d.ticker), d.ticker = 0)
}, e.hidePreviousFrame = function () {
f[e.getNormalizedCurrentFrame()].removeClass("current-image").addClass("previous-image")
}, e.showCurrentFrame = function () {
f[e.getNormalizedCurrentFrame()].removeClass("previous-image").addClass("current-image")
}, e.getNormalizedCurrentFrame = function () {
var a, b;
return d.disableWrap ? (a = Math.min(d.currentFrame, d.totalFrames - (d.zeroBased ? 1 : 0)), b = Math.min(d.endFrame, d.totalFrames - (d.zeroBased ? 1 : 0)), a = Math.max(a, d.zeroBased ? 0 : 1), b = Math.max(b, d.zeroBased ? 0 : 1), d.currentFrame = a, d.endFrame = b) : (a = Math.ceil(d.currentFrame % d.totalFrames), 0 > a && (a += d.totalFrames - (d.zeroBased ? 1 : 0))), a
}, e.getCurrentFrame = function () {
return d.currentFrame
}, e.responsive = function () {
d.responsive && e.$el.css({height: e.$el.find(".current-image").first().css("height"), width: "100%"})
}, e.zeroPad = function (a) {
function b(a, b) {
var c = a.toString();
if (d.zeroPadding)for (; c.length < b;)c = "0" + c;
return c
} var c = Math.log(d.totalFrames) / Math.LN10, e = 1e3, f = Math.round(c * e) / e, g = Math.floor(f) + 1;
return b(a, g)
}, e.browser = {}, e.browser.isIE = function () {
var a = -1;
if ("Microsoft Internet Explorer" === navigator.appName) {
var b = navigator.userAgent, c = new RegExp("MSIE ([0-9]{1,}[\\.0-9]{0,})");
null !== c.exec(b) && (a = parseFloat(RegExp.$1))
}
return -1 !== a
}, e.getConfig = function () {
return d
}, a.ThreeSixty.defaultOptions = {
dragging: !1,
ready: !1,
pointerStartPosX: 0,
pointerEndPosX: 0,
pointerDistance: 0,
monitorStartTime: 0,
monitorInt: 10,
ticker: 0,
speedMultiplier: 7,
totalFrames: 180,
currentFrame: 0,
endFrame: 0,
loadedImages: 0,
framerate: 60,
domains: null,
domain: "",
parallel: !1,
queueAmount: 8,
idle: 0,
filePrefix: "",
ext: "png",
height: "300px",
width: "300px",
styles: {},
navigation: !1,
autoplay: !1,
autoplayDirection: 1,
disableSpin: !1,
disableWrap: !1,
responsive: !1,
zeroPadding: !1,
zeroBased: !1,
plugins: [],
showCursor: !1,
drag: !0,
onReady: function () {
},
imgList: ".threesixty_images",
imgArray: null,
playSpeed: 100
}, e.init()
}, a.fn.ThreeSixty = function (b) {
return Object.create(new a.ThreeSixty(this, b))
}
}(jQuery), "function" != typeof Object.create && (Object.create = function (a) {
"use strict";
function b() {
} return b.prototype = a, new b
});

 

treesixty.css 源码

.threesixty {
position: relative;
overflow: hidden;
margin: 0 auto;
}
.threesixty .threesixty_images {
display: none;
list-style: none;
margin:;
padding:;
}
.threesixty .threesixty_images img {
position: absolute;
top:;
width: 100%;
height: auto;
}
.threesixty .threesixty_images img.previous-image {
visibility: hidden;
width:;
}
.threesixty .threesixty_images img.current-image {
visibility: visible;
width: 100%;
}
.threesixty .spinner {
width: 60px;
display: block;
margin: 0 auto;
height: 30px;
background: #333;
background: rgba(0, 0, 0, 0.7);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
border-radius: 5px;
}
.threesixty .spinner span {
font-family: Arial, "MS Trebuchet", sans-serif;
font-size: 12px;
font-weight: bolder;
color: #FFF;
text-align: center;
line-height: 30px;
display: block;
}
.threesixty .nav_bar {
position: absolute;
top: 10px;
right: 10px;
z-index:;
}
.threesixty .nav_bar a {
display: block;
width: 32px;
height: 32px;
float: left; text-indent: -99999px;
}
.threesixty .nav_bar a.nav_bar_play {
background-position: 0 0 !important;
}
.threesixty .nav_bar a.nav_bar_previous {
background-position: 0 -73px !important;
}
.threesixty .nav_bar a.nav_bar_stop {
background-position: 0 -37px !important;
}
.threesixty .nav_bar a.nav_bar_next {
background-position: 0 -104px !important;
}
/* html */
.threesixty:-webkit-full-screen {
background: #ffffff;
width: 100%;
height: 100%;
margin-top:;
padding-top: 200px;
}
.threesixty:-moz-full-screen {
background: #ffffff;
width: 100%;
height: 100%;
margin-top:;
padding-top: 200px;
}

 使用方法:

html代码:

<link type="text/css" rel="stylesheet" href="css/threesixty.css" rel="external nofollow" >
<script type="text/javascript" src="js/jquery-2.1.1.js"></script>
<script type="text/javascript" src="js/threesixty.min.js"></script>
<div class="threesixty">
<div class="spinner">
<span>0%</span>
</div>
<ol class="threesixty_images "></ol>
</div>

  js代码:

$(window).ready(function(){
$('.threesixty').ThreeSixty({
totalFrames: 12,//图片的总数
endFrame: 2,
currentFrame: 1,//初始化时现实的第几个元素
imgList: '.threesixty_images',//显示图片的父级div
progress: '.spinner',//显示进度的div
imagePath: 'images/car/',//图片的路径
filePrefix: '',//用到的图片的前缀名称
ext: '.png',//存放的图片的后缀名(要一致)
height: "30%",//显示区域的高度
width: "100%",//显示区域的宽度
navigation: true,//是否显示导航条(可以进行的操作:上一步 下一步 开始自动旋转)
disableSpin: false
});
});

如果

navigation:true 就会添加
<div class="nav_bar"><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="nav_bar_previous">previous</a><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="nav_bar_play">play</a><a href="#" rel="external nofollow"  rel="external nofollow"  rel="external nofollow"  class="nav_bar_next">next</a></div>

可以根据自己的需求修改样式

jquery.threesixty.js 源码:

/*!
* ThreeSixty: A jQuery plugin for generating a draggable 360 preview from an image sequence.
* Version: 0.1.2
* Original author: @nick-jonas
* Website: http://www.workofjonas.com
* Licensed under the MIT license
*/;(function ( $, window, document, undefined ) {var scope,
pluginName = 'threeSixty',
defaults = {
dragDirection: 'horizontal',
useKeys: false,
draggable: true
},
dragDirections = ['horizontal', 'vertical'],
options = {},
$el = {},
data = [],
total = 0,
loaded = 0; /**
* Constructor
* @param {jQuery Object} element main jQuery object
* @param {Object} customOptions options to override defaults
*/
function ThreeSixty( element, customOptions ) {
scope = this;
this.element = element;
options = options = $.extend( {}, defaults, customOptions) ;
this._defaults = defaults;
this._name = pluginName; // make sure string input for drag direction is valid
if($.inArray(options.dragDirection, dragDirections) < 0){
options.dragDirection = defaults.dragDirection;
} this.init();
} // PUBLIC API ----------------------------------------------------- $.fn.destroy = ThreeSixty.prototype.destroy = function(){
if(options.useKeys === true) $(document).unbind('keydown', this.onKeyDown);
$(this).removeData();
$el.html('');
}; $.fn.nextFrame = ThreeSixty.prototype.nextFrame = function(){
$(this).each(function(i){
var $this = $(this),
val = $this.data('lastVal') || 0,
thisTotal = $this.data('count'); val = val + 1; $this.data('lastVal', val); if(val >= thisTotal) val = val % (thisTotal - 1);
else if(val <= -thisTotal) val = val % (thisTotal - 1);
if(val > 0) val = thisTotal - val; val = Math.abs(val); $this.find('.threesixty-frame').css({display: 'none'});
$this.find('.threesixty-frame:eq(' + val + ')').css({display: 'block'});
});
}; $.fn.prevFrame = ThreeSixty.prototype.prevFrame = function(){
$(this).each(function(i){
var $this = $(this),
val = $this.data('lastVal') || 0,
thisTotal = $this.data('count'); val = val - 1; $this.data('lastVal', val); if(val >= thisTotal) val = val % (thisTotal - 1);
else if(val <= -thisTotal) val = val % (thisTotal - 1);
if(val > 0) val = thisTotal - val; val = Math.abs(val); $this.find('.threesixty-frame').css({display: 'none'});
$this.find('.threesixty-frame:eq(' + val + ')').css({display: 'block'});
});
}; // PRIVATE METHODS ------------------------------------------------- /**
* Initializiation, called once from constructor
* @return null
*/
ThreeSixty.prototype.init = function () {
var $this = $(this.element); // setup main container
$el = $this; // store data attributes for each 360
$this.each(function(){
var $this = $(this),
path = $this.data('path'),
count = $this.data('count');
data.push({'path': path, 'count': count, 'loaded': 0, '$el': $this});
total += count;
}); _disableTextSelectAndDragIE8(); this.initLoad();
}; /**
* Start loading all images
* @return null
*/
ThreeSixty.prototype.initLoad = function() {
var i = 0, len = data.length, url, j;
$el.addClass('preloading');
for(i; i < len; i++){
j = 0;
for(j; j < data[i].count; j++){
url = data[i].path.replace('{index}', j);
$('<img/>').data('index', i).attr('src', url).load(this.onLoadComplete);
}
}
}; ThreeSixty.prototype.onLoadComplete = function(e) {
var index = $(e.currentTarget).data('index'),
thisObj = data[index];
thisObj.loaded++;
if(thisObj.loaded === thisObj.count){
scope.onLoadAllComplete(index);
}
}; ThreeSixty.prototype.onLoadAllComplete = function(objIndex) {
var $this = data[objIndex].$el,
html = '',
l = data[objIndex].count,
pathTemplate = data[objIndex].path,
i = 0; // remove preloader
$this.html('');
$this.removeClass('preloading'); // add 360 images
for(i; i < l; i++){
var display = (i === 0) ? 'block' : 'none';
html += '<img class="threesixty-frame" style="display:' + display + ';" data-index="' + i + '" src="' + pathTemplate.replace('{index}', i) + '"/>';
}
$this.html(html); this.attachHandlers(objIndex);
}; var startY = 0,
thisTotal = 0,
$downElem = null,
lastY = 0,
lastX = 0,
lastVal = 0,
isMouseDown = false;
ThreeSixty.prototype.attachHandlers = function(objIndex) {
var that = this;
var $this = data[objIndex].$el; // add draggable events
if(options.draggable){
// if touch events supported, use
if(typeof document.ontouchstart !== 'undefined' &&
typeof document.ontouchmove !== 'undefined' &&
typeof document.ontouchend !== 'undefined' &&
typeof document.ontouchcancel !== 'undefined'){
var elem = $this.get()[0];
elem.addEventListener('touchstart', that.onTouchStart);
elem.addEventListener('touchmove', that.onTouchMove);
elem.addEventListener('touchend', that.onTouchEnd);
elem.addEventListener('touchcancel', that.onTouchEnd);
}
} // mouse down
$this.mousedown(function(e){
e.preventDefault();
thisTotal = $(this).data('count');
$downElem = $(this);
startY = e.screenY;
lastVal = $downElem.data('lastVal') || 0;
lastX = $downElem.data('lastX') || 0;
lastY = $downElem.data('lastY') || 0;
isMouseDown = true;
$downElem.trigger('down');
}); // arrow keys
if(options.useKeys === true){
$(document).bind('keydown', that.onKeyDown);
} // mouse up
$(document, 'html', 'body').mouseup(that.onMouseUp);
$(document).blur(that.onMouseUp);
$('body').mousemove(function(e){
that.onMove(e.screenX, e.screenY);
});
}; ThreeSixty.prototype.onTouchStart = function(e) {
var touch = e.touches[0];
e.preventDefault();
$downElem = $(e.target).parent();
thisTotal = $downElem.data('count');
startX = touch.pageX;
startY = touch.pageY;
lastVal = $downElem.data('lastVal') || 0;
lastX = $downElem.data('lastX') || 0;
lastY = $downElem.data('lastY') || 0;
isMouseDown = true;
$downElem.trigger('down');
}; ThreeSixty.prototype.onTouchMove = function(e) {
e.preventDefault();
var touch = e.touches[0];
scope.onMove(touch.pageX, touch.pageY);
}; ThreeSixty.prototype.onTouchEnd = function(e) { }; ThreeSixty.prototype.onMove = function(screenX, screenY){
if(isMouseDown){
var x = screenX,
y = screenY,
val = 0; $downElem.trigger('move'); if(options.dragDirection === 'vertical'){
if(y > lastY){
val = lastVal + 1;
}else{
val = lastVal - 1;
}
}else{
if(x > lastX){
val = lastVal + 1;
}else if(x === lastX){
return;
}else{
val = lastVal - 1;
}
} lastVal = val;
lastY = y;
lastX = x; $downElem.data('lastY', lastY);
$downElem.data('lastX', lastX);
$downElem.data('lastVal', lastVal); if(val >= thisTotal) val = val % (thisTotal - 1);
else if(val <= -thisTotal) val = val % (thisTotal - 1);
if(val > 0) val = thisTotal - val; val = Math.abs(val); $downElem.find('.threesixty-frame').css({display: 'none'});
$downElem.find('.threesixty-frame:eq(' + val + ')').css({display: 'block'});
}
}; ThreeSixty.prototype.onKeyDown = function(e) {
switch(e.keyCode){
case 37: // left
$el.prevFrame();
break;
case 39: // right
$el.nextFrame();
break;
}
}; ThreeSixty.prototype.onMouseUp = function(e) {
isMouseDown = false;
$downElem.trigger('up');
}; /**
* Disables text selection and dragging on IE8 and below.
*/
var _disableTextSelectAndDragIE8 = function() {
// Disable text selection.
document.body.onselectstart = function() {
return false;
}; // Disable dragging.
document.body.ondragstart = function() {
return false;
};
}; /**
* A really lightweight plugin wrapper around the constructor,
preventing against multiple instantiations
* @param {Object} options
* @return {jQuery Object}
*/
$.fn[pluginName] = function ( options ) {
return this.each(function () {
if (!$.data(this, 'plugin_' + pluginName)) {
$.data(this, 'plugin_' + pluginName,
new ThreeSixty( this, options ));
}
});
};})( jQuery, window, document );

使用方法:

html

<script src="assets/js/jquery-2.1.1.js"></script>
<script src="assets/js/jquery.threesixty.js"></script>
<div class="threesixty-wrapper">
<div class="threesixty" data-path="assets/img/threesixty_{index}.jpg" data-count="179">
<!-- put your preloader here -->在图片没有加载完毕时,现实的内容,在图片加载完毕之后,就自动删除
<div class="ui-spinner">
<span class="side side-left">
<span class="fill"></span>
</span>
<span class="side side-right">
<span class="fill"></span>
</span>
</div>
<!-- end preloader -->
</div>
</div>

  js

$(document).ready(function(){                var $threeSixty = $('.threesixty');                $threeSixty.threeSixty({
dragDirection: 'horizontal',//拖拽的方向
useKeys: true,//是否可以使用键盘上的左右按键进行操作
draggable: true//是否可以鼠标拖拽
}); $('.next').click(function(){//显示下一张图片
$threeSixty.nextFrame();
}); $('.prev').click(function(){//显示上一张图片
$threeSixty.prevFrame();
}); $threeSixty.on('down', function(){//拖拽图片时,标题隐藏
$('h1').stop().animate({opacity:0}, 300);
}); $threeSixty.on('up', function(){//方法鼠标之后,标题回显
$(' h1').stop().animate({opacity:1}, 500);
});
});

  

 

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,036
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,522
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,370
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,151
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,784
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,866