I have a layout which I dont think its necessary to post here. But its basically a parent div with a very small width and height that stays on bottom right of a page, if clicked on it, it enlarges width and height.
Here where I had issue:
The parent contains onclick, if its click, it then change its size as well as disabling its onclick and adding onclick to an image, which is a button to minimise the parent div to its original size.
If the image is clicked then again, I disable the onclick on the image and add onclick on the main parent. However Javascript is executing onclick on the parent as it thinks its been clicked, since the image is inside the parent.
To fix this issue I had to set a setTimeout to add the onclick to the parent, that solved the issue, but is there a better way, and why does that happen?
Tahnks
function adjust_window_displayed(el, main_el){
var val = el.value;
var img_el = document.getElementById("img_envelope");
if(val === "true"){
document.getElementById("display_mail_info").style.display = "block";
img_el.src = "https://co.uk/minimise.png";
img_el.style.cursor = "pointer";
main_el.style.cursor = "default";
main_el.onclick = function () {
return false;
};
el.value = "false";
img_el.onclick = function () {
adjust_window_displayed(el, main_el);
console.log("first");
};
console.log("first " + main_el.className);
}else{
document.getElementById("display_mail_info").style.display = "none";
img_el.src = "https://dco.uk/envelope.png";
img_el.style.cursor = "default";
main_el.style.cursor = "pointer";
el.value = "true";
img_el.onclick = function () {
return false;
};
setTimeout(function() {
main_el.onclick = function () {
adjust_window_displayed(el, main_el);
console.log("sec");
};
}, 700);
console.log("second " + main_el.className);
}
}
What happens is due to the event bubble, when you click on the <img> the click event fire once, then a second time for the parent, now if you don't handle that in your function properly it'll give you problems.
Now I have no idea how you're calling that function nor what parameters, you're passing to it, so i tried to reproduce the problem myself.
If you would assign the click event useing the .onclick = function(){}
you can use it to alter between the two, since you're using the same function.
document.querySelector('#parent').onclick = lol;
function lol(e){
var type = e.target.nodeName;
if (type == "DIV")
{
if (e.target.onclick)
{
alert('clicked parent');
e.target.onclick = "";
document.querySelector('#kid').onclick = lol;
}
}
else if (type == "IMG")
{
if (e.target.onclick)
{
alert('clicked kid');
e.target.onclick = "";
document.querySelector('#parent').onclick = lol;
}
}
}
#parent{
width: 500px;
height: 500px;
background-color: red;
}
img{
width: 10%;
height: 10%;
}
<div id="parent">
<img id="kid">
</div>
Related
How can I make a HTML button act like a toggle? I have two JS functions that modify an image, one to a new image and the other to change it back. How can I make sure a button activates the first function when pressed the first time but then activates the second when pressed again, repeated for the third and fourth time etc.
document.getElementById("baseImg").src = "assets/1stImg.png";
function imgChange1() {
document.getElementById("baseImg").src = "assets/2ndImg.png";
}
function imgBack1() {
document.getElementById("baseImg").src = "assets/1stImg.png";
}
<img id="baseImg">
<button onclick="imgChange1()">Change</button>
How would I go about including the second function within this button?
`
I don't really get your question because you were saying "toggle" but you were saying
How can I make sure a button activates the first function when pressed
the first time but then activates the second when pressed again?
But well, here's how you do it:
var clicked = false;
function toggleBtnClick(button) {
var img = document.getElementById('baseImg');
if (clicked) { //this will be executed on future clicks after first click
img.src = 'http://via.placeholder.com/350x150/4CAF50/000000';
console.log('Next click');
//or do something else
} else { //this will only be executed once
img.src = 'http://via.placeholder.com/350x150/e9e9e9/000000';
console.log('First click');
}
clicked = true; //update to true after first click
}
button {
position: absolute;
right: 0;
}
<img id="baseImg" src="http://via.placeholder.com/350x150/3fafed/000000">
<button onclick="toggleBtnClick()">Change</button>
But, if you really want a "toggle" functionality, here's how you do it:
var clicked = false;
function toggleBtnClick() {
var img = document.getElementById('baseImg');
if (clicked) {
img.src = 'http://via.placeholder.com/350x150/e9e9e9/000000';
clicked = false;
} else {
img.src = 'http://via.placeholder.com/350x150/3fafed/000000';
clicked = true;
}
}
button {
position: absolute;
right: 0
}
<img id="baseImg" src="http://via.placeholder.com/350x150/e9e9e9/000000">
<button onclick="toggleBtnClick()">Change</button>
I'm trying this and my background changes color (what I want) but the src of the input only changes on the second time I click it. how can I make it change the source on the first click? Also how can I change the src back to the original with a second click?
<input id="showHideContainer" type="image" src="on.png " height="3%" width="2%" alt="On" onclick="toggle();">
<script>
document.getElementById('showHideContainer').onclick = function () {
divTest = document.getElementById('header');
if (divTest.style.display === "none") {
divTest.style.display = 'block';
} else {
divTest.style.display = "none";
};
$('body').toggleClass('style2');
$('#showHideContainer').click(function(){
$('#showHideContainer').attr('src', 'off.png');
});
}
</script>
You need to determine the current state of the obj then toggle it with the other
$('#showHideContainer').click(function(){
var off = $(this).attr('src').indexOf('off.png')>-1;
$(this).attr('src', (off?'on.png':'off.png'));
});
Quick fix. You are now attaching anoter eventhandler on the first click on the #showHideContainer, that is why it's not firing the first time. This trimmed version of your code should get you the expected result, also see the other answer to look at the state of your element attribute:
document.getElementById('showHideContainer').onclick = function () {
divTest = document.getElementById('header');
if (divTest.style.display === "none") {
divTest.style.display = 'block';
} else {
divTest.style.display = "none";
};
$('body').toggleClass('style2');
var off = $(this).attr('src').indexOf('off.png')>-1;
$(this).attr('src', (off?'on.png':'off.png'));
}
I asked this question yesterday hopefully this one is clearer as I've now provided a working example of my store.
I'm developing a Shopify Theme. I've been using Timber as my base and I'm currently having a problem with my Quick Cart and Quick Shop/View drawers.
I have 2 drawers on the right of my site, 1 for the cart and 1 for the product quick view option. The drawers currently slide open - #PageContainer moves to the left on click to reveal each drawer.
As they are currently sitting on top of each other I need to alter the JS so that on click the z-index changes so that the correct drawer being called is highest in the stack.
I'm not great with JS so not sure if this is a simple task?
Here is a link to my Dev Store
JS:
timber.Drawers = (function () {
var Drawer = function (id, position, options) {
var defaults = {
close: '.js-drawer-close',
open: '.js-drawer-open-' + position,
openClass: 'js-drawer-open',
dirOpenClass: 'js-drawer-open-' + position
};
this.$nodes = {
parent: $('body, html'),
page: $('#PageContainer'),
moved: $('.is-moved-by-drawer')
};
this.config = $.extend(defaults, options);
this.position = position;
this.$drawer = $('#' + id);
if (!this.$drawer.length) {
return false;
}
this.drawerIsOpen = false;
this.init();
};
Drawer.prototype.init = function () {
$(this.config.open).on('click', $.proxy(this.open, this));
this.$drawer.find(this.config.close).on('click', $.proxy(this.close, this));
};
Drawer.prototype.open = function (evt) {
// Keep track if drawer was opened from a click, or called by another function
var externalCall = false;
// Prevent following href if link is clicked
if (evt) {
evt.preventDefault();
} else {
externalCall = true;
}
// Without this, the drawer opens, the click event bubbles up to $nodes.page
// which closes the drawer.
if (evt && evt.stopPropagation) {
evt.stopPropagation();
// save the source of the click, we'll focus to this on close
this.$activeSource = $(evt.currentTarget);
}
if (this.drawerIsOpen && !externalCall) {
return this.close();
}
// Add is-transitioning class to moved elements on open so drawer can have
// transition for close animation
this.$nodes.moved.addClass('is-transitioning');
this.$drawer.prepareTransition();
this.$nodes.parent.addClass(this.config.openClass + ' ' + this.config.dirOpenClass);
this.drawerIsOpen = true;
// Run function when draw opens if set
if (this.config.onDrawerOpen && typeof(this.config.onDrawerOpen) == 'function') {
if (!externalCall) {
this.config.onDrawerOpen();
}
}
if (this.$activeSource && this.$activeSource.attr('aria-expanded')) {
this.$activeSource.attr('aria-expanded', 'true');
}
// Lock scrolling on mobile
this.$nodes.page.on('touchmove.drawer', function () {
return false;
});
this.$nodes.page.on('click.drawer', $.proxy(function () {
this.close();
return false;
}, this));
};
Drawer.prototype.close = function () {
if (!this.drawerIsOpen) { // don't close a closed drawer
return;
}
// deselect any focused form elements
$(document.activeElement).trigger('blur');
// Ensure closing transition is applied to moved elements, like the nav
this.$nodes.moved.prepareTransition({ disableExisting: true });
this.$drawer.prepareTransition({ disableExisting: true });
this.$nodes.parent.removeClass(this.config.dirOpenClass + ' ' + this.config.openClass);
this.drawerIsOpen = false;
this.$nodes.page.off('.drawer');
};
return Drawer;
})();
Update
As instructed by Ciprian I have placed the following in my JS which is making the #CartDrawer have a higher z-index. I'm now unsure how I adapt this so that it knows which one to have higher dependant on which button is clicked. This is what I've tried:
...
Drawer.prototype.init = function () {
$(this.config.open).on('click', $.proxy(this.open, this));
$('.js-drawer-open-right-two').click(function(){
$(this).data('clicked', true);
});
if($('.js-drawer-open-right-two').data('clicked')) {
//clicked element, do-some-stuff
$('#QuickShopDrawer').css('z-index', '999');
} else {
//run function 2
$('#CartDrawer').css('z-index', '999');
}
this.$drawer.find(this.config.close).on('click', $.proxy(this.close, this));
};
...
The approach would be like this:
$('.yourselector').css('z-index', '999');
Add it (and adapt it to your needs) inside your onclick() function.
if you need to modify the z-index of your div when clicking a buton, you shoud put in this code on your onclick() function, else if you need to activate it when you looding the page you shoud put it on a $( document ).ready() function , the code is :
$('#yourID').css('z-index', '10');
You can use:
document.getElementById("your-element-id").style.zIndex = 5;
It's pure Javascript and sets the z-index to 5. Just bind this to onClick event!
My intention is to make it so that the img will be visible only when I enter the mouse inside the boundaries of the input. The problem I have seen is that the code works differently in chrome (ver 39) than in firefox (ver 35).
In firefox and IE, it works as intended, but in chrome it only triggers the functions when I click inside or outside the boundaries. I tried using other events like onmouseenter, onmousemove or onmouseleave, but they seem to have the same results.
Is there some problem with my code?
I have the following code:
<html>
<body>
<form><table><tr><td><input name="var1" id="var1"></td><td><img name="var1_img" id="var1_img" src="nostar.png" style="display:inline-block; position:relative; left:-20px" onclick="callClickEvent(this)"></td></tr></table></form>
<script>
var statusImg = 0;
function obtenerObj(idName) {
var obj = null;
if (document.getElementsByName && document.getElementsByName(idName)[0]) obj = document.getElementsByName(idName)[0];
else if (document.getElementById && document.getElementById(idName)) obj = document.getElementById(idName);
return obj;
}
function makeVisible(idName) {
console.log("Visible "+idName);
var obj = obtenerObj(idName+"_img");
if (obj) obj.style.display = "inline-block";
}
function makeInvisible(idName) {
console.log("Invisible "+idName);
var obj = obtenerObj(idName+"_img");
if (obj) obj.style.display = "none";
}
function callClickEvent(obj) {
if (obj) {
if (statusImg == 0) {
obj.src = "star.png";
statusImg = 1;
} else {
obj.src = "nostar.png";
statusImg = 0;
}
}
}
var obj = obtenerObj("var1");
if (obj) {
obj.onfocus = function() { makeVisible("var1"); };
obj.onmouseover = function() { makeVisible("var1"); };
obj.onmouseout = function() { makeInvisible("var1"); };
obj.onblur = function() { makeInvisible("var1"); };
}
</script>
</body>
</html>
If you want to trigger the event when you're hover the input, you need only onmouseover and onmouseout events.
I think that your problem is caused by the height of the td.
When you show the image the td become bigger and move down, to prevent this problem you could declare the height of the td with the same height of the image.
<td style="height:150px;"><input name="var1" id="var1"></td><td><img name="var1_img" id="var1_img" src="http://placehold.it/350x150" style="display:inline-block; position:relative; left:-20px" onclick="callClickEvent(this)"/></td>
Try this working example.
I have a div that I'm appending to another div when a button is clicked. I'm also calling a bunch of functions on the div that gets created.
HTML
<a onClick="drawRect();">Rect</a>
JS
function drawRect(){
var elemRect = document.createElement('div');
elemRect.className = 'elem elemRect';
elemRect.style.position = "absolute";
elemRect.style.background = "#ecf0f1";
elemRect.style.width = "100%";
elemRect.style.height = "100%";
elemRect.style.opacity = "100";
renderUIObject(elemRect);
$('.elemContainer').draggableParent();
$('.elemContainer').resizableParent();
makeDeselectable();
handleDblClick();
}
var createDefaultElement = function() {
..
..
};
var handleDblClick = function() {
..
..
};
var renderUIObject = function(object) {
..
..
};
var makeDeselectable = function() {
..
..
};
I could clone the element when the browser detects a keydown event
$(window).keydown(function(e) {
if (e.keyCode == 77) {
$('.ui-selected').clone();
return false;
}
});
then append it to #canvas. But the problem is, none of the functions I mentioned above get called with this method.
How can I copy/paste an element (by pressing CMD+C then CMD+V) and call those above functions on the cloned element?
The jQuery.clone method returns the cloned node. So you could adjust your code to do something like this:
var myNodes = $('.ui-selected').clone();
myNodes.each(function () {
createDefaultElement(this);
appendResizeHandles(this);
appendOutline(this);
});