Send an Array to an object constructor in JQuery - javascript

I'm trying to send values of an array created by checkboxes to the constructor of a "buzz" sound object. Code Follows.
<input type="checkbox" name="loops" value="drums01" id="drums01" class="Checkbox" > Drums #1</li>
<li><input type="checkbox" name="loops" value="drums02" id="drums02" class="Checkbox"> Drums #2</li>
<li><input type="checkbox" name="loops" value="guitar01" id="guitar01" class="Checkbox"> Guitar #1</li>
//CHECKBOXES
<button class="button button_type_sound" id="b01">Play<q class="key" id="key_q">Q</q></button>
//BUTTON
var arr = new Array();
var drums01 = new buzz.sound("drumloop01", {
formats: [ "wav" ],
preload: true,
autoplay: false,
loop: true
});
var drums02 = new buzz.sound("drumloop02", {
formats: [ "wav" ],
preload: true,
autoplay: false,
loop: true
});
var guitar01 = new buzz.sound("guitarloop01", {
formats: [ "wav" ],
preload: true,
autoplay: false,
loop: true
});
//ATTEMPT TO CREATE SOUND OBJECT FROM ARRAY AND PLAY IT
$("#b01").click(function(event){
event.preventDefault();
var arr = new Array( $("input:checkbox:checked").map(function(){
return this.value;
}).toArray());
console.log(arr.toString());
console.log("Try Playing Sound");
console.log(arr.toString());
var myGroup = new buzz.group(arr.toString());
myGroup.play();
});
Console Gives me the following error:
drums01,drums02 index.html:68
Try Playing Sound index.html:71
drums01,drums02 index.html:72
Uncaught TypeError: Cannot call method 'apply' of undefined

Here is a working fiddle created fixing the code you posted in your question.
http://jsfiddle.net/fmKeV/3/
Explanation
As you may see, in the "init section" I create an object literal of instances of buzz.sound.
Then, in the event handler of the button I map every selected checkbox to the corresponding sound (I changed the value of the input elements so that it is the same as the key in the buzzSounds object).
The new Array in new Array($() ... .toArray()) in your code is not needed. The toArray() method called on the result of the map function is sufficient, otherwise the result would be a nested array, which is not what the buzz.group function needs.
Code
Markup
<ul class="sounds">
<li>
<input type="checkbox" name="loops" value="drumloop01" id="drums01" class="Checkbox" />Drums #1</li>
<li>
<input type="checkbox" name="loops" value="drumloop02" id="drums02" class="Checkbox" />Drums #2</li>
<li>
<input type="checkbox" name="loops" value="guitarloop01" id="guitar01" class="Checkbox" />Guitar #1</li>
</ul>
<button class="button button_type_sound" id="b01">Play
<q class="key" id="key_q">Q</q>
</button>
Javascript
$(document).ready(function() {
// init sounds
var buzzSounds = {};
buzzSounds.drumloop01 = new buzz.sound("drumloop01", {
formats: ["wav"],
preload: true,
autoplay: false,
loop: true
});
buzzSounds.drumloop02 = new buzz.sound("drumloop02", {
formats: ["wav"],
preload: true,
autoplay: false,
loop: true
});
buzzSounds.guitarloop01 = new buzz.sound("guitarloop01", {
formats: ["wav"],
preload: true,
autoplay: false,
loop: true
});
//CLICK EVENT HANDLER
$("#b01").on('click', function(e) {
var sounds, group;
//0) Prevent default
e.preventDefault();
//1) map every selected element to the sound defined in the "buzzSounds" object
toPlay = $(".sounds input:checkbox:checked").map(function() {
return buzzSounds[this.value];
}).toArray();
//2) create a group from the collected buzz.sound instances
myGroup = new buzz.group(toPlay);
//3) play the group
console.log("Try Playing Sounds", toPlay, myGroup);
try {
myGroup.play();
} catch (e) {
console.log('uh-oh', e);
//in this example the sound files have not been loaded, so an error could be raised
}
});
});

Try something like this:
$(document).ready(function () {
var drums01 = new buzz.sound("drumloop01", {
formats: ["wav"],
preload: true,
autoplay: false,
loop: true
});
var drums02 = new buzz.sound("drumloop02", {
formats: ["wav"],
preload: true,
autoplay: false,
loop: true
});
var guitar01 = new buzz.sound("guitarloop01", {
formats: ["wav"],
preload: true,
autoplay: false,
loop: true
});
//ATTEMPT TO CREATE SOUND OBJECT FROM ARRAY AND PLAY IT
$("#b01").click(function (event) {
event.preventDefault();
var arr = new Array();
$('input[type="checkbox"]').each(function () {
arr.push($(this).val());
});
console.log(arr.toString());
console.log("Try Playing Sound");
console.log(arr.toString());
var myGroup = new buzz.group(arr.toString());
myGroup.play();
});
});
Let me know how it works out.
fiddle

as far as I know, to create a buzz.group we should pass the array no the string:
Sounds can be added to a group by passing an array to the constructor.
but you pass string instead, so it should be like this:
var myGroup = new buzz.group([
mySound1,
mySound2,
mySound3
]);
I changes your fiddle example like this:
$(document).ready(function () {
var drums = {};
drums.drums01 = new buzz.sound("drumloop01", {
formats: ["wav"],
preload: true,
autoplay: false,
loop: true
});
drums.drums02 = new buzz.sound("drumloop02", {
formats: ["wav"],
preload: true,
autoplay: false,
loop: true
});
drums.guitar01 = new buzz.sound("guitarloop01", {
formats: ["wav"],
preload: true,
autoplay: false,
loop: true
});
$("#b01").click(function (event) {
event.preventDefault();
var arr = new Array();
$('input[type="checkbox"]:checked').each(function () {
arr.push(drums[$(this).val()]);
});
var myGroup = new buzz.group(arr.toString());
myGroup.play();
});
});
check the new DEMO out.
The Problem in you have in your code is, you are passing the variable names as a string array, whereas you should pass the actual objects. to solve your problem you should make them accessible using a accessible in the context object like var drums = {} which you can use it in your anonymous function.
for mor information check this link out.

Related

How to get these numbers from var stocks while scraping web?

<form class="col-xs-12"> <script type="text/javascript">
var stocks = {
"938975": true,
"938977": true,
"938979": true,
"938981": true,
"938983": true,
"938985": true,
"938987": false,
"938989": true,
"938991": true,
"938993": true,
"938995": true,
"938997": false,
"938999": true,
"939001": true,
"939003": true,
"939005": true,
"939007": true
};
How do I get and loop it, that if there is a true value in var stocks for any variable bot goes further but when there is false it stops?
For now I'm using something like that, hope you understand:
div = soup.find("form",("class"=="col-xs-12")).find("script",("type"=="text/javascript"
I’m doing bot in python
See if this can help!
Have added the code so if we have some entries at the end, even if we do not have false, they also get added. Its outside the loop and can be removed if not needed.
var stocks = {"938975":true,"938977":true,"938979":true,"938981":true,"938983":true,"938985":true,"938987":false,"938989":true,"938991":true,"938993":true,"938995":true,"938997":false,"938999":true,"939001":true,"939003":true,"939005":true,"939007":true};
var arraysOfStocks = [],tempArray = [];
for (let [key, value] of Object.entries(stocks)) {
//console.log(key +":"+value);
if(value){
tempArray.push(key);
} else {
arraysOfStocks.push(tempArray);
tempArray = [];
}
}
arraysOfStocks.push(tempArray);
tempArray = [];
console.log(arraysOfStocks);

How to interact with buzz.sound function outside function scope?

function audio(path2audio){
var mySound = new buzz.sound ( path2audio, {
formats: ["mp3"],
preload: false,
autoplay: false,
loop: false,
volume: 70,
});
mySound.play();
}
http://buzz.jaysalvat.com/documentation/sound/
Well, I need to make a trigger called outside this function in order to stop the audio file to stop playing. My difficulty is that whenever I call the method outside the function, it shows an error: "main.js:40 Uncaught TypeError: Cannot read property 'bind' of undefined".
mySound.bind('playing', function () {
mySound.stop();
});
Can somebody help me to solve this?
Try assigning it to a variable in the global or outer scope.
var myRealSound;
function audio(path2audio){
var mySound = new buzz.sound ( path2audio, {
formats: ["mp3"],
preload: false,
autoplay: false,
loop: false,
volume: 70,
});
myRealSound = mySound;
myRealSound.play();
}
myRealSound.bind('playing', function () {
myRealSound.stop();
});
OR... do the event binding in the same scope as your function.

How do I get the current element id which triggered horizonSwiper event in javascript?

I have implemented horizonSwiper in my php(Yii2) website for loading images of one album in one row with left and right scroll as well as swipe and having multiple albums in that page each have different id. And now I need to add lazyloading when scroll to left/right or swipe to left/right. But I didn't get the current selected div id to find the scrolling images album id.
I have used the following link for implementing swiper,
http://horizon-swiper.sebsauer.de/
And my javascript code as follows,
$('.horizon-swiper.fix-item-width').horizonSwiper({
showItems: 7,
arrows: true,
onSlideStart: function(){
alert('slide started');
},
onDragStart: function(){
alert('drag started');
}
});
I have added my album id with one '.horizon-swiper.fix-item-width' div and to get that inside onSlideStart and onDragStart function
My html is like follows,
<div class="horizon-swiper fix-item-width" id="alb_<?php echo $album['albumId']; ?>">
<div class="horizon-item" data-horizon-index="0" id="img_<?php echo $album['albumId']; ?>_<?php echo $count; ?>">
<div class="card view view-second">
<img class="img responsive " src="<?php echo $baseurl; ?>/images/uploaded_images/profile/<?php echo $img['img']; ?>" width="100%;" height="350px;">
</div>
</div>
</div>
Please note that this html is in a for loop
Can anyone help to find out one solution for this?
Thank you in advance...
I have seen the source code horizon-swiper.js. But as far as I think It doesn't have any functionality by which you can get the reference of current element on which swiper is going on (Sorry I may be wrong, I didn't have enough time to check it deeply). So I have slightly modified the horizon-swiper.js file, and now you can get the reference of current element on which swiper is going on.
in top of horizon-swiper.js file replace
var settings = {
// Default settings
item: '.horizon-item',
showItems: 'auto',
dots: false,
numberedDots: false,
arrows: true,
arrowPrevText: '',
arrowNextText: '',
animationSpeed: 500,
mouseDrag: true,
// Methods and callbacks
onStart: function onStart() {},
onEnd: function onEnd() {},
onSlideStart: function onSlideStart() {},
onSlideEnd: function onSlideEnd() {},
onDragStart: function onDragStart() {},
onDragEnd: function onDragEnd() {},
};
with
var settings = {
// Default settings
item: '.horizon-item',
showItems: 'auto',
dots: false,
numberedDots: false,
arrows: true,
arrowPrevText: '',
arrowNextText: '',
animationSpeed: 500,
mouseDrag: true,
// Methods and callbacks
onStart: function onStart() {},
onEnd: function onEnd() {},
onSlideStart: function onSlideStart() {},
onSlideEnd: function onSlideEnd() {},
onDragStart: function onDragStart() {},
onDragEnd: function onDragEnd() {},
currentElm:""
};
I have just added one more value in settings object named "currentElm"
and add following function
Plugin.prototype.getElem=function(){
this.settings.currentElm=this.$element;
}
after Plugin.prototype.init function
and replace
Plugin.prototype.init = function () {
var that = this;
that._setWrapper();
that._addArrows();
that._addDots();
that._mouseDrag();
that._setSizes();
that._resize();
that._checkPosition();
that.initialized = true;
};
with
Plugin.prototype.init = function () {
var that = this;
that._setWrapper();
that._addArrows();
that._addDots();
that._mouseDrag();
that._setSizes();
that._resize();
that._checkPosition();
that.getElem(); //call here our newly made function
that.initialized = true;
};
Now you can get the reference of element like following.
$('.horizon-swiper.fix-item-width').horizonSwiper({
arrows: true,
dots:true,
onSlideStart: function(){
console.log($(this)[0].currentElm.attr('id'));
},
onDragStart: function(){
}
});
ensure that you have id attribute for each div.
I hope this will help.

only allow change line and link. disable all other features with marked

http://jsfiddle.net/zsvbzwgL/1/
How to only allow change line and link. disable all other features with marked https://github.com/chjj/marked ?
(like font style, header, list style, image ...)
js
marked.setOptions({
renderer: new marked.Renderer(),
gfm: false,
tables: false,
breaks: false,
pedantic: false,
sanitize: true,
smartLists: true,
smartypants: false
});
$('.output').on('click', function() {
var inputVal = $('.textarea').val();
var decode = marked(inputVal);
console.log(decode);
});
html
<textarea class="textarea"></textarea>
<div class="output">output</div>
<div class="preview"></div>
UPDATE
I tried below two way, both not work with strong ...
// lexer.rules.strong = { exec: function() {} };
lexer.rules.strong = /(a^) (a^) (a^)/;
resource https://github.com/chjj/marked/issues/420
// d\ne\n\nf\n**c**
var lexer = new marked.Lexer();
lexer.rules.heading = /(a^) (a^) (a^)/;
lexer.rules.strong = /(a^) (a^) (a^)/; // not work
lexer.rules.em = /(a^) (a^) (a^)/;
lexer.rules.code = /(a^) (a^) (a^)/;
var b = marked.parser(lexer.lex(d));
console.log(b);
>>
<p>d
e</p>
<p>f
<strong>c</strong></p>
found this in marked.js,
var inline = {
escape: /^\\([\\`*{}\[\]()#+\-.!_>])/,
autolink: /^<([^ >]+(#|:\/)[^ >]+)>/,
url: noop,
tag: /^<!--[\s\S]*?-->|^<\/?\w+(?:"[^"]*"|'[^']*'|[^'">])*?>/,
link: /^!?\[(inside)\]\(href\)/,
reflink: /^!?\[(inside)\]\s*\[([^\]]*)\]/,
nolink: /^!?\[((?:\[[^\]]*\]|[^\[\]])*)\]/,
strong: /^__([\s\S]+?)__(?!_)|^\*\*([\s\S]+?)\*\*(?!\*)/,
em: /^\b_((?:[^_]|__)+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,
code: /^(`+)\s*([\s\S]*?[^`])\s*\1(?!`)/,
br: /^ {2,}\n(?!\s*$)/,
del: noop,
text: /^[\s\S]+?(?=[\\<!\[_*`]| {2,}\n|$)/
};
but marked.InlineLexer.rules.strong = /(a^) (a^) (a^)/; or above way lexer.rules.strong both still not work ...

jPlayer playing two media files

I am attempting to piece together a jPlayer example that plays two audio files, one right after another.
I need to have full event control, so i decided not to use the playlist option, unless somebody can give me an example of having a way of controlling when the events fire, something like:
first media 'before' function
first media 'after' function
second media 'before' function
second media 'after' function
My example below is using a global variable in the "ended:" function and seems pretty clumsy.
Does anybody have a better suggestion how i might accomplish this? here is my working example of using the global variable:
$(document).ready(function(){
$("#jquery_jplayer_1").jPlayer({
ready: function (event) {
console.log('ready function.');
},
ended: function() {
console.log('ending function starting.');
var player = $("#jquery_jplayer_1");
player.jPlayer("stop");
player.jPlayer("clearMedia");
player.jPlayer("setMedia", {
wav: globalParmTwo
});
player.jPlayer("play", 0);
globalParmTwo = null;
},
loop: false, // added to remove the if condition
supplied: "wav, oga",
wmode: "window",
useStateClassSkin: true,
autoBlur: false,
smoothPlayBar: true,
keyEnabled: true,
remainingDuration: true,
toggleDuration: true
});
});
var globalParmTwo = null;
function komPare(parmOne, parmTwo) {
globalParmTwo = parmTwo;
var player = $("#jquery_jplayer_1");
player.jPlayer("stop");
player.jPlayer("clearMedia");
player.jPlayer("setMedia", {
wav: parmOne
});
player.jPlayer("play", 0);
}
And here my working example using the playlist, which seems like a better solution, assuming there is some way to fire specific functions at specific times:
var myPlaylist = null;
$(document).ready(function(){
myPlaylist = new jPlayerPlaylist({
jPlayer: "#jquery_jplayer_N",
cssSelectorAncestor: "#jp_container_N"
}, []
, {
playlistOptions: {
enableRemoveControls: true
},
supplied: "wav, ogv",
useStateClassSkin: true,
autoBlur: false,
smoothPlayBar: true,
keyEnabled: true,
audioFullScreen: false
});
$('.jp-playlist').hide();
myPlaylist.option("autoPlay", true);
});
function komPare(firstMediaUrl, secondMediaUrl) {
myPlaylist.setPlaylist([
{ wav: firstMediaUrl },
{ wav: secondMediaUrl }
]);
};
any suggestions are very appreciated.
UPDATE: i removed an if-condition and put in "loop: false," instead in the first example.
We can bind events to the playlist player, and then use a global media counter. This still uses global variables, but the code is cleaner.
as always, any suggestions are most appreciated.
var myPlaylist = null;
var mediaCounter = null;
$(document).ready(function(){
myPlaylist = new jPlayerPlaylist({
jPlayer: "#jquery_jplayer_1"
}, [] // empty initial playlist
, {
playlistOptions: {
enableRemoveControls: true
},
supplied: "ogv",
useStateClassSkin: true,
autoBlur: false,
smoothPlayBar: true,
keyEnabled: true,
audioFullScreen: false
});
$('#jquery_jplayer_1').bind($.jPlayer.event.ready,
function(event) {
console.log('ready.');
}
);
$('#jquery_jplayer_1').bind($.jPlayer.event.loadeddata,
function(event) {
console.log('loadeddata ' + mediaCounter++ );
}
);
$('#jquery_jplayer_1').hide();
$('.jp-playlist').hide();
$('.jp-controls').hide();
myPlaylist.option("autoPlay", true);
});
function komPare() {
var playlist = [];
for ( urlName of arguments ) {
playlist.push( { ogv: urlName } );
};
mediaCounter = 0;
myPlaylist.setPlaylist(playlist);
};

Categories