SoundCloud: how to stop playing when hash change - ajax

I'm using ajax page switching method with SoundCloud script.
How to stop playing music when the user leaves the page with SoundCloud container?
I've found these stokes:
// stop all players, might be useful, before replacing the player dynamically
$.scPlayer.stopAll = function() {
$('.sc-player.playing a.sc-pause').click();
};
Currently I call initialization $(".sc-player").scPlayer(); inside .load function, but where do I need the put the code which will stop playing audio before any page switching?

you can add event listener window.onhashchange = stopAll;
and definition of stopAll() will be
stopAll = function() {
$('.sc-player.playing a.sc-pause').click();
};

Related

Electron webview events

I'm writing an app in electron and came across with some issues, appreciate if anyone can help.
I'm navigating a webview to src="about:blank"
and load it with
var urlOptions = {
extraHeaders: 'Authorization: Bearer ' + arg.token
};
webview.loadURL(arg.viewToLoad, urlOptions);
Then, when the dom-ready event is triggered, I'm calling
webview.addEventListener('did-finish-load', () => spiner.hide());
I'm trying to make a spinner stop after the webview is finished loading but the 'did-finish-load' event fires twice - this causes a blank page for couple of seconds.
Does anyone has a clue why?
I looked the documentation again but this is not explained right. Is there an event that's triggered once after all resources are done downloading and are ready to show?
The 'did-finish-load' event is triggered 2 times : when you load the about:blank, and when you use loadURL().
To convince you, try this:
main.js :
const { BrowserWindow} = require('electron')
let win = new BrowserWindow({width: 1450, height: 1200})
win.webContents.on('did-finish-load', () => {
console.log('finished to load ');
})
win.loadURL(`about:blank`)
Then you will notice that did-finish-load has been triggered!
That's why the event is triggered two times in your code.
Note that the important part here is the webContents EventEmitter, that is an attribute of both BrowserWindows and webviews. I used a BrowserWindow to keep the example minimal.

How do I find out with Mootools if an element is being animated?

I need to be able to detect is an animation is currently happening using Mootools.
Of course if there is a way to detect this with plain old js even better. But I couldn't think of a way to do this without running it every ms and seeing if the styles are changing.
How i'm doing the animation
new Fx.Tween(c.getElement('.is-active'), {
property: 'opacity',
duration: e.options.speed,
onComplete: function () {
this.element
.removeClass("is-active")
.addClass("is-hidden")
.setStyle('display', "")
.setStyle('opacity', "");
}
}).start(0).wait(e.options.speed);
One way that I often use is to check if animation is running with isRunning function:
// constructor
var fx = new Fx.Tween( ....
// later when I want to check if animation is running
if ( fx.isRunning() ) ...

Handle ajax response with node.js

I am trying to scrape information from a specified website. This site uses authentication first, thus a i use zombie.js:
var Browser = require("zombie");
var browser = new Browser();
browser.visit("https://*****login.aspx", function(){
browser.fill('#user', '*****');
browser.fill('#pwd', '*****');
var button = browser.querySelector('#btnSubmit');
browser.fire('click', button, function(){
//scraping main.aspx
});
});
It's working, i can scrape the main.aspx: there is a <table>, containig information about new messages(from, date, subject,), the problems comes here: the subject field is clickable, and clicking on it makes a new window appear with the actual message. However it is an ajaxgrid, and when i perform a click:
var field = browser.querySelector('#VeryLongIdOfTheField');
browser.fire('click', field, function(){
console.log(browser.querySelector('#VeryLongIdOfTheFieldContainingTheMessage').innerHTML);
});
it returns an error message, saying that undefined has no innerHTML. I suppose its because this action handled with some ajax magic. I am new in this js/nodejs/jquery/.. world, some help needed to enlight me.
Since the data is populated using async ajax, I'm guessing there's a lag between your click and the actual DOM population inside the node. How about waiting for a bit before checking the content inside the node.
browser.fire('click', field, function(){
setTimeout(function(){
console.log(browser.querySelector('#VeryLongIdOfTheFieldContainingTheMessage').innerHTML);
}, 3000)
});
If the time taken is not very predictable, you could also run it inside a loop until you find the content or exit after a reasonable number of retries.

jQuery .load() wait till content is loaded

How to prevent jQuery $('body').load('something.php'); from changing any DOM till all the content from something.php (including images,js) is fully loaded
-Lets say some actual content is:
Hello world
And something.php content is:
image that loads for 10 seconds
20 js plugins
After firing .load() function nothing should happen, till images an js files are fully loaded, and THEN instantly change the content.
some preloader may appear, but its not subject of question.
[edit]----------------------------------------------------------------------
My solution for that was css code (css is loaded always before dom is build) that has cross-browser opacity 0.
.transparent{
-moz-opacity: 0.00;
opacity: 0.00;
-ms-filter:"progid:DXImageTransform.Microsoft.Alpha"(Opacity=0);
filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0);
filter:alpha(opacity=0);
}
And it prevent from bad flickr of content usually but not always. Now its possible to detect somehow that content is loaded by jQuery ajax and apply some show timeout and so on. But in fact question is still open.
To make now a little more simple example for that question:
How to begin changing DOM after $('body').load('something.php') with 3000ms delay after clicking the link that fire .load('something.php') function? (Browser should start downloading instantly, but DOM changing has to be initiated later)
Use .get instead and assign the contents in the success callback:
$.get('something.php', function(result) {
$('body').html(result);
});
There are some implementation details you may have to solve yourself, but here's a rough solution:
Don't use .load() directly. It can't be changed to wait for all images to load.
Use $.get() to fetch the HTML into a variable, let's call it frag.
Use $(frag).find('img').each(fn) to find all images and dump each this.src inside a preloader.
var images = [],
$frag = $(frag),
loaded = 0;
function imageLoaded()
{
++loaded;
// reference images array here to keep it alive
if (images.ready && loaded >= images.length) {
// add $frag to the DOM
$frag.appendTo('#container');
}
}
$frag.find('img').each(function() {
var i = new Image();
i.onload = i.onerror = imageLoaded;
i.src = this.src;
images[images.length] = i;
});
// signal that images contains all image objects that we wish to monitor
images.ready = true;
Demo
Once all images are loaded, append the earlier frag to the DOM using $frag.appendTo('#container').
Here is a quick proof of concept that loads relevant images before inserting an HTML fragment into the DOM: http://jsfiddle.net/B8B6u/5/
You can preload the images using the onload handler to trigger iterations:
var images = $(frag).find('img'),
loader = $('<img/>');
function iterate(i, callback) {
if (i > 0) {
i--;
loader.unbind("load");
loader.load(function() {
iterate(i, callback);
});
loader.attr('src', images[i].src);
}else{
callback();
}
}
iterate(images.length,function(){
$('#container').html(frag);
});
This should work, since each image is loaded after the previous one has finished loading.
Have you tried this?
$(function(){$('body').load('something.php')});
Edit: I just realized you are actually wanting to wait for the stuff to load before it get's placed in the body.
Here are three links to similar questions.
Preloading images with jQuery
Is it possible to preload page contents with ajax/jquery technique?
Preloading images using PHP and jQuery - Comma seperated array?
You can probably adapt those to scripts too.
This might work too.
$.ajax({
'url': 'content.php',
'dataType': 'text',
'success': function(data){
var docfrag = document.createDocumentFragment();
var tmp = document.createElement('div'), child;
//get str from data here like: str data.str
tmp.innerHTML = str;
while(child = tmp.firstChild){
docfrag.appendChild(child);
}
$('body').append(docfrag);
}
});
It's a longer way of doing what Shadow Wizard suggests, but it will probably work.
Hm. Never mind. Jack's answer looks the best. I'll wait a while and if no one likes my answer I'll delete it.
Edit: It looks like appending to documentfragments can do http requests.
Any script using createDocumentFrament may benefit from preloading.
In this question they want no http requests even though that's what createDocumentFragment is doing:
Using documentFragment to parse HTML without sending HTTP requests.
I can't be sure if this is true for all browsers or just when the console.log is run, but it could be a good option for preloading if this behavior is universal.

Track Youtube player's states in YUI.add

My embed code to play Youtube video is:
<object height="356" width="425" type="application/x-shockwave-flash" id="myytplayer" data="http://www.youtube.com/v/MTf6qXn5Prw?enablejsapi=1&playerapiid=ytplayer&version=3"><param name="allowScriptAccess" value="always"></object>
I want to track Youtube player's events (play/pause/stop etc)
The following piece of code works independently
window.onYouTubePlayerReady = function(playerId){
ytplayer = document.getElementById("myytplayer");
ytplayer.addEventListener("onStateChange", "onytplayerStateChange");
}
window.onytplayerStateChange = function (newState) {
alert("Player's new state: " + newState);
}
I am using YUI.
When I put the same in
YUI.add('module-name', function(Y) {
[some other code...]
window.onYouTubePlayerReady = function(playerId){
// console.log(playerId); console.log(ytplayer);
ytplayer = document.getElementById("myytplayer");
ytplayer.addEventListener("onStateChange", "onytplayerStateChange");
}
window.onytplayerStateChange = function (newState) {
alert("Player's new state: " + newState);
}
},'3.4.0', {requires:'module-a', 'module-b'})
Function onytplayerStateChange works in Firefox and Safari but not in other browsers.
Then I tried YUI functions to make that working in all browsers so I did some changes
window.onYouTubePlayerReady = function(playerId){
var shinyPlayer = Y.one("#myytplayer");
shinyPlayer.on('onStateChange', function (e) {
e.preventDefault();
alert('here');
});
}
but it didn't work for me.
I don't want to place window.onytplayerStateChange outside of YUI.add('module-name', function(Y) {})
Please suggest what should I do to track Youtube player's states in all browsers.
Thanks in advance.
I made a jsFiddle to test this:
http://jsfiddle.net/2Mj6b/4/
For me it feels like addEventListener is a custom implementation of Google.
Normally the second parameter is a callback/function-pointer and no string.
If you attach a variable to the window object it gets global and is from every scope visible. So it's no problem if you define it in the YUI module.
The second problem is that you cant use the player as YUI object you have to stay on dom objects to get this work.
Oh this is a old question. Damn. But i will post this anyway. ;)

Resources