Chaining events in mootools on toggle() - mootools

I have a toggle event on specific div witch works fine ,
here is the demo
http://jsfiddle.net/b5SVg/9/
the trouble is that I have the outside container that I need to hide on load and show/hide on toggle. CUrrently my container display block fires first and I need it to be sinced wht the toggle. I know you might think that i should put the container inside the toggle but i cant since the FX.slide adds div around toggle element which is overflow hidden and has position . my container must stay where it is. Please advise

Read the comments on the code below ;)
var container = $$('.container').setStyle('display','none'); //cache container (useful for the 'future' ;) )"
var mySlide= new Fx.Slide('hidden').hide();
$('toggle').addEvent('click', function(event){
event.stop();
container.setStyle('display','block'); //put it before the toggle
mySlide.toggle().chain(function(){ //at the end of the sliding, this callback will be called
if(!this.open){ //if it's closed
container.setStyle('display', 'none'); //hide the container
}
});
});
Demo: http://jsfiddle.net/amgyw/1/
..btw you also can use the element proper instance of 'slide', without declaring var mySlide = ... ..like i.e. $('hidden').get('slide').toggle()

Related

<a> link to nearest object of a defined class

So I would like to have a link that would point to the nearest element with the class ".example" on their screen. I know you can have links pointing to unique IDs on the page setting the href to #uniqueID I just want to know if that is possible with classes
You'd need to use JavaScript for this. Assuming that by 'nearest element... on their screen' you mean the element with the smallest vertical distance to the clicked link.
A quick way to do this would be looping through each element with the class example, finding the one with the smallest distance, and scrolling it into view:
<script>
function toNearestExample(clicked_element) {
// first we get all elements of 'example' class
var examples = document.getElementsByClassName("example");
// now we find the index of the element nearest to the clicked element
// to do this we go through each element in this list, and find the closest vertical distance from the clicked element
var smallest = Math.abs(clicked_element.getBoundingClientRect().top - examples[0].getBoundingClientRect().top);
var indexOfSmallest = 0;
for(var i=1;i<examples.length;i++) { // for each element with class 'example'
// calculate vertical distance
var verticalDistance = Math.abs(clicked_element.getBoundingClientRect().top - examples[i].getBoundingClientRect().top);
if (verticalDistance < smallest) {
smallest = verticalDistance;
indexOfSmallest = i;
}
}
// once we have that, we can scroll it into view
examples[indexOfSmallest].scrollIntoView();
}
</script>
Now all we have to do is call this function when your element is clicked, making sure to pass the element that clicked it:
<a onclick="toNearestExample(this);">click me!</a>
Of course, you could easily modify the code for elements with distances other than vertical.
An issue with this method is that it will get slow as you add more and more example elements onto the page. Unless your <a> tag will be moving around the page, it would be better to just hardcode this in for performance or to prevent issues with different window sizes.

How to trigger mouse-click event on multiple HTML elements covering each other?

How to trigger multiple mouse-click events on arbitrarily many HTML elements covering each other?
I know you can use pointer-events: none; to let your click pass through your elements, but what if I want to trigger the mouse-click event on an element AND the mouse-click event on arbitrarily many other elements beneath it?
but what if I want to trigger the mouse-click event on an element AND the mouse-click event on arbitrarily many other elements beneath it?
Events bubble. Which means and event fired on an inner element, will also be received by the parent elements until the top most parent.
<div id="topmost">
<div id="second">
<p id="firstp"></p>
</div>
</div>
Assume you are using jquery. Below is how you would listen to click events from all elements below div.id="topmost".
Since the normal flow of events is for any click event (could be any other type of event) that is fired by any element with in the topmost div element will be bubbled to the outermost element, I only list to topmost click event and then check which element fired that event by checking the id of the target element. e.target will be the actual element that the click was performed on. You can either switch target.attr('id') or run it through if else conditions.
$(function () {
$("#topmost").on("click", function (e) {
e.preventDefault();
var target = $(e.target);
if(target.attr('id') === "idOfElement"){
// code to handle the event
}else{
});
A solution could be to track mouse move using :
$( document ).mousemove();
Store coordinates to a global variable then check its position when your element is clicked. That would give something like :
var mousePos = [0,0];
$( document ).mousemove(function( event ) {
mousePos[0] = event.pageX
mousePos[1] = event.pageY
});
$("#target").click(function(){
// Compare mouse coordinates and your items ones using offset, height and width
if(mousePos[0] > $('#target2').offset.left){
// Do whatever you are willing to do
}
});

Jquery elements follow each other

I have been working on this. Obviously, it uses key binding to animate and shoot bullets. Unfortunately, if you move up or down and a bullet is on its way to the target, and you move up or down, the bullet moves with you. Same situation with the target. So I looked at css positioning, and I think that the problem could be that somehow the created bullet is appended to the player. I have tried to change the positioning on both of them, and changing the bullet creater code to append to body. To no avail.
Here is my link:http://jsfiddle.net/5khhmepv/9/
And here is the creator code that I think is the problem:
var shoot = function () {
if (canshoot === true) {
canshoot = false;
bullety = 0;
var div = $('<div class=' + 'bullet' + ' style=' + 'marginTop:-25;' + '>yt</div>');
div.appendTo('html');
div.animate({
marginLeft: 500 + 'px'
}, 1500);
canshoot = false;
setTimeout(function () {
$(".bullet").hide();
canshoot = true;
}, 1500);
}
};
By setting the position of your #player element to static, you make the size of the document dependent on how far down the document your player is. Moving your player up and down then causes the bullet to shift based on its relationship to the document height. What you probably want to do is have a fixed-size canvas, and absolutely positioned #player and .bullet. Don't forget to initialize the bullet's top to be aligned with the player's current scrollOffset.
I made some quick adjustments to your fiddle and i think it's working as intended.
http://jsfiddle.net/5khhmepv/28/
Basically you shouldn't use static as position value as Palpatim explained.

How can I fix this element to stick at the top of the page on scroll?

I'm working on a project for my UI design class and need help fixing an element to the top of a page on scroll.
Here's what I have so far: http://ieatthings.com/opinio/query.html
As you scroll, the search bar should move up, over the navbar, and fit nicely into place to let the user search while in the middle of a page. But the problem is that the search bar keeps going up!
I used the Javascript from this tutorial: Fix object to top of browser window when scrolling. I have tried all kinds of possibilities and combinations, but have unfortunately not gotten this damn thing to work.
Any suggestions?
You will have to use Javascript to test the position of your element ("myElement") on the page compared to how far the page has been scrolled. If the page has been scrolled up beyond your element then you alter your element's css to snap it to the top of the page. Note: mobile browsers don't like the "position: fixed;" style property.
Give your element the id of "myElement" and insert this into your tag.
<script type="text/javascript">
var yPosition; // save original y position of element here
window.onload = function(){ // once entire page is loaded this function is fired
// save original y position of element before it is scrolled
yPosition = document.getElementById("myElement").offsetTop;
}
window.onscroll = function(){ // scrolling fires this function
var myElement = document.getElementById("myElement"); // for cleaner code
// compare original y position of element to y position of page
if( yPosition <= window.pageYOffset ){
// snap element to the top by changing css values of element
myElement.style.position = "fixed";
myElement.style.top = "0px";
}else{
// re-position to original flow of content
myElement.style.position = "relative";
myElement.style.top = ""; // set to default
}
}
</script>
Hopefully this helps!

Is there a way to keep an object always at the top of the display list?

Is there a way to make a display object always be at the top of the display list?
For example, I know you can set the childIndex, i.e:
setChildIndex(myDisplayObject, numChildren-1);
But is there a way that an object has sensed that something else has been added to the display list and restack themselves accordingly?
You can listen to the Event.ADDED event on the container. This event will bubble up, so you'll get called whenever a display object is added to the container or any of its children.
Here's an example of how you could do this. You'll see the black box always stays on top.
var container:DisplayObjectContainer = this; // this is a frame script but just change this line as necessary
container.addEventListener(Event.ADDED,handleAdded,true);
function handleAdded(e:Event):void {
// this if tries to cover some edge cases, unlikely to happen in your code, from your description
if(container == topElement.parent && container.numChildren > 0 && container.getChildIndex(topElement) != container.numChildren - 1) {
container.setChildIndex(topElement,numChildren - 1);
}
}
function getSprite(c:uint):Sprite {
var sp:Sprite = new Sprite();
sp.graphics.beginFill(c);
sp.graphics.drawRect(0,0,100,100);
sp.graphics.endFill();
return sp;
}
var topElement:Sprite = getSprite(0);
container.addChild(topElement);
var sp:Sprite = getSprite(0xff0000);
container.addChild(sp);
sp.addChild(getSprite(0xff00));
var sp2:Sprite = getSprite(0xff);
container.addChild(sp2);
However, I think it's much simpler and cleaner just to have 2 containers, say, top and bottom, kind of like layers. In top you'd add the element that always must be on top (or this could be your element as you probably don't need to have this extra container). In bottom you'd add and remove whatever you want. Then you can forget about manually restacking stuff (at least to keep the top element atop).
You can override the addChild() method in the parent object. In that method you can move your child to the top using
setChildIndex(myDisplayObject, numChildren-1);
In this way everytime an object is added to the parent, the parent moves your object to the top.