1、判断图片是否加载完成
(1)第一种方法,通过onload事件,比如:
(2)第二种方法,使用 onreadystatechange 来判断
说明:document.readyState 的 状态值分别如下,
-
0-UNINITIALIZED:XML 对象被产生,但没有任何文件被加载。
1-LOADING:加载程序进行中,但文件尚未开始解析。
2-LOADED:部分的文件已经加载且进行解析,但对象模型尚未生效。
3-INTERACTIVE:仅对已加载的部分文件有效,在此情况下,对象模型是有效但只读的。
4-COMPLETED:文件已完全加载,代表加载成功。
2、预加载图片
方案一:
方案二:
lightbox类效果为了让图片居中显示而使用预加载,需要等待完全加载完毕才能显示,体验不佳(如filick相册的全屏效果)。javascript无法获取img文件头数据,真的是这样吗?本文通过一个巧妙的方法让javascript获取它。
这是大部分人使用预加载获取图片大小的例子:
01 | var imgLoad = function (url, callback) { |
02 | var img = new Image(); |
06 | callback(img.width, img.height); |
08 | img.onload = function () { |
09 | callback(img.width, img.height); |
可以看到上面必须等待图片加载完毕才能获取尺寸,其速度不敢恭维,我们需要改进。
web应用程序区别于桌面应用程序,响应速度才是最好的用户体验。如果想要速度与优雅兼得,那就必须提前获得图片尺寸,如何在图片没有加载完毕就能获取图片尺寸?
十多年的上网经验告诉我:浏览器在加载图片的时候你会看到图片会先占用一块地然后才慢慢加载完毕,并且不需要预设width与height属性,因为浏览器能够获取图片的头部数据。基于此,只需要使用javascript定时侦测图片的尺寸状态便可得知图片尺寸就绪的状态。
当然实际中会有一些兼容陷阱,如width与height检测各个浏览器的不一致,还有webkit new Image()建立的图片会受以处在加载进程中同url图片影响,经过反复测试后的最佳处理方式:
02 | // 05.27: 1、保证回调执行顺序:error > ready > load;2、回调函数this指向img本身 |
03 | // 04-02: 1、增加图片完全加载后的回调 2、提高性能 |
06 | * 图片头数据加载就绪事件 - 更快获取图片尺寸 |
10 | * @param {String} 图片路径 |
11 | * @param {Function} 尺寸就绪 |
12 | * @param {Function} 加载完毕 (可选) |
13 | * @param {Function} 加载错误 (可选) |
14 | * @example imgReady('', function () { |
15 | alert('size ready: width=' + this.width + '; height=' + this.height); |
18 | var imgReady = (function () { |
19 | var list = [], intervalId = null, |
24 | for (; i < list.length; i++) { |
25 | list[i].end ? list.splice(i--, 1) : list[i](); |
27 | !list.length && stop(); |
32 | clearInterval(intervalId); |
36 | return function (url, ready, load, error) { |
37 | var onready, width, height, newWidth, newHeight, |
45 | load && load.call(img); |
53 | img.onerror = function () { |
54 | error && error.call(img); |
56 | img = img.onload = img.onerror = null; |
60 | onready = function () { |
62 | newHeight = img.height; |
63 | if (newWidth !== width || newHeight !== height || |
64 | // 如果图片已经在其他地方加载可使用面积检测 |
65 | newWidth * newHeight > 1024 |
74 | img.onload = function () { |
75 | // onload在定时器时间差范围内可能比onready快 |
76 | // 这里进行检查并保证onready优先执行 |
77 | !onready.end && onready(); |
79 | load && load.call(img); |
81 | // IE gif动画会循环执行onload,置空onload即可 |
82 | img = img.onload = img.onerror = null; |
88 | // 无论何时只允许出现一个定时器,减少浏览器性能损耗 |
89 | if (intervalId === null) intervalId = setInterval(tick, 40); |
调用例子:
1 | imgReady('', function () { |
2 | alert('size ready: width=' + this.width + '; height=' + this.height); |
是不是很简单?这样的方式获取摄影级别照片尺寸的速度往往是onload方式的几十多倍,而对于web普通(800×600内)浏览级别的图片能达到秒杀效果。看了这个再回忆一下你见过的web相册,是否绝大部分都可以重构一下呢?好了,请观赏令人愉悦的 DEMO。
方案三:
(function($) { var cache = []; // Arguments are image paths relative to the current page. $.preLoadImages = function() { var args_len = arguments.length; for (var i = args_len; i--;) { var cacheImage = document.createElement('img'); cacheImage.src = arguments[i]; cache.push(cacheImage); } } jQuery.preLoadImages("image1.gif", "/path/to/image2.png");
3、让页面中的每个元素都适合在移动设备上展示
var scr = document.createElement('script'); scr.setAttribute('src', 'https://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js'); document.body.appendChild(scr); scr.onload = function(){ $('div').attr('class', '').attr('id', '').css({ 'margin' : 0, 'padding' : 0, 'width': '100%', 'clear':'both' }); };
4、图像等比例缩放
$(window).bind("load", function() { // IMAGE RESIZE $('#product_cat_list img').each(function() { var maxWidth = 120; var maxHeight = 120; var ratio = 0; var width = $(this).width(); var height = $(this).height(); if(width > maxWidth){ ratio = maxWidth / width; $(this).css("width", maxWidth); $(this).css("height", height * ratio); height = height * ratio; } var width = $(this).width(); var height = $(this).height(); if(height > maxHeight){ ratio = maxHeight / height; $(this).css("height", maxHeight); $(this).css("width", width * ratio); width = width * ratio; } }); //$("#contentpage img").show(); // IMAGE RESIZE });
5、返回页面顶部
PC通用返回页面顶部:
// Back To Top $(document).ready(function(){ $('.top').click(function() { $(document).scrollTo(0,500); }); }); //Create a link defined with the class .top Back To Top
适用于移动端返回页面顶部:
Q:what's the purpose of having the y pos to be either 0 or 1? is it better than just scroll to 0?
A:In testing, we found that Android uses 1px y pos for hiding, while it's 0 in iOS. This is meant to normalize the two.
/* * Normalized hide address bar for iOS & Android * (c) Scott Jehl, scottjehl.com * MIT License */ (function( win ){ var doc = win.document; // If there's a hash, or addEventListener is undefined, stop here if( !location.hash && win.addEventListener ){ //scroll to 1 window.scrollTo( 0, 1 ); var scrollTop = 1, getScrollTop = function(){ return win.pageYOffset || doc.compatMode === "CSS1Compat" && doc.documentElement.scrollTop || doc.body.scrollTop || 0; }, //reset to 0 on bodyready, if needed bodycheck = setInterval(function(){ if( doc.body ){ clearInterval( bodycheck ); scrollTop = getScrollTop(); win.scrollTo( 0, scrollTop === 1 ? 0 : 1 ); } }, 15 ); win.addEventListener( "load", function(){ setTimeout(function(){ //at load, if user hasn't scrolled more than 20 or so... if( getScrollTop() < 20 ){ //reset to hide addr bar at onload win.scrollTo( 0, scrollTop === 1 ? 0 : 1 ); } }, 0); } ); } })( this );
6、使用jQuery打造手风琴式的折叠效果
var accordion = { init: function(){ var $container = $('#accordion'); $container.find('li:not(:first) .details').hide(); $container.find('li:first').addClass('active'); $container.on('click','li a',function(e){ e.preventDefault(); var $this = $(this).parents('li'); if($this.hasClass('active')){ if($('.details').is(':visible')) { $this.find('.details').slideUp(); } else { $this.find('.details').slideDown(); } } else { $container.find('li.active .details').slideUp(); $container.find('li').removeClass('active'); $this.addClass('active'); $this.find('.details').slideDown(); } }); } };
7、通过预加载图片廊中的上一幅下一幅图片来模仿Facebook的图片展示方式
var nextimage = "/images/some-image.jpg"; $(document).ready(function(){ window.setTimeout(function(){ var img = $("").attr("src", nextimage).load(function(){ //all done }); }, 100); });
8、使用jQuery和Ajax自动填充选择框
$(function(){ $("select#ctlJob").change(function(){ $.getJSON("/select.php",{id: $(this).val(), ajax: 'true'}, function(j){ var options = ''; for (var i = 0; i < j.length; i++) { options += ' ' + j[i].optionDisplay + ' '; } $("select#ctlPerson").html(options); }) }) })
9、自动替换丢失的图片
// Safe Snippet $("img").error(function () { $(this).unbind("error").attr("src", "missing_image.gif"); }); // Persistent Snipper $("img").error(function () { $(this).attr("src", "missing_image.gif"); });
10、在鼠标悬停时显示淡入/淡出特效
$(document).ready(function(){ $(".thumbs img").fadeTo("slow", 0.6); // This sets the opacity of the thumbs to fade down to 60% when the page loads $(".thumbs img").hover(function(){ $(this).fadeTo("slow", 1.0); // This should set the opacity to 100% on hover },function(){ $(this).fadeTo("slow", 0.6); // This should set the opacity back to 60% on mouseout }); });
11、清空表单数据
function clearForm(form) { // iterate over all of the inputs for the form // element that was passed in $(':input', form).each(function() { var type = this.type; var tag = this.tagName.toLowerCase(); // normalize case // it's ok to reset the value attr of text inputs, // password inputs, and textareas if (type == 'text' || type == 'password' || tag == 'textarea') this.value = ""; // checkboxes and radios need to have their checked state cleared // but should *not* have their 'value' changed else if (type == 'checkbox' || type == 'radio') this.checked = false; // select elements need to have their 'selectedIndex' property set to -1 // (this works for both single and multiple select elements) else if (tag == 'select') this.selectedIndex = -1; }); };
12、预防对表单进行多次提交
$(document).ready(function() { $('form').submit(function() { if(typeof jQuery.data(this, "disabledOnSubmit") == 'undefined') { jQuery.data(this, "disabledOnSubmit", { submited: true }); $('input[type=submit], input[type=button]', this).each(function() { $(this).attr("disabled", "disabled"); }); return true; } else { return false; } }); });
13、动态添加表单元素
//change event on password1 field to prompt new input $('#password1').change(function() { //dynamically create new input and insert after password1 $("#password1").append(""); });
14、让整个Div可点击
blah blah blah. link The following lines of jQuery will make the entire div clickable: $(".myBox").click(function(){ window.location=$(this).find("a").attr("href"); return false; });
15、平衡高度或Div元素
var maxHeight = 0; $("div").each(function(){ if ($(this).height() > maxHeight) { maxHeight = $(this).height(); } }); $("div").height(maxHeight);