1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/koalalc-pptHtml

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
Клонировать/Скачать
slideshow.js 20 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
KoalaLC Отправлено 16.05.2015 18:01 d6a650f
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746
/**
* CSSS javascript code
* @author Lea Verou (http://lea.verou.me)
* @version 2.1
*/
/**
* Make the environment a bit friendlier
*/
function $(expr, con) { return typeof expr === 'string'? (con || document).querySelector(expr) : expr; }
function $$(expr, con) { return [].slice.call((con || document).querySelectorAll(expr)); }
/**
*
*/
(function(head, body, html){
// Check for classList support and include the polyfill if it's not supported
//这一步是验错的,看看是否支持classList属性
if(!('classList' in body)) {
var thisScript = $('script[src$="slideshow.js"]'),
script = document.createElement('script');
script.src = thisScript.src.replace(/\bslideshow\.js/, 'classList.js');
thisScript.parentNode.insertBefore(script, thisScript);
}
// http://ichuan.net/post/52/stable-sort-of-javascript-array/
//为Array添加新的排序方法。
Array.prototype.stableSort = function (fn) {
if (!fn) {
return this.sort();
}
var newArr = this.map(function (i, j) { return {i:i, j:j}; });
return newArr.sort(function (a, b) {
result = fn(a.i, b.i);
if (result === 0) {
return a.j - b.j;
}
return result;
}).map(function (i) { return i.i; });
};
// Cache <title> element, we may need it for slides that don't have titles
var documentTitle = document.title + '';
var _ = window.SlideShow = function(slide) {
var me = this;
// Set instance
if(!window.slideshow) {
window.slideshow = this;
}
// Current slide
this.index = this.slide = slide || 0;
// Current .delayed item in the slide
this.item = 0;
// Create timer, if needed
this.duration = body.getAttribute('data-duration');
if(this.duration > 0) {
var timer = document.createElement('div');
timer.id = 'timer';
timer.setAttribute('style', PrefixFree.prefixCSS('transition-duration: ' + this.duration * 60 + 's;'));
body.appendChild(timer);
addEventListener('load', function() {
timer.className = 'end';
setTimeout(function() {
timer.classList.add('overtime');
}, me.duration * 60000);
});
}
// Create slide indicator
this.indicator = document.createElement('div');
this.indicator.id = 'indicator';
body.appendChild(this.indicator);
// Add on screen navigation
var onscreen = document.createElement('nav');
onscreen.id = 'onscreen-nav';
var prev = document.createElement('button');
prev.className = 'onscreen-nav prev';
prev.textContent = '';
prev.type = 'button';
prev.onclick = function() { me.previous(); }
var next = document.createElement('button');
next.className = 'onscreen-nav next';
next.textContent = 'Next ▶';
next.type = 'button';
next.onclick = function() { me.next(); }
onscreen.appendChild(prev);
onscreen.appendChild(next);
onscreen.style.display = 'none';
document.body.appendChild(onscreen);
// Expand multiple imported slides
//这个具体是干什么的并不清楚,但是好像是针对有 data-base和data-src属性的class为slide的标签
$$('.slide[data-base][data-src*=" "]').forEach(function(slide) {
var hashes = slide.getAttribute('data-src').split(/\s+/).forEach(function (hash) {
var s = slide.cloneNode(true);
s.setAttribute('data-src', hash);
slide.parentNode.insertBefore(s, slide);
});
slide.parentNode.removeChild(slide);
});
// Get the slide elements into an array
this.slides = $$('.slide', body);
// Get the overview
// 这个很有可能是看缩略图用的东西
this.overview = function(evt) {
if(body.classList.contains('show-thumbnails')) {
body.classList.remove('show-thumbnails');
body.classList.remove('headers-only');
}
else {
body.classList.add('show-thumbnails');
if(evt && (!evt.shiftKey || !evt.ctrlKey)) {
body.classList.add('headers-only');
}
body.addEventListener('click', function(evt) {
var slide = evt.target;
while(slide && !slide.classList.contains('slide')) {
slide = slide.parentNode;
}
if(slide) {
me.goto(slide.id);
setTimeout(function() { me.adjustFontSize(); }, 1000); // for Opera
}
body.classList.remove('show-thumbnails');
body.classList.remove('headers-only');
body.removeEventListener('click', arguments.callee);
}, false);
}
}
// Process iframe slides
//下面这个函数的选择器真的需要好好学习一下啊。
$$('.slide[data-src]:not([data-base]):empty').forEach(function(slide) {
var iframe = document.createElement('iframe');
iframe.setAttribute('data-src', slide.getAttribute('data-src'));
slide.removeAttribute('data-src');
slide.appendChild(iframe);
});
$$('.slide > iframe:only-child').forEach(function(iframe) {
var slide = iframe.parentNode,
src = iframe.src || iframe.getAttribute('data-src');
slide.classList.add('iframe');
if(!slide.classList.contains('notitle')) {
addTitle(slide, src, iframe.title);
}
slide.classList.add('onscreen-nav');
});
this.isIpad = navigator.userAgent.indexOf('iPad;') > -1;
// Order of the slides
this.order = [];
for (var i=0; i<this.slides.length; i++) {
var slide = this.slides[i]; // to speed up references
// Asign ids to slides that don't have one
if(!slide.id) {
slide.id = 'slide' + (i+1);
}
// Set data-title attribute to the title of the slide
if(!slide.title) {
// no title attribute, fetch title from heading(s)
var heading = $('hgroup', slide) || $('h1,h2,h3,h4,h5,h6', slide);
if(heading && heading.textContent.trim()) {
slide.setAttribute('data-title', heading.textContent);
}
}
else {
// The title attribute is set, use that
slide.setAttribute('data-title', slide.title);
slide.removeAttribute('title');
}
slide.setAttribute('data-index', i);
var imp = slide.getAttribute('data-import'),
imported = imp? this.getSlideById(imp) : null;
this.order.push(imported? +imported.getAttribute('data-index') : i);
// [data-steps] can be used to define steps (applied through the data-step
// property), used in CSS to go through multiple states for an element
// 这个stepped倒是是什么东西? 同时这个东西去哪里找呢??????
var stepped = $$('[data-steps]', slide);
if (slide.hasAttribute('data-steps')) {
stepped.push(slide);
}
stepped.forEach(function(element) {
var steps = +element.getAttribute('data-steps');
element.removeAttribute('data-step');
for(var i=0; i<steps; i++) {
var dummy = document.createElement('span');
dummy.style.display = 'none';
dummy.className = 'delayed dummy';
dummy.dummyFor = element;
dummy.dummyIndex = i+1;
if (element === slide) {
slide.appendChild(dummy);
}
else {
element.parentNode.insertBefore(dummy, element);
}
}
});
}
if(window.name === 'projector' && window.opener && opener.slideshow) {
body.classList.add('projector');
this.presenter = opener.slideshow;
this.presenter.projector = this;
}
// Adjust the font-size when the window is resized
addEventListener('resize', this, false);
// In some browsers DOMContentLoaded is too early, so try again onload
addEventListener('load', this, false);
addEventListener('hashchange', this, false);
// If there's already a hash, update current slide number...
this.handleEvent({type: 'hashchange'});
document.addEventListener('keyup', this, false);
document.addEventListener('keydown', this, false);
$$('link[rel~="csss-import"]').forEach(function (link) {
var url = link.href;
var id = link.id;
var slides = $$('.slide[data-base="' + id + '"][data-src^="#"]');
var isSlideshow = link.rel.indexOf('slides') > -1;
if (slides.length) {
var iframe = document.createElement('iframe');
var hash = slides[0].getAttribute('data-src');
iframe.className = 'csss-import';
iframe.src = url + hash;
document.body.insertBefore(iframe, document.body.firstChild);
// Process the rest of the slides, which should use the same iframe
slides.forEach(function (slide) {
var hash = slide.getAttribute('data-src');
slide.classList.add('dont-resize');
this.onSlide(slide.id, function () {
onscreen.style.display = '';
iframe.src = iframe.src.replace(/#.+$/, hash);
iframe.className = 'csss-import show';
});
}, this);
}
}, this);
function addTitle(slide, url, title) {
var h = document.createElement('h1'),
a = document.createElement('a');
title = title || slide.title || slide.getAttribute('data-title') ||
url.replace(/\/#?$/, '').replace(/^\w+:\/\/(www\.)?/, '');
a.href = url;
a.target = '_blank';
a.textContent = title;
h.appendChild(a);
slide.appendChild(h);
}
};
_.prototype = {
handleEvent: function(evt) {
var me = this;
// Prevent script from hijacking the user’s navigation
if (evt.metaKey && evt.keyCode) {
return true;
}
switch(evt.type) {
/**
Keyboard navigation
Ctrl+G : Go to slide...
Ctrl+H : Show thumbnails and go to slide
Ctrl+P : Presenter view
(Shift instead of Ctrl works too)
*/
case 'keyup':
if((evt.ctrlKey || evt.shiftKey) && !evt.altKey && !/^(?:input|textarea)$/i.test(document.activeElement.nodeName)) {
switch(evt.keyCode) {
case 71: // G
var slide = prompt('Which slide?');
me.goto(+slide? slide - 1 : slide);
break;
case 72: // H 这个用于显示预览,仅仅显示标题头,不过已经很牛逼了,好好研究一下
me.overview(evt);
break;
case 74: // J 这种用于隐藏的操作可以学习一下!可以用于动态的切换图片
if(body.classList.contains('hide-elements')) {
body.classList.remove('hide-elements');
}
else {
body.classList.add('hide-elements');
}
break;
case 80: // P
// Open new window for attendee view
this.projector = open(location, 'projector');
// Get the focus back
window.focus();
// Switch this one to presenter view
body.classList.add('presenter');
}
}
break;
case 'keydown':
/**
Keyboard navigation
Home : First slide
End : Last slide
Space/Up/Right arrow : Next item/slide
Ctrl + Space/Up/Right arrow : Next slide
Down/Left arrow : Previous item/slide
Ctrl + Down/Left arrow : Previous slide
(Shift instead of Ctrl works too)
*/
if(evt.target === body || evt.target === body.parentNode || evt.metaKey && evt.altKey) {
if(evt.keyCode >= 32 && evt.keyCode <= 40) {
evt.preventDefault();
}
switch(evt.keyCode) {
case 33: //page up
this.previous();
break;
case 34: //page down
this.next();
break;
case 35: // end
this.end();
break;
case 36: // home
this.start();
break;
case 37: // <-
case 38: // up arrow
this.previous(evt.ctrlKey || evt.shiftKey);
break;
case 32: // space
case 39: // ->
case 40: // down arrow
this.next(evt.ctrlKey || evt.shiftKey);
break;
}
}
break;
case 'load':
case 'resize':
this.adjustFontSize();
break;
case 'hashchange':
this.goto(location.hash.substr(1) || 0);
}
},
start: function() {
this.goto(0);
},
end: function() {
this.goto(this.slides.length - 1);
},
/**
@param hard {Boolean} Whether to advance to the next slide (true) or
just the next step (which could very well be showing a list item)
*/
next: function(hard) {
if(!hard && this.items.length) {
this.nextItem();
}
else {
this.goto(this.index + 1);
this.item = 0;
// Mark all items as not displayed, if there are any
if(this.items.length) {
for (var i=0; i<this.items.length; i++) {
var classes = this.items[i].classList;
if(classes) {
classes.remove('displayed');
classes.remove('current');
}
}
}
}
},
nextItem: function() {
if(this.item < this.items.length) {
this.gotoItem(++this.item);
}
else {
this.item = 0;
this.next(true);
}
},
previous: function(hard) {
if(!hard && this.item > 0) {
this.previousItem();
}
else {
this.goto(this.index - 1);
this.item = this.items.length;
// Mark all items as displayed, if there are any
if(this.items.length) {
for (var i=0; i<this.items.length; i++) {
if(this.items[i].classList) {
this.items[i].classList.add('displayed');
}
}
// Mark the last one as current
var lastItem = this.items[this.items.length - 1];
lastItem.classList.remove('displayed');
lastItem.classList.add('current');
}
}
},
previousItem: function() {
this.gotoItem(--this.item);
},
getSlideById: function(id) {
return $('.slide#' + id);
},
/**
Go to an aribtary slide
@param which {String|Integer} Which slide (identifier or slide number)
*/
goto: function(which) {
var slide;
// We have to remove it to prevent multiple calls to goto messing up
// our current item (and there's no point either, so we save on performance)
window.removeEventListener('hashchange', this, false);
var id;
if (which + 0 === which && which in this.slides) {
// Argument is a valid slide number
this.index = which;
this.slide = this.order[which]
slide = this.slides[this.slide];
location.hash = '#' + slide.id;
}
else if (which + '' === which) { // Argument is a slide id
slide = this.getSlideById(which);
if(slide) {
this.slide = this.index = +slide.getAttribute('data-index');
location.hash = '#' + which;
}
}
if (slide) { // Slide actually changed, perform any other tasks needed
document.title = slide.getAttribute('data-title') || documentTitle;
if (slide.classList.contains('iframe')) {
var iframe = $('iframe', slide), src;
if(iframe && !iframe.hasAttribute('src') && (src = iframe.getAttribute('data-src'))) {
iframe.setAttribute('src', src);
}
}
else {
this.adjustFontSize();
}
$('#onscreen-nav').style.display = this.isIpad || slide.classList.contains('onscreen-nav')? '' : 'none';
// Hide iframes from CSSS imports
$$('iframe.csss-import').forEach(function (iframe) { iframe.classList.remove('show'); });
this.indicator.textContent = this.index + 1;
// Update items collection
this.items = $$('.delayed, .delayed-children > *', this.slides[this.slide]);
this.items.stableSort(function(a, b){
return (a.getAttribute('data-index') || 0) - (b.getAttribute('data-index') || 0)
});
this.item = 0;
this.projector && this.projector.goto(which);
// Update next/previous
var previousPrevious = this.slides.previous,
previousNext = this.slides.next;
this.slides.previous = this.slides[this.order[this.index - 1]];
this.slides.next = this.slides[this.order[this.index + 1]];
this.slides.previous && this.slides.previous.classList.add('previous');
this.slides.next && this.slides.next.classList.add('next');
if (previousPrevious && previousPrevious != this.slides.previous) {
previousPrevious.classList.remove('previous');
}
if (previousNext && previousNext != this.slides.next) {
previousNext.classList.remove('next');
}
}
// If you attach the listener immediately again then it will catch the event
// We have to do it asynchronously
var me = this;
setTimeout(function() {
addEventListener('hashchange', me, false);
}, 1000);
},
gotoItem: function(which) {
this.item = which;
var items = this.items, classes;
for(var i=items.length; i-- > 0;) {
classes = this.items[i].classList;
classes.remove('current');
classes.remove('displayed');
if (classes.contains('dummy') && items[i].dummyFor) {
items[i].dummyFor.removeAttribute('data-step');
}
}
for (var i=this.item - 1; i-- > 0;) {
items[i].classList.add('displayed');
}
if (this.item > 0) { // this.item can be zero, at which point no items are current
var item = items[this.item - 1];
item.classList.add('current');
// support for nested lists
for (var i = this.item - 1, cur = items[i], j; i > 0; i--) {
j = items[i - 1];
if (j.contains(cur)) {
j.classList.remove('displayed');
j.classList.add('current');
}
}
if (item.classList.contains('dummy') && item.dummyFor) {
item.dummyFor.setAttribute('data-step', item.dummyIndex);
}
}
this.projector && this.projector.gotoItem(which);
},
adjustFontSize: function() {
// Cache long lookup chains, for performance
var htmlStyle = html.style,
scrollRoot = html.scrollHeight? html : body,
innerHeight = window.innerHeight,
innerWidth = window.innerWidth,
slide = this.slides[this.slide];
// Clear previous styles
htmlStyle.fontSize = '';
if(body.classList.contains('show-thumbnails')
|| slide.classList.contains('dont-resize')) {
return;
}
for(
var percent = 100;
(scrollRoot.scrollHeight > innerHeight || scrollRoot.scrollWidth > innerWidth) && percent >= 35;
percent-=5
) {
htmlStyle.fontSize = percent + '%';
}
// Individual slide
if(slide.clientHeight && slide.clientWidth) {
// Strange FF bug: scrollHeight doesn't work properly with overflow:hidden
var previousStyle = slide.getAttribute('style');
slide.style.overflow = 'auto';
for(
;
(slide.scrollHeight > slide.clientHeight || slide.scrollWidth > slide.clientWidth) && percent >= 35;
percent--
) {
htmlStyle.fontSize = percent + '%';
}
slide.setAttribute('style', previousStyle);
}
if(percent <= 35) {
// Something probably went wrong, so just give up altogether
htmlStyle.fontSize = '';
}
},
// Is the element on the current slide?
onCurrent: function(element) {
var slide = _.getSlide(element);
if (slide) {
return '#' + slide.id === location.hash;
}
return false;
},
onSlide: function(id, callback, once) {
var me = this;
id = (id.indexOf('#') !== 0? '#' : '') + id;
var fired = false;
if (id == location.hash) {
callback.call(this.slides[this.slide]);
fired = true;
}
if (!fired || !once) {
addEventListener('hashchange', function() {
if (id == location.hash) {
callback.call(me.slides[me.slide]);
fired = true;
if (once) {
removeEventListener('hashchange', arguments.callee);
}
}
});
}
}
};
/**********************************************
* Static methods
**********************************************/
// Helper method for plugins
_.getSlide = function(element) {
var slide = element;
while (slide && slide.classList && !slide.classList.contains('slide')) {
slide = slide.parentNode;
}
return slide;
}
})(document.head || document.getElementsByTagName('head')[0], document.body, document.documentElement);
//第一个立即执行函数的执行终点。
// Rudimentary style[scoped] polyfill
if (!('scoped' in document.createElement('style'))) {
addEventListener('load', function(){ // no idea why the timeout is needed
$$('style[scoped]').forEach(function(style) {
var rulez = style.sheet.cssRules,
parentid = style.parentNode.id || SlideShow.getSlide(style).id || style.parentNode.parentNode.id;
for(var j=rulez.length; j--;) {
var selector = rulez[j].selectorText.replace(/^|,/g, function($0) {
return '#' + parentid + ' ' + $0
});
var cssText = rulez[j].cssText.replace(/^.+?{/, selector + '{');
style.sheet.deleteRule(j);
style.sheet.insertRule(cssText, j);
}
style.removeAttribute('scoped');
style.setAttribute('data-scoped', '');
});
});
}

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/koalalc-pptHtml.git
git@api.gitlife.ru:oschina-mirror/koalalc-pptHtml.git
oschina-mirror
koalalc-pptHtml
koalalc-pptHtml
master