<div id="uploader">
<div class="queueList">
<div id="dndArea" class="placeholder">
<div id="filePicker"></div>
<p>或将照片拖到这里,单次最多可选30张</p>
</div>
</div>
<div class="statusBar" style="display:none;">
<div class="progress">
<span class="text">0%</span>
<span class="percentage"></span>
</div><div class="info"></div>
<div class="btns">
<div id="filePicker2"></div><div class="uploadBtn">开始上传</div>
</div>
</div>
</div>
<script>
require(['jquery', 'webuploader' ], function($, WebUploader) {
return;
// 当domReady的时候开始初始化
$(function() {
var $wrap = $('#uploader'),
// 图片容器
$queue = $( '<ul class="filelist"></ul>' )
.appendTo( $wrap.find( '.queueList' ) ),
// 状态栏,包括进度和控制按钮
$statusBar = $wrap.find( '.statusBar' ),
// 文件总体选择信息。
$info = $statusBar.find( '.info' ),
// 上传按钮
$upload = $wrap.find( '.uploadBtn' ),
// 没选择文件之前的内容。
$placeHolder = $wrap.find( '.placeholder' ),
$progress = $statusBar.find( '.progress' ).hide(),
// 添加的文件数量
fileCount = 0,
// 添加的文件总大小
fileSize = 0,
// 优化retina, 在retina下这个值是2
ratio = window.devicePixelRatio || 1,
// 缩略图大小
thumbnailWidth = 110 * ratio,
thumbnailHeight = 110 * ratio,
// 可能有pedding, ready, uploading, confirm, done.
state = 'pedding',
// 所有文件的进度信息,key为file id
percentages = {},
supportTransition = (function(){
var s = document.createElement('p').style,
r = 'transition' in s ||
'WebkitTransition' in s ||
'MozTransition' in s ||
'msTransition' in s ||
'OTransition' in s;
s = null;
return r;
})(),
// WebUploader实例
uploader;
// 实例化
uploader = WebUploader.create({
pick: {
id: '#filePicker',
label: '点击选择图片'
},
dnd: '#dndArea',
paste: '#uploader',
// swf文件路径
swf: '{$_W['siteroot']}app/resource/componets/webuploader/Uploader.swf',
// 文件接收服务端。
server: '{$_W['siteroot']}app/{php echo str_replace('./','',url('utility/file',array('do'=>'upload', 'type'=>'image'), true))}',
chunked: true,
// runtimeOrder: 'flash',
// sendAsBinary: true,
fileNumLimit: 30,
fileSizeLimit: 30 * 1024 * 1024, // 30 M
fileSingleSizeLimit: 4 * 1024 * 1024 // 1 M
});
// 添加“添加文件”的按钮,
uploader.addButton({
id: '#filePicker2',
label: '继续添加'
});
// 当有文件添加进来时执行,负责view的创建
function addFile( file ) {
var $li = $( '<li id="' + file.id + '">' +
'<p class="title">' + file.name + '</p>' +
'<p class="imgWrap"></p>'+
'<p class="progress"><span></span></p>' +
'</li>' ),
$btns = $('<div class="file-panel">' +
'<span class="cancel">删除</span>' +
'<span class="rotateRight">向右旋转</span>' +
'<span class="rotateLeft">向左旋转</span></div>').appendTo( $li ),
$prgress = $li.find('p.progress span'),
$wrap = $li.find( 'p.imgWrap' ),
$info = $('<p class="error"></p>'),
showError = function( code ) {
switch( code ) {
case 'exceed_size':
text = '文件大小超出';
break;
case 'interrupt':
text = '上传暂停';
break;
default:
text = '上传失败,请重试';
break;
}
$info.text( text ).appendTo( $li );
};
if ( file.getStatus() === 'invalid' ) {
showError( file.statusText );
} else {
// @todo lazyload
$wrap.text( '预览中' );
uploader.makeThumb( file, function( error, src ) {
if ( error ) {
$wrap.text( '不能预览' );
return;
}
var img = $('<img src="'+src+'">');
$wrap.empty().append( img );
}, thumbnailWidth, thumbnailHeight );
percentages[ file.id ] = [ file.size, 0 ];
file.rotation = 0;
}
file.on('statuschange', function( cur, prev ) {
if ( prev === 'progress' ) {
$prgress.hide().width(0);
} else if ( prev === 'queued' ) {
$li.off( 'mouseenter mouseleave' );
$btns.remove();
}
// 成功
if ( cur === 'error' || cur === 'invalid' ) {
console.log( file.statusText );
showError( file.statusText );
percentages[ file.id ][ 1 ] = 1;
} else if ( cur === 'interrupt' ) {
showError( 'interrupt' );
} else if ( cur === 'queued' ) {
percentages[ file.id ][ 1 ] = 0;
} else if ( cur === 'progress' ) {
$info.remove();
$prgress.css('display', 'block');
} else if ( cur === 'complete' ) {
$li.append( '<span class="success"></span>' );
}
$li.removeClass( 'state-' + prev ).addClass( 'state-' + cur );
});
$li.on( 'mouseenter', function() {
$btns.stop().animate({height: 30});
});
$li.on( 'mouseleave', function() {
$btns.stop().animate({height: 0});
});
$btns.on( 'click', 'span', function() {
var index = $(this).index(),
deg;
switch ( index ) {
case 0:
uploader.removeFile( file );
return;
case 1:
file.rotation += 90;
break;
case 2:
file.rotation -= 90;
break;
}
if ( supportTransition ) {
deg = 'rotate(' + file.rotation + 'deg)';
$wrap.css({
'-webkit-transform': deg,
'-mos-transform': deg,
'-o-transform': deg,
'transform': deg
});
} else {
$wrap.css( 'filter', 'progid:DXImageTransform.Microsoft.BasicImage(rotation='+ (~~((file.rotation/90)%4 + 4)%4) +')');
}
});
$li.appendTo( $queue );
}
// 负责view的销毁
function removeFile( file ) {
var $li = $('#'+file.id);
delete percentages[ file.id ];
updateTotalProgress();
$li.off().find('.file-panel').off().end().remove();
}
function updateTotalProgress() {
var loaded = 0,
total = 0,
spans = $progress.children(),
percent;
$.each( percentages, function( k, v ) {
total += v[ 0 ];
loaded += v[ 0 ] * v[ 1 ];
} );
percent = total ? loaded / total : 0;
spans.eq( 0 ).text( Math.round( percent * 100 ) + '%' );
spans.eq( 1 ).css( 'width', Math.round( percent * 100 ) + '%' );
updateStatus();
}
function updateStatus() {
var text = '', stats;
if ( state === 'ready' ) {
text = '选中' + fileCount + '张图片,共' + WebUploader.formatSize( fileSize ) + '。';
} else if ( state === 'confirm' ) {
stats = uploader.getStats();
if ( stats.uploadFailNum ) {
text = '已成功上传' + stats.successNum+ '张照片至XX相册,'+
stats.uploadFailNum + '张照片上传失败,<a class="retry" href="#">重新上传</a>失败图片或<a class="ignore" href="#">忽略</a>'
}
} else {
stats = uploader.getStats();
text = '共' + fileCount + '张(' +
WebUploader.formatSize( fileSize ) +
'),已上传' + stats.successNum + '张';
if ( stats.uploadFailNum ) {
text += ',失败' + stats.uploadFailNum + '张';
}
}
$info.html( text );
}
function setState( val ) {
var file, stats;
if ( val === state ) {
return;
}
$upload.removeClass( 'state-' + state );
$upload.addClass( 'state-' + val );
state = val;
switch ( state ) {
case 'pedding':
$placeHolder.removeClass( 'element-invisible' );
$queue.hide();
$statusBar.addClass( 'element-invisible' );
uploader.refresh();
break;
case 'ready':
$placeHolder.addClass( 'element-invisible' );
$( '#filePicker2' ).removeClass( 'element-invisible');
$queue.show();
$statusBar.removeClass('element-invisible');
uploader.refresh();
break;
case 'uploading':
$( '#filePicker2' ).addClass( 'element-invisible' );
$progress.show();
$upload.text( '暂停上传' );
break;
case 'paused':
$progress.show();
$upload.text( '继续上传' );
break;
case 'confirm':
$progress.hide();
$upload.text( '开始上传' ).addClass( 'disabled' );
stats = uploader.getStats();
if ( stats.successNum && !stats.uploadFailNum ) {
setState( 'finish' );
return;
}
break;
case 'finish':
stats = uploader.getStats();
if ( stats.successNum ) {
alert( '上传成功' );
} else {
// 没有成功的图片,重设
state = 'done';
location.reload();
}
break;
}
updateStatus();
}
uploader.onUploadProgress = function( file, percentage ) {
var $li = $('#'+file.id),
$percent = $li.find('.progress span');
$percent.css( 'width', percentage * 100 + '%' );
percentages[ file.id ][ 1 ] = percentage;
updateTotalProgress();
};
uploader.onFileQueued = function( file ) {
fileCount++;
fileSize += file.size;
if ( fileCount === 1 ) {
$placeHolder.addClass( 'element-invisible' );
$statusBar.show();
}
addFile( file );
setState( 'ready' );
updateTotalProgress();
};
uploader.onFileDequeued = function( file ) {
fileCount--;
fileSize -= file.size;
if ( !fileCount ) {
setState( 'pedding' );
}
removeFile( file );
updateTotalProgress();
};
uploader.on( 'all', function( type ) {
var stats;
switch( type ) {
case 'uploadFinished':
setState( 'confirm' );
break;
case 'startUpload':
setState( 'uploading' );
break;
case 'stopUpload':
setState( 'paused' );
break;
}
});
uploader.onError = function( code ) {
alert( 'Eroor: ' + code );
};
$upload.on('click', function() {
if ( $(this).hasClass( 'disabled' ) ) {
return false;
}
if ( state === 'ready' ) {
uploader.upload();
} else if ( state === 'paused' ) {
uploader.upload();
} else if ( state === 'uploading' ) {
uploader.stop();
}
});
$info.on( 'click', '.retry', function() {
uploader.retry();
} );
$info.on( 'click', '.ignore', function() {
alert( 'todo' );
} );
$upload.addClass( 'state-' + state );
updateTotalProgress();
});
});
</script>
‘贰’ 理解iOS中深浅拷贝-为什么NSString使用
一直以为对深浅拷贝理解很透彻,最近面试中被问到这样一个问题,
这个概念相比很好理解,直接看图吧。
浅拷贝 :指针拷贝,复制一个新的指针,只想同一块内存区域。实际内存并没有发生拷贝
深拷贝 :内容拷贝,拷贝数据到一块新内存区域,指针指向拷贝的数据区
strong: 浅拷贝,也就是指针引用,很明显的。我们来测试一下
运行结果如下,实际对象是一致的。
这意味着A使用属性对可变字符串做出了appendstring这样的操作,B中的值也会发生修改。
:这里我们研究系统的NSstring,NSArray对象之后是怎么样的
先看一个有意思的现象,我们新建一个NSMutableString,然后,接着用这个对象调用MutableString特有的appendstring修改字符串
结果呢?
闪退了!这是为什么?
细看一下,我们的MutableString对象调用了之后,拷贝出来的字符串内存地址发生了变化,也就是说这里是发生了深拷贝。
接着我们使用String调用appendString方法发生了很常规的闪退,日志显示我们拷贝出来的是NSTaggedPointerString,这是个不可变字符串。
也就是说可变字符串在之后会发生深拷贝,拷贝出来的是一个不可变字符串!
接下来我们测试下如果一个NSString对象是怎样的
结果是这里是浅拷贝,地址没有发生变化。
我们从这得出了结论:
并不一定是浅拷贝,出来的一定是不可变字符串或者数组,如果被拷贝的对象是可变数组或者字符串,这时候会发生深拷贝,反之则是浅拷贝。
MutableCopy
这里就不贴验证了,直接上结果,对于字符串和数组MutableCopy一定是深拷贝,而且拷贝出来对象一定是可变字符串或者数组。即使被拷贝对象是不可变字符串。
1. 出来的字符串一定是不可变字符串,如果传入的是可变字符串,会发生深拷贝为不可变字符串,否则为浅拷贝。
2. mutable,一定是深拷贝,拷贝出来的一定是可变字符串或者数组,即使传入的是不可变字符串或者数组。
‘叁’ switch无法备份什么意思
可能是存档太大,然后你网络和任天堂的服务器不搭导致链接不稳定经常掉包导致失败。比如arms的存档文件好像是128MB,我大概备份了三次才成功,存档小的比如死亡细胞才5.3MB每次都能成功。一般来说你可以开个加速器,或者换dns,或者就不要管他,等他自己多试个几次说不定就成功了。经过4.0固件升级之后,任天堂Switch加入了更多的系统功能,正在赶上对手索尼和微软,不过到现在为止仍然没有Switch游戏存档备份功能,这让部分玩家很伤心,毕竟自己努力数百小时的进度如果丢失那感觉简直如世界末日。对此,最近美国任天堂总裁雷吉接受了相关采访。雷吉在采访当中谈到了自己对于游戏存档重要性的理解,因为他也已经在Switch《塞尔达传说:旷野之息》当中投入了大量时间,目前已经收集到了400个呀哈哈!他谈到任天堂目前已经注意到了这个问题(存档不能备份)。并表明任天堂是一家重视用户的公司,希望用户能够开心快乐。接下来这一问题将是任天堂开始解决的方向。也有玩家可能会说,做一个云备份存档就这么难吗?要知道,任天堂给出统一的账户系统还是经过了Wii、WiiU和Switch三个世代才做到,所以,还是耐心等待并祈祷自己的Switch游戏存档吧。‘肆’ switch破解版拷完游戏直接退出吗
是的。1、在switch双点游戏界面,点击有手柄的“+”。
2、会出现游戏保存画面,选择保存选项,点击按键A进行保存。出现保存完成画面后,点击右手柄的主页键。直接退出游戏即可。
‘伍’ WebStorm启动项目后报错Switch language version to React JSX
webstorm启动一个项目时,提示“Switch language version to React JSX”
解决方法:file——setting——language & frameworks——JavaScript改为ReactJSX即可
‘陆’ 适合初学者学习Web前端技术的学习路线汇总
今天小编要跟大家分享的文章是关于适合初学者学习Web前端技术的学习路线汇总。在当下来说Web前端开发工程师可谓是高福利、高薪水的职业了。所以现在学习Web前端开发的技术人员也是日益增多了,但是在学习Web前端开发中盲目的去学习而没有一个完整的思路和学习路线也是不行的。
那么想学好Web前端,该从哪里入手学习呢?零基础学习Web前端学习路线图从哪里可以找到呢?在此为大家整理完整的适合零基础学员的Web前端学习路线分享给大家,来和小编一起看一看吧!
1.HTML5介绍
内容包括:(互联网发展趋势、H5语言的优势、简单易学人人都能编程、H5就业和薪资情况、H5常见的项目与产品、H5的未来与方向)
2.HTML基础
内容包括:(HTML简介与历史版本、常用开发软件、常见标签与属性、表格与表单、标签规范与标签语义化、实战:网页结构布局)
3.CSS基础
内容包括:(css简介与基本语法、常见的各种样式属性、CSS选择器与标签类型、理解盒子模型与CSS重置、浮动与定位、利用photoshop工具测量样式、HTML+CSS开发网页、实战:高仿电商首页效果)
4.CSS3基础
内容包括:(css3常见样式、css3选择器、变形与动画、3D效果与关键帧、弹性盒模型)
5.移动端布局
移动端基本概念、viewport窗口设置、移动端布局方案、rem、vh、vw等单位、响应式布局、bootstrap框架
6.JavaScript基础
内容包括:(JS简介、JS变量、数据类型与类型转换、运算符与优先级、流程控制-if..else流程控制-switch...case、流程控制-while、do..while、for循环、break、continue语法、函数定义与调用、全局变量与局部变量、函数传参与返回值、函数作用域与变量作用域。
而且还有DOM的基本操作、定时器使用、this指向与修改指向、数组、字符串等方法操作、时间对象与正则对象、掌握常见BOM操作、常见事件与事件细节、JSON与AJAX、JSONP跨域操作、前端cookie的使用、实战:JS配合HTML与CSS完成电商项目)
7.jquery框架
内容包括:(jquery框架介绍及优势介绍、jquery核心思想、jquery常见方法、jquery动画操作、jqueryAJAX操作、jquery工具方法、利用jquery快速开发网页)
8.PHP基础
内容包括:(PHP简介与基本语法、mysql数据库及sql语法、apache服务器与集成开发工具、PHP链接数据库、PHP与AJAX交互、实战:留言板、登录、注册等)
9.H5基础项目
内容包括:(项目简介、项目功能演示、项目划分及框架、编写HTML页面结构、设置CSS样式、添加JS交互、可选框架:bootstrap、jquery、PHP等、项目调试及兼容、项目验收)
如何成为合格的Web前端开发工程师(Web前端职业规划+各阶段薪资待遇)
原来是需要熟练的掌握HTML、CSS、JS、JQ等最基本的技术。
现在,只掌握这些已经远远不够了。无论是开发难度上,还是开发方式上,Web前端开发不比从前,现在的功能非常强大。
而前端开发为什么现在这么火,在于互联网高速发展,和HTML5技术的不断成熟,各大浏览器的不断兼容,让Web前端开发成为最热的职业。
WEB前端初级开发工程师需要掌握的具体知识点包含:
HTML5基础、CSS基础、jquery框架、PHP基础
此阶段可达成学习效果:
可胜任Web前端开发工程师前端页面布局与重构工程师。
薪资可以达到:4K-6K。
WEB前端中高级开发工程师所需要掌握的知识点包含:
面向对象、javascript、Nodejs、微信端开发
此阶段可达成效果:
可胜任Web前端工程师、高级Web前端工程师、网站开发工程师、移动前端开发工程师等职位。
薪资可达到:6K-10K。
WEB前端大神级开发工程师需要掌握的知识点包含:
VueJS框架、ReactJS框架、AngularJS框架、HybridApp开发、前端架构
此阶段可达成效果:
可胜任高级Web前端工程师、全栈工程师、移动前端App开发工程师、微信开发工程师、小程序开发工程师、数据可视化开发工程师等职位。
薪资可达到:10K-15K+。
以上就是小编今天为大家分享的关于适合初学者学习Web前端技术的学习路线汇总的文章,希望本篇文章能够对正想要学习Web前端知识的小伙伴们有所帮助,想要了解更多Web前端相关知识记得关注北大青鸟Web培训官网。最后祝愿小伙伴们工作顺利,成为一名优秀的Web前端工程师。
‘柒’ web自动化测试之web自动化中操作要点
1、切换iframe:
driver.switch_to.frame(' xxx')
2、浏览器向右移动页面(浏览器中执行JavaScript代码)
driver.execute_script('window.scrollBy(200,0)') # window.scrollBy(x,y)
3、driver.implicitly_wait()和time.sleep()的区别
driver.implicitly_wait(10) #设置寻找元素最大等待时间;
implicitly_wait(5)属于隐式等待,5秒钟内只要找到了元素就开始执行,5秒钟后未找到,就超时;
time.sleep(5)表示必须等待5秒定位。
4、切换到新的目标窗口
#切换webdriver到新的目标窗口
for handle in driver.window_handles:
driver.switch_to.window(handle)
#判断是否进行了目标窗口
title=driver.title
if 'xxxxx' in title:
break
5、当页面广告遮挡了元素,可将页面广告元素删除
element=driver.find_element_by_css_selector('#meiqia-container iframe[name=chat]') driver.execute_script('$(arguments[0]).remove()',element) #将element传给了arguments[0] time.sleep(2)
6、切换浏览器标签页
使用switch_to_window(window),搭配句柄window_handles、current_window_handle使用。
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www..com")
driver.implicitly_wait(10)
driver.find_element_by_id("kw").send_keys("python")
driver.find_element_by_id("su").click()
driver.find_element_by_xpath("//*[@id='2']/h3/a").click()
#获取当前窗口所有句柄
all_windows = driver.window_handles
#获取当前标签页窗口句柄
current_window = driver.current_window_handle
#切换标签页窗口
for window in all_windows:
if window !=current_window:
print("切换前的窗口名称是:",driver.title)
driver.switch_to_window(window)
time.sleep(2)
print("切换后的窗口名称是:",driver.title)
break
7、切换iframe页面
使用switch_to_frame()、switch_to_default_content(),一般成套使用更好,以防止未切回导致定位失败。
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("https://ke.qq.com/")
driver.implicitly_wait(10)
#点击登录
driver.find_element_by_class_name("btn-default").click()
time.sleep(0.5)
driver.find_element_by_xpath("//*[@class='js-btns-enter btns-enter btns-enter-qq']").click() time.sleep(2)
#点击账号密码登录
#这里直接定位会失败,需要切换到登录弹窗页面后再进行定位,习惯使用的是2种切换方式
#1.iframe有唯一名称
driver.switch_to_frame("login_frame_qq")
driver.find_element_by_id("switcher_plogin").click()
driver.find_element_by_id("u").send_keys("123456789")
#回切到主页面
driver.switch_to_default_content()
time.sleep(2)
#2.iframe无名字,使用下标进行切换,且下标从0开始
#在页面中查到到当前需要定位的iframe在第3个,所以下标是2
#再次切换到弹窗页面 driver.switch_to_frame(2)
driver.find_element_by_id("p").send_keys("123456789")
driver.find_element_by_id("login_button").click()
driver.switch_to_default_content()
time.sleep(5)
driver.quit()
8、处理弹窗
使用switch_to_alert()中的accept()、dismiss()、send_keys、text进行操作,弹窗一般有三种类型,①.只有确认按钮的;②.有确认/取消按钮的;③.需要输入文字的。
import time
from selenium import webdriver
driver = webdriver.Chrome()
driver.get("http://www..com")
driver.implicitly_wait(10)
#创建一个测试弹窗
driver.execute_script("window.alert('这是一个测试弹窗')")
time.sleep(2)
#1.弹窗中只有确认按钮的
driver.switch_to_alert().accept()
time.sleep(1)
#2.弹窗中有确认/取消按钮的
driver.execute_script("window.alert('这是一个测试弹窗')")
time.sleep(3)
#点击取消
driver.switch_to_alert().dismiss()
time.sleep(1)
#弹窗中需要输入文字的
# driver.switch_to_alert().send_keys("测试测试测试")
#获取弹窗中的内容
driver.execute_script("window.alert('这是一个测试弹窗')")
res = driver.switch_to_alert().text
print(res)
‘捌’ nintendo switch怎样从手机拷游戏
如果是放在手机储存里的XCI或者NSP游戏文件的话用USB线连接电脑拷贝出来,SWITCH关机取出SD卡放到读卡器连接电脑就可以复制粘贴到卡里了。
如果你说的是把手游放到SWITCH上玩是无法实现的。手机游戏是APK格式和IPA的。格式都不同,怎么用。