Action Script 3. How to access button from Movie Clip in Flash? - javascript

I have MyMovieClip named mClip. Inside mClip are 2 buttons named: btn1 btn2
I need access these buttons in my Action Script code. I have declared It:
var mClip:MyMovieClip = new MyMovieClip();
var btn1:MyButton1 = new MyButton1();
var btn2:MyButton2 = new MyButton2();
I have tried in 2 ways, but both unsuccessfully:
1.
mClip.btn1.addEventListener(MouseEvent.CLICK, popUp1);
mClip.btn2.addEventListener(MouseEvent.CLICK, popUp2);
function popUp1(event:MouseEvent):void {
trace("test 1");
}
function popUp2(event:MouseEvent):void {
trace("test 2");
}
2.
btn1.addEventListener(MouseEvent.CLICK, popUp1); //removed mClip
btn2.addEventListener(MouseEvent.CLICK, popUp2); //removed mClip
function popUp1(event:MouseEvent):void {
trace("test 1");
}
function popUp2(event:MouseEvent):void {
trace("test 2");
}
I don't get any errors, just nothing happens after buttons is clicked. Could you help me, please? Thank you

Here is what is likely going on. Though I have to make the following assumptions:
You are using flash pro
In flash pro, you've created a movie clip, placed it on the main timeline, and given it the instance name of mClip
On the mClip timeline, you've created two buttons and given them the instance names of btn1 and btn2.
All your code is on the main timeline.
When you do the following:
var mClip:MyMovieClip = new MyMovieClip();
var btn1:MyButton1 = new MyButton1();
var btn2:MyButton2 = new MyButton2();
You are actually telling flash to take those names (mClip, btn1,btn2) and assign NEW objects to them (the old ones still exists, but the vars refer to the new objects you've just created - so your adding click events to objects that aren't on screen).
When you add a movie clip to the timeline and give it an instance name, behind the scenes it's effectively done the same as that code. Remove those three lines, and your code from your first try will work. (assuming all my assumptions above are correct, please advise if not)

The first try would be correct if the class is marked as dynamic. But as this is not your case, you should either use the variable directly:
btn1.addEventListener(..
IF this is used exactly in the same class that you define them (and add them in the mClip). What actually happens is that you work with the variable, rather than the instance name. You might have problem because you are not working where you define those buttons.
If that still doesn't work, you are probably clicking on something above that child.

It's not entirely clear from your diagram, but the buttons should have colored (not empty) fields (although the alpha can be anything, including 'zero') -- so that you're actually clicking on something. And, if the 'buttons' are just MovieClips coded as buttons, the labels should be static text and non-selectable.
We're assuming that your code is timeline code, NOT part of coded classes.

Related

Reset or Clear before appending an element in javascript

It's my first app, I have been in tutorial hell for one year and decided to start my own little app.
So in this part Im using an addEventListener(),which appends and create text. The text is a variable created by the sum of the results of other functions (I don't know if this is relevant), but the thing is once I submit a button and creates the HTML element, if I keep submitting the elements will pile up. So I tried removeChild() but it didn't work because the variable was already created with its value, or...brought an error that can't removedChild() of undefined (since I tried to clear the values before appending), also tried to reseting the variable by adding a .innerHTML=""; but I don't know where to locate it. I also checked the replaceChild() but it didn't make sense, since everytime you click should be a new first event created. I tried the empty().append() but seems it's for jquery.
Seems that I need to learn a lot about scopes.
let frase;
function armarPersonaje() {
if(!reversarNombre() || !descMes || !descDia){
return false
} else {
frase = nombreReves + descMes + descDia;
return true
}
}
let div;
let h3Element;
function mostrarPersonaje(){
let div = document.getElementById('container')
let h3Element = document.createElement("h3")
h3Element.className = "addedH3"
if(frase.length > 0){
h3Element.appendChild(document.createTextNode(frase));
div.appendChild(h3Element)
}
}
enter image description here
Here's the complete code
https://jsfiddle.net/santiso/mzv3ct5e/
The problem here that in your last function mostrarPersonaje() you are always creating the element h3Element before the if , and even if you empty the parent node which is the div it will create a new element whit class addedH3 the very next click !
How to fix it ? first do not create until you enter the condition , then delete it when ever you click again even before the condition
here is the fiddle
and this is what i added
let oldH3Element = document.querySelector('h3.addedH3')
if(oldH3Element) oldH3Element.parentNode.removeChild(oldH3Element)

array of objects for an html5 canvas nav bar

I have a html5 Canvas animation that I am doing on Adobe Animate and tweaking with some code.
I have a portion on the animation that will be like a combobox with all the links to navigate through the different frames. The thing is, I don't want to be creating a bunch of EventListener to many buttons because from experience I know that doesn't work so well. So I am trying to think of a more creative solution. This is my idea.
Create an array that will contain all the buttons.
Assing a variable for each target frame.
Create a for loop with a function inside that assigns the listener to the selected button and then points it to the desired frame (variable)
This is what I have got so far, (not much)
var combobox = [this.btncasco , this.btnbanyera , this.btnLumbrera , this.btnproapopa, this.btnestriborbabor ];
for (var i=0; i<combobox.length; i++) {
var clipcasco = gotoAndStop(0);
var clipbanyera = gotoAndStop(2);
var cliplumbera = gotoAndStop(4);
var clipproapoa = gotoAndStop(6);
var clipestriborbabor = gotoAndStop(8);
}
Would that be feasible ?
In your example, you are just assigning the result of gotoAndStop (with no scope, so likely you're getting an error in the console)
I think you are looking for something like this:
for (var i=0; i<combobox.length; i++) {
// This is kind of complex, but if you just reference "i" in your callback
// It will always be combobox.length, since it references the value of i
// after the for loop completes variable.
// So just store a new reference on your button to make it easy
combobox[i].index = i*2; // x2 lines up with your code 0,2,4,etc.
// Add a listener to the button
combobox[i].on("click", function(event) {
// Use event.target instead of combobox[i] for the same reason as above.
event.target.gotoAndStop(event.target.index);
}
}
You might have the same problem as your other StackOverflow post where the button is undefined (check the console). There is actually a bug in Animate export right now where children of a clip are not immediately available. To get around this, you can call this.gotoAndStop(0); at the start to force it to update the children.

javascript how to insert new elements at different locations in page

I'm writing a chrome extension that will add helper text instructions/reminders to specific location in the "new order" form we use at work. I'm really new to coding (basically using this project as a way to learn). I've created something that works - but I'm convinced there's a more elegant solution that I just haven't been able to figure out.
var helpText = "this is the message"
var customAlert = makeAlert(helpText) //create html container for msg
function makerAlert(helpText){...} //createElem, add class/style, append children
I'm okay with that bit (above). But should i be storing information on each message in objects instead? why would/wouldn't i? what information would go in it?
function alertPlacer(customAlert){
var par = document.getElementsByClassName("class-name")[i];
var sib = par.childNodes[j];
par.insertBefore(customAlert, sib);
};
really struggling with this bit (above). I have actually made alertPlacer() functions for each message because i can't figure out how to create a function that will take different class name & index parameters. should i be breaking this up more? if i stored these bits of info in an object, would that be useful?
relevant info:
because the target locations are within a form, almost nothing has an "id" attribute. so i have to use getElementsByClassName & an index.
for each message, I know the target parent className & index and the child node index to "insert before".
i would like to stick with javascript-only solution.
functions can take multiple arguments:
function alertPlacer(customAlert,className,parIndex,childIndex){
var par = document.getElementsByClassName(className)[parIndex]; var sib = par.childNodes[childIndex];
par.insertBefore(customAlert, sib);
};
And you call your function like
alertPlacer(yourAlert,"class-name",6,9);

Store a changing jQuery variable to session or local storage

I currently have the following jQuery code working. Here's what it does: when I click a button, it will swap between classes. Each of those classes contains a background image. So, as I click this single button, it cycles through the background images. (edit: I just need to store whatever the current variable is, so when they swap pages, that variable is what's loaded).
$('.button').mousedown(function () {
$('#backgrounds').each(function(){
var classes = ['bg1','bg2','bg3','bg4'];
this.className = classes[($.inArray(this.className, classes)+1)%classes.length];
});
});
However, my website has multiple pages. So, what I need to do is store the current variable to the session storage or local storage, and then retrieve that variable on page load. That way as I jump from one page to another, the same class (and therefore background image) will be displayed. I don't need to (nor want to) use cookies -- I just need this to last the current session.
Additionally, if possible (though much less important than storing the variable), I'd also like this jQuery function to neatly fade when swapping from one background image to another. Right now it "snaps" from one image to the next as it swaps out the classes.
Thanks in advance -- any help greatly appreciated!
Use the Window.sessionStorage API for a single session.
Just set by getting the value from the sessionStorage if applicable (if not, set a default value):
var classes = sessionStorage.getItem(classes) || ['bg1','bg2','bg3','bg4'];
and set it when you need to:
sessionStorage.setItem("classes", classes);
The selector #backgrounds should only match one element. So it is unnecessary to use each:
// Define classes & background element.
var classes = ['bg1','bg2','bg3','bg4'],
$bg = document.getElementById('backgrounds');
// On first run:
$bg.className = sessionStorage.getItem('currentClass') || classes[0];
// On button click:
$('.button').mousedown(function () {
// (1) Get current class of background element,
// find its index in "classes" Array.
var currentClassIndex = classes.indexOf($bg.className);
// (2) Get new class from list.
var nextClass = classes[(currentClassIndex + 1)%classes.length];
// (3) Assign new class to background element.
$bg.className = nextClass;
// (4) Save new class in sessionStorage.
sessionStorage.setItem('currentClass', nextClass);
});
In this demo I've used getElementById to select the #backgrounds DOM element, rather than selecting it using jQuery. This is because jQuery element representations don't actually have a className property, and the ordinary JavaScript API is simpler in this case.

How to condense similar duplicate jquery functions

Well if my maths is right, my Jquery file is 16 times bigger than it could be.
I am building a tabbed category page which looks like this..
Tab1
cat1
cat2
etc
Tab2
cat1
cat2
etc
All content starts of hidden and then appears when a button in the category header is clicked (also toggling an arrow up/down).
$("#tabName_contentLink_cat1").click(function(){
$("#tabName_contentLink_cat1 > .arrow").toggleClass('greyArrow_down')
.toggleClass('blackArrow_up');
$("#tabName_content_cat1").slideToggle("fast");
});
This code works fine but I've repeated it 16 times!
The only part that varies is the number at the end of '_cat1'.
How can I convert this one piece of code, so that it can be reused 16 times?
I am a newbie, so please keep that in mind.
In my mind; assigning some sought of unique identifier (applicable category number), collecting it in a jQuery variable onClick and then pasted at the end of each _cat'HERE' seams like the way forward. I haven't a clue on how to carry it out though.
Thanks
you could add another class to all cat elements and then use it as selector or you can do what i did. Notice i made the code smaller, efficient. And it does what you wanted by using Function.
addClick(cat1);
addClick(cat2);
addClick(cat3);
addClick(cat4);
function addClick(x) {
$("#tabName_contentLink_"+x).click(function(){
$(this).slideToggle("fast").children(".arrow")
.toggleClass('greyArrow_down blackArrow_up');
});}
What about
$("[id^='tabName_contentLink_cat']").click(function(){
$(this).children(".arrow").toggleClass('greyArrow_down')
.toggleClass('blackArrow_up');
var contentId = this.id.replace(/contentLink/, 'content');
$("#"+ contentId).slideToggle("fast");
});
It's not the most elegant code, but it should work.
Why don't you use a simple for loop?
for(var i = 1; i <= 16; i++){
$("#tabName_contentLink_cat" + i).click(function(){
$("#tabName_contentLink_cat" + i + " > .arrow").toggleClass('greyArrow_down')
.toggleClass('blackArrow_up');
$("#tabName_content_cat" + 1).slideToggle("fast");
});
}
There are other options, but this seems to be the quickest way to make it work without changing too much of the existing code. To make it more generic you can wrap it in a function that receives 'i' as an argument.
Give them all the tabName_contentLink class, then:
$(".tabName_contentLink").click(function(){
$(this).children(".arrow").toggleClass('greyArrow_down')
.toggleClass('blackArrow_up');
$(this).find(".tabName_content").slideToggle("fast");
});
The keyword this allows you to reference the object calling the function, thus relate to a specific object out of a set. It can become a little tricky, but basically - you can use it as described above.

Categories