I've a problem with a html5 gallery.
This gallery must point to a html page after last slide transition.
I have 3 slides (a sort of splash composed by images) and after the third image I want to redirect on my website's home page.
<div class="slider">
<figure class="active">
<img src="gallery/hp-1.jpg" onload="imageLoaded();" alt="image 1" />
</figure>
<figure>
<img src="gallery/hp-2.jpg" alt="image 2" />
</figure>
<figure>
<img src="gallery/hp-3.jpg" alt="image 3" />
</figure>
</div>
<script>
(function($, window, document, undefined) {
var Html5Gallery = {
isTransitionInProgress : false,
isMusicPlaying : false,
fMusicPlayer : null,
nextSwitch : null,
fMusicPlayerIsLoaded : false,
isWindowReady : false,
imageIsStillLoading : true,
init : function(element, options)
{
var self = this;
$(window).ready(function(){
self.isWindowReady = true;
if (!self.imageIsStillLoading) {
self.handleReadness();
}
});
this.options = $.fn.extend({}, $.fn.Html5Gallery.options, options);
this.imageIsStillLoading = true;
$(window).bind("resize", this.handleResizing);
window.flashIsLoaded = function() {
self.flashPlayerLoaded();
};
window.imageLoaded = function() {
if(!$("figure.active img").get(0).complete)
{
self.isTransitionInProgress = true;
setTimeout(imageLoaded, 100);
return;
}
self.imageIsStillLoading = false;
if (self.isWindowReady) {
self.handleReadness();
}
};
},
nextImage: function(e)
{
if (this.isTransitionInProgress)
{
return;
}
this.cancelNextScheduledImage();
var from = $("figure.active");
var to = (from.next().is("figure") ? from.next() : from.parent().children(":first"));
this.isTransitionInProgress = true;
this.switchImages(from, to);
},
prevImage: function(e)
{
if (this.isTransitionInProgress)
return;
var from = $("figure.active");
var to = (from.prev().is("figure") ? from.prev() : from.parent().children(":last"));
this.isTransitionInProgress = true;
this.switchImages(from, to);
},
switchImages: function(from, to)
{
var self = this;
var isNextImageLoaded = to.children("img").get(0).complete;
if (isNextImageLoaded)
{
from.stop().fadeOut(self.options.transitionSpeed, function(){
from.removeClass("active").css("display", "none");
to.addClass("active");
self.handleResizing();
to.hide().fadeIn(self.options.transitionSpeed, function(){
self.isTransitionInProgress = false;
self.scheduleNextImage();
});
});
return;
}
$("#loading").hide().fadeIn(self.options.transitionSpeed, function(){
from.removeClass("active").css("display", "none");
to.addClass("active");
if (isNextImageLoaded)
{
self.handleResizing();
self.hideLoading();
}
else
{
imageLoaded();
}
});
},
hideLoading: function()
{
var self = this;
$("#loading").fadeOut(this.options.transitionSpeed, function(){
self.isTransitionInProgress = false;
self.scheduleNextImage();
});
},
cancelNextScheduledImage: function()
{
clearTimeout(this.nextSwitch);
this.nextSwitch = null;
},
scheduleNextImage: function()
{
var self = this;
this.cancelNextScheduledImage();
if (!this.isTransitionInProgress && this.options.autoSwitch)
{
this.nextSwitch = setTimeout(function(){
self.nextImage();
}, this.options.pauseOnPictureFor);
}
},
};
})
</script>
You can download here the html file complete with all code.
Thank you for your help.
Simone
You can hook into the logic which loops back to the first slide. This works by checking whether the next element is a figure element and, if not, grabbing the first figure element and switching to it. You can override this logic to redirect your page after the last slide has displayed like so (not tested):
nextImage: function(e)
{
if (this.isTransitionInProgress)
{
return;
}
this.cancelNextScheduledImage();
var from = $("figure.active");
// var to = (from.next().is("figure"); ? from.next() : from.parent().children(":first"));
var to = from.next();
if (to.is("figure")) {
this.isTransitionInProgress = true;
this.switchImages(from, to);
} else {
window.location.replace("http://stackoverflow.com");
}
},
I've hardcoded the URL in place for speed and clarity, but a better approach would be to pass the URL to the plugin via the options object it receives as a parameter of the init method.
Related
I'm using Slit Slider js. This opens div slides with arrows and dots for navigation. Is there a way to create a link to open a specific slide? For example: Home, About Us etc. instead of arrows.
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
$(function() {
var Page = (function() {
var $navArrows = $('#nav-arrows'),
$nav = $('#nav-dots > span'),
slitslider = $('#slider').slitslider({
onBeforeChange: function(slide, pos) {
$nav.removeClass('nav-dot-current');
$nav.eq(pos).addClass('na```v-dot-current');
}
}),
init = function() {
initEvents();
},
initEvents = function() {
// add navigation events
$navArrows.children(':last').on('click', function() {
slitslider.next();
return false;
});
$navArrows.children(':first').on('click', function() {
slitslider.previous();
return false;
});
$nav.each(function(i) {
$(this).on('click', function(event) {
var $dot = $(this);
if (!slitslider.isActive()) {
$nav.removeClass('nav-dot-current');
$dot.addClass('nav-dot-current');
}
slitslider.jump(i + 1);
return false;
});
});
};
return {
init: init
};
})();
Page.init();
});
Thanks for your support :)
I am creating a karaoke type website, I simply want to add HTML with the words. I also want to add a break tag so some lyrics are showing on the second page.
The codepen is here:- https://codepen.io/scottYg55/pen/OJPRyXy
As you can see I have tried adding in a break tag, but this isn't outputting as HTML. I understand this, but is there a way to change this?
Can anyone help with this?
var lyricsText = [
{
"text": "Intro <br>Ding Dong Merrily on High",
"duration": 3900
}];
var player = new Vue({
el: '#player',
data: {
lyrics: {
show: false,
timer: null,
currentLine: '',
text: lyricsText,
},
song : {
progress: 0
},
audio: null,
playing: false,
playerTouched: false
},
ready: function() {
// Setup the audio element
this.audio = this.$els.audio;
// Setup time tracker updates
this.audio.addEventListener('timeupdate', this.updateTimeTracker, false);
// Setup end reset
this.audio.addEventListener('ended', this.resetPlayer, false);
},
methods: {
hideText: function() {
this.lyrics.show = !this.lyrics.show;
},
startPlayback: function() {
this.playing = true;
this.audio.volume = 0.5;
this.audio.play();
this.lyrics.show = true;
this.displayNextLine(0);
},
togglePlayback: function() {
if (!this.playerTouched) {
this.startPlayback();
this.playerTouched = true;
return;
}
this.playing = !this.playing;
if (this.audio.paused) {
this.audio.play();
this.resumeLyrics();
} else {
this.audio.pause();
this.pauseLyrics();
}
},
pauseLyrics: function() {
if (this.lyrics.timer) {
this.lyrics.timer.pause();
}
},
resumeLyrics: function() {
if (this.lyrics.timer) {
this.lyrics.timer.resume();
}
},
displayNextLine: function(line) {
var _this = this;
// Set the currentLine, which will auto display
_this.lyrics.currentLine = _this.lyrics.text[line].text;
if (_this.lyrics.text[line + 1] !== undefined) {
_this.lyrics.timer = new Timer(function() {
_this.displayNextLine(line + 1);
}, _this.lyrics.text[line].duration);
}
//else {
// _this.lyrics.currentLine = 'THE END';
//}
},
updateTimeTracker: function() {
this.song.progress = 100 * (this.audio.currentTime / this.audio.duration);
},
resetPlayer: function() {
this.playing = false;
this.playerTouched = false;
}
}
});
function Timer(callback, delay) {
var timerId;
var start;
var remaining = delay;
this.pause = function() {
window.clearTimeout(timerId);
remaining -= new Date() - start;
};
this.resume = function() {
start = new Date();
window.clearTimeout(timerId);
timerId = window.setTimeout(callback, remaining);
};
this.resume();
}
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.0-rc.2/vue.js"></script>
<div class="Player" id="player">
<audio src="dd.mp3"
v-el:audio></audio>
<div class="Player__cover" #click="hideText">
<div class="Player__lyrics">
<div class="line"
v-if="lyrics.show"
v-text="lyrics.currentLine"></div>
</div>
</div>
<div class="Player__track"
:style="{ width: song.progress + '%' }"></div>
<div class="Player__controls">
<i class="icon play material-icons"
v-text="playing ? 'pause_circle_filled' : 'play_circle_filled'"
#click="togglePlayback"></i>
</div>
</div>
Try using v-html directive instead of v-text on your HTML.
<div class="line" v-if="lyrics.show" v-html="lyrics.currentLine"></div>
There are two main ways to create elements in Javascript. The first is to use createElement() function:
const div = document.createElement("div");
div.innerHTML = "I'm a div";
div.id = "myDiv";
document.body.appendChild(div);
#myDiv{
color: red;
}
The second is to use the innerHTML property on an existing element:
const div = document.getElementById("myDiv");
div.innerHTML = "<p>I'm a p tag</p>";
p{
color: green;
}
<div id="myDiv"></div>
I am making an app on visual studio 2012. I am navigating from home page to levelOne. On a button click on level one i'm doing some animation,during animation if i get back to home page using windows back button, and then again come back to level one i get the animation running ,i want this animation to get stopped.
This is my first page where the animation will occur:
(function () {
"use strict";
WinJS.UI.Pages.define("/pages/levelOne/levelOne.html", {
// This function is called whenever a user navigates to this page. It
// populates the page elements with the app's data.
ready: function initiazlize(element, options) {
document.getElementById("play").addEventListener("click",function initial(){
roundCount++;
if (flag1 == false) {
//if flag1 is false that means its time for next storyboard
j = 0;
var r3 = Math.random();
if (r3 <= 0.333) {
$(Left).animate({ marginTop: '-=100px' }, 500);
$(Left).animate({ marginTop: '+=100px' }, 500, animateAsync);
//document.getElementById("play").disabled = false;
}
else if (r3 <= 0.666) {
$(midle).animate({ marginTop: '-=100px' }, 500);
$(midle).animate({ marginTop: '+=100px' }, 500, animateAsync);
//document.getElementById("play").disabled = false;
}
else {
$("#bowlThree").animate({ marginTop: '-=100px' }, 500);
$("#bowlThree").animate({ marginTop: '+=100px' }, 500, animateAsync);
//document.getElementById("play").disabled = false;
}
//inside animate Async(), some more animation on capOne,capTwo,capThree and on object, I want to stop animation on these
//There is a counter j, when j reachs 100 animation is stopped
}
});
document.onbeforeunload = function () {
j = 100;
flag1 = true;
$("#capOne").stop(true, false);
$("#capTwo").stop(true, false);
$("#capThree").stop(true, false);
clearTimeout(variableTimer);
window.cancelAnimationFrame(variableTimer);
Debug;
};
},
unload: function () {
// TODO: Respond to navigations away from this page.
$("#capOne").stop();
$("#capOne").css({ "margin-top": "360px", "margin-left": "250px" })
$("#capTwo").css({ "margin-top": "360px", "margin-left": "580px" })
$("#capThree").css({ "margin-top": "360px", "margin-left": "910px" })
////return false;
$("#capOne").fadeOut(100);
WinJS.UI.disableAnimations();
flag1 = true;//if flag1=false then animation is stopped
$("#capOne").stop(true, false);
$("#capTwo").stop(true, false);
$("#capThree").stop(true, false);
clearTimeout(document.variableTimer);
window.cancelAnimationFrame(document.variableTimer);
debugger;
},
updateLayout: function (element, viewState, lastViewState) {
/// <param name="element" domElement="true" />
// TODO: Respond to changes in viewState.
}
});
})();
Here is the navigator.js file
(function () {
"use strict";
var appView = Windows.UI.ViewManagement.ApplicationView;
var nav = WinJS.Navigation;
WinJS.Namespace.define("Application", {
PageControlNavigator: WinJS.Class.define(
// Define the constructor function for the PageControlNavigator.
function PageControlNavigator(element, options) {
this._element = element || document.createElement("div");
this._element.appendChild(this._createPageElement());
this.home = options.home;
this._lastViewstate = appView.value;
nav.onnavigated = this._navigated.bind(this);
window.onresize = this._resized.bind(this);
document.body.onkeyup = this._keyupHandler.bind(this);
document.body.onkeypress = this._keypressHandler.bind(this);
document.body.onmspointerup = this._mspointerupHandler.bind(this);
Application.navigator = this;
}, {
home: "",
/// <field domElement="true" />
_element: null,
_lastNavigationPromise: WinJS.Promise.as(),
_lastViewstate: 0,
// This is the currently loaded Page object.
pageControl: {
get: function () { return this.pageElement && this.pageElement.winControl; }
},
// This is the root element of the current page.
pageElement: {
get: function () { return this._element.firstElementChild; }
},
// Creates a container for a new page to be loaded into.
_createPageElement: function () {
var element = document.createElement("div");
element.style.width = "100%";
element.style.height = "100%";
return element;
},
// Retrieves a list of animation elements for the current page.
// If the page does not define a list, animate the entire page.
_getAnimationElements: function () { //IHDAr
if (this.pageControl && this.pageControl.getAnimationElements) {
return this.pageControl.getAnimationElements();
}
return this.pageElement;
},
// Navigates back whenever the backspace key is pressed and
// not captured by an input field.
_keypressHandler: function (args) {
if (args.key === "Backspace") {
nav.back();
}
},
// Navigates back or forward when alt + left or alt + right
// key combinations are pressed.
_keyupHandler: function (args) {
if ((args.key === "Left" && args.altKey) || (args.key === "BrowserBack")) {
nav.back();
} else if ((args.key === "Right" && args.altKey) || (args.key === "BrowserForward")) {
nav.forward();
}
},
// This function responds to clicks to enable navigation using
// back and forward mouse buttons.
_mspointerupHandler: function (args) {
if (args.button === 3) {
nav.back();
} else if (args.button === 4) {
nav.forward();
}
},
// Responds to navigation by adding new pages to the DOM.
_navigated: function (args) {
var newElement = this._createPageElement();
var parentedComplete;
var parented = new WinJS.Promise(function (c) { parentedComplete = c; });
this._lastNavigationPromise.cancel();
this._lastNavigationPromise = WinJS.Promise.timeout().then(function () {
return WinJS.UI.Pages.render(args.detail.location, newElement,args.detail.state, parented);
}).then(function parentElement(control) {
var oldElement = this.pageElement;
if (oldElement.winControl && oldElement.winControl.unload) {
oldElement.winControl.unload();
}
this._element.appendChild(newElement);
this._element.removeChild(oldElement);
oldElement.innerText = "";
this._updateBackButton();
parentedComplete();
var history = args.detail.state;
WinJS.UI.Animation.enterPage(this._getAnimationElements()).done(
function () {
}
);//IDHAR
}.bind(this));
args.detail.setPromise(this._lastNavigationPromise);//IDHAR BHI
},
// Responds to resize events and call the updateLayout function
// on the currently loaded page.
_resized: function (args) {
if (this.pageControl && this.pageControl.updateLayout) {
this.pageControl.updateLayout.call(this.pageControl, this.pageElement, appView.value, this._lastViewstate);
}
this._lastViewstate = appView.value;
},
// Updates the back button state. Called after navigation has
// completed.
_updateBackButton: function () {
var backButton = this.pageElement.querySelector("header[role=banner] .win-backbutton");
if (backButton) {
backButton.onclick = function () { nav.back(); };
if (nav.canGoBack) {
backButton.removeAttribute("disabled");
} else {
backButton.setAttribute("disabled", "disabled");
}
}
},
}
)
});
})();
I want to play the songs only if the user press the button 'play',
without Waiting to load all the 21 songs.
when I press the button 'play' the page jump up like refreshing ,it is not normal.
what I can do to improve my code.
please try to play the songs in the example site and see the problem.
many thanks.
var Music = {
init:function(){
song = new Audio();
//speaKer = document.getElementById("imgSpeaker");
this.volume = 0.08;
this.isMute = false;
canPlayMP3 = (typeof song.canPlayType === "function" && song.canPlayType("audio/mpeg") !== "");
song.src = canPlayMP3 ? "http://rafih.co.il/wp-content/uploads/2013/07/1.mp3" : "http://rafih.co.il/wp-content/uploads/2013/07/1.ogg";
song.preload = 'auto';
},
/* start:function(){
song.src = canPlayMP3 ? "http://rafih.co.il/wp-content/uploads/2013/07/1.mp3" : "http://rafih.co.il/wp-content/uploads/2013/07/1.ogg";
song.volume = 0.08;
song.autoplay = true;
song.load();
},*/
play: function () {
song.volume = 0.08;
song.autoplay = true;
song.load();
// Music.speaker();
},
stop: function () {
if (!song.ended) {
song.pause();
}
},
next: function () {
if (curr < count) {
curr++;
}else curr = 1;
song.src = canPlayMP3 ? "http://rafih.co.il/wp-content/uploads/2013/07/" + curr + ".mp3" : "http://rafih.co.il/wp-content/uploads/2013/07/" + curr + ".ogg";
},
};
function load() {
Music.init();
}
You need to return false from the play buttons event handler, to prevent the page from scrolling to the top.
Change:
<div id="play" onclick='Music.play()'>
To:
<div id="play" onclick='Music.play(); return false;'>
That's because of the anchor in your link, such as href="#". A very simple fix would be to add return false; in to your inline handler attribute, such as onclick="Music.play(); return false;", however that isin't a good approach and is considered a bad practice.
Instead you could add your handlers programmatically, it will also make your code more modular and testable:
var Music = {
init: function (options) {
var playBtn = this.playBtn = document.querySelector(options.playBtn);
playBtn.addEventListener('click', this._onPlayBtnClick.bind(this));
//...
return this;
},
_onPlayBtnClick: function (e) {
e.preventDefault(); //prevents the browser's default behaviour
this.play();
},
//...
};
Then you could do something like:
function load() {
var musicController = Object.create(Music).init({
playBtn: '#play',
//...
});
}
You could also use it as a singleton like:
Music.init({ ... });
i have a problem with a InfiniteScrolls calls, this is a part of code in 'Friends' for example:
var InfiniteScrollView = Backbone.View.extend({
el : window,
container : '#profile-friends',
triggerHeight : 10, //px
events : {
'scroll' : 'throttledDetectBottomPage'
},
initialize : function() {
this.throttledDetectBottomPage = _.throttle(this.detectBottomPage, 1000);
},
detectBottomPage : function() {
var self = this;
var offset = $(this.container).height() - this.$el.height() - this.triggerHeight;
if (this.$el.scrollTop() >= offset) {
self.nextPage();
}
},
stop : function() {
this.$el.unbind('scroll');
},
nextPage : function() {
if (this.collection.activeScroll == true) {
this.collection.nextPage();
if (!this.collection.isPaginated) {
if (this.collection.length == 0) {
this.renderNotFoundPage();
this.stop();
return false;
}
} else {
if (this.collection.length == 0) {
this.renderNotFoundMoreResults();
this.stop();
return false;
}
}
}
},
renderNotFoundMoreResults : function() {
$('#profile-friends').append('No more results');
},
renderNotFoundPage : function() {
var container = $(this.container);
container.html('0 results');
}
});
In this.collection.nextPage() is called 'api/friends/pag', pag = page number.
Here the code of the collection:
// profile friends collection
define(
['underscore',
'backbone',
'models/user'],
function(_, Backbone, User){
var PFriendsCollection = Backbone.Collection.extend({
// Reference to this collection's model.
model: User,
initialize: function(){
this.isPaginated = false;
this.active = false;
},
//Call in render
search: function() {
this.page = 1;
this.isPaginated = false;
this.active = true;
this.fetch();
},
//Call in Infinite Scroll view NextPage
nextPage: function() {
if(this.active) {
this.isPaginated = true;
this.page = parseInt(this.page) + 1;
this.fetch({update: true});
}
},
// Url, points to the server API
url: function() {
return 'api/pfriends/' + this.page;
},
// Url, points to the server API
// ATM it is just a json test file
parse: function(response){
// extract items from response.
return response.items;
}
});
return new PFriendsCollection;
});
I created this view in the render() function of FriendsView, and down I surje a problem: i go bottom and trigger launch, but he launch a lot of times if i move the scroll, he call api/pfriends/2, api/pfriends/3, api/friends/4 (For example, is random the number of calls) in the same moment, because he don't wail the first response and launch trigger :(
I do not know where to put a trigger, result or something that blocks the execution of that scroll trigger whenever there pending fetch response.
Thanks =)
fetch returns a jQuery deferred, so you could try this in your collection's nextPage:
return this.fetch({update: true});
Then in your view:
nextPage : function() {
if (this.collection.activeScroll == true && !this.updating) {
var self = this;
this.updating = true;
// function passed to 'always' is called whether the fetch succeeded or failed
this.collection.nextPage().always(function(){
self.updating = false;
if (!self.collection.isPaginated) {
if (self.collection.length == 0) {
self.renderNotFoundPage();
self.stop();
return false;
}
} else {
if (self.collection.length == 0) {
self.renderNotFoundMoreResults();
self.stop();
return false;
}
}
}
}
},
You might want to actually use done and fail instead of always. Check the documentation for more info.