How to add both mouseover and click event at same time? - javascript

I have two different example one have mouseover functionality and other have click event functionality but now i want both together below are the description:
Mouseover Example Link: http://wheaton.advisorproducts.com/investment-advisory
Mouse click Example : http://ivyfa.advisorproducts.com/financial-planning-process
Requirement are like this
In this example ( http://ivyfa.advisorproducts.com/financial-planning-process ) right now mouseover functionality is working but now i want below functionality:
When user move mouse over the images then in center thier related text will be visible both for funnel and below circle example.
If user click on any of the image section then their related text will be visible everytime untill user click on another image or portion.
Along with this click event when user mousehover on diif-2 images section then also thier related text will be visible , when user move mouse out of the circle then the selcted text will be shown.
In the end i want to merge both the examples
Its very complicated to explain this example sorry for that :(
Below is the js code used for mouseover functionality:
/*-----Only for hove over image -show hide text------*/
var IdAry=['slide1','slide2','slide3','slide4'];
window.onload=function() {
for (var zxc0=0;zxc0<IdAry.length;zxc0++){
var el=document.getElementById(IdAry[zxc0]);
if (el){
el.onmouseover=function() {
changeText(this,'hide','show')
}
el.onmouseout=function() {
changeText(this,'show','hide');
}
}
}
}
function changeText(obj,cl1,cl2) {
obj.getElementsByTagName('SPAN')[0].className=cl1;
obj.getElementsByTagName('SPAN')[1].className=cl2;
}
Below is the js code used for click event functionality:
/*----------Text change on click - Our Process page---------------*/
var prev;
var IdAry = ['slide1', 'slide2', 'slide3', 'slide4'];
window.onload = function () {
for (var zxc0 = 0; zxc0 < IdAry.length; zxc0++) {
var el = document.getElementById(IdAry[zxc0]);
if (el) {
setUpHandler(el);
el.onmouseover = function () {
changeText(this,'hide','show')
}
el.onmouseout = function () {
changeText(this,'show','hide');
}
}
}
}
/*---------This is used to add selected class on clicked id only and remove class selected from rest---------*/
function setUpHandler(el) {
$("#" + IdAry.join(",#")).click(function () {
$(this).addClass("selected");
$("#graphics .selected").not(this).removeClass("selected");
})
/*---------This will add show hide class to thier spans and vise versa-------*/
$("#" + IdAry.join(",#")).click(
function () {
changeText(this, "hide", "show");
clearSelection();
},
function () {
changeText(this, "show", "hide");
clearSelection();
})
}
function changeText(obj, cl1, cl2) {
obj.getElementsByTagName('SPAN')[0].className = "hide";
obj.getElementsByTagName('SPAN')[1].className = "show";
if (prev && obj !== prev) {
prev.getElementsByTagName('SPAN')[0].className = "show";
prev.getElementsByTagName('SPAN')[1].className = "hide";
}
prev = obj
}
function clearSelection() {
if (window.getSelection) window.getSelection().removeAllRanges();
else if (document.selection) document.selection.empty();
}
Thanks
Sushil

You can add multiple event names to the same assignment:
$(document).on('mouseover click', '.yourObject', function (event) {
if (event.type === "mouseover") {
// Mouse-Over code here
} else if (event.type === "click") {
// Click code here
}
});
Also, try to use addEventListener instead of hardcoding events like el.onmouseout=function(){...}
use:
el.addEventListener("mouseout", function () {...});
That'll make it easier to manage the events (Remove them, for example), should that be needed.

You can add multiple events to a DOM by using
$(document).on('mouseover','.yourObject', function(){ //over code })
.on('click', '.yourObject', function() { //click code});

The problem with your code is that you are setting window.onload twice.
Since your are using jQuery you can make it work by binding on document.ready event.
//first sample
(function($){
/*-----Only for hove over image -show hide text------*/
var IdAry=['slide1','slide2','slide3','slide4'];
$(function() {
for (var zxc0=0;zxc0<IdAry.length;zxc0++){
var el=document.getElementById(IdAry[zxc0]);
if (el){
el.onmouseover=function() {
changeText(this,'hide','show')
}
el.onmouseout=function() {
changeText(this,'show','hide');
}
}
}
});
function changeText(obj,cl1,cl2) {
obj.getElementsByTagName('SPAN')[0].className=cl1;
obj.getElementsByTagName('SPAN')[1].className=cl2;
}
}(jQuery));
//second sample
(function($){
/*----------Text change on click - Our Process page---------------*/
var prev;
var IdAry = ['slide1', 'slide2', 'slide3', 'slide4'];
$(function () {
for (var zxc0 = 0; zxc0 < IdAry.length; zxc0++) {
var el = document.getElementById(IdAry[zxc0]);
if (el) {
setUpHandler(el);
el.onmouseover = function () {
changeText(this,'hide','show')
}
el.onmouseout = function () {
changeText(this,'show','hide');
}
}
}
});
/*---------This is used to add selected class on clicked id only and remove class selected from rest---------*/
function setUpHandler(el) {
$("#" + IdAry.join(",#")).click(function () {
$(this).addClass("selected");
$("#graphics .selected").not(this).removeClass("selected");
})
/*---------This will add show hide class to thier spans and vise versa-------*/
$("#" + IdAry.join(",#")).click(
function () {
changeText(this, "hide", "show");
clearSelection();
},
function () {
changeText(this, "show", "hide");
clearSelection();
})
}
function changeText(obj, cl1, cl2) {
obj.getElementsByTagName('SPAN')[0].className = "hide";
obj.getElementsByTagName('SPAN')[1].className = "show";
if (prev && obj !== prev) {
prev.getElementsByTagName('SPAN')[0].className = "show";
prev.getElementsByTagName('SPAN')[1].className = "hide";
}
prev = obj
}
function clearSelection() {
if (window.getSelection) window.getSelection().removeAllRanges();
else if (document.selection) document.selection.empty();
}
}(jQuery));

Related

How to trigger a function on parent div when iframe content is clicked?

I'm trying to create a reusable function that works by hiding a specific div (outside the iframe) whenever a click is made anywhere inside an iframe.
To be more specific, this div I want to hide is a search menu that can be opened on top (z-index) of an iframe. I'd like to close this menu whenever I click outside it, which happens to be inside the full screen iframe.
I couldn't make it work using the solutions from this and other similar pages (Whenever I change the URL, it doesn't work anymore): Detect click event inside iframe
I managed to do something like this that works but the code is repetitive. I'd like a more general function that works whenever I click inside any iframe.
const iframeListener1 = addEventListener('blur', function() {
if (document.activeElement === document.getElementById('chrono-loader')) {
$('#outer-layer-card').stop().fadeOut('fast');
}
removeEventListener('blur', iframeListener);
});
const iframeListener2 = addEventListener('blur', function() {
if (document.activeElement === document.getElementById('plus-loader')) {
$('#outer-layer-card').stop().fadeOut('fast');
}
removeEventListener('blur', iframeListener);
});
const iframeListener3 = addEventListener('blur', function() {
if (document.activeElement === document.getElementById('google-docs-1-loader')) {
$('#outer-layer-card').stop().fadeOut('fast');
}
removeEventListener('blur', iframeListener);
});
const iframeListener4 = addEventListener('blur', function() {
if (document.activeElement === document.getElementById('google-sheets-2-loader')) {
$('#outer-layer-card').stop().fadeOut('fast');
}
removeEventListener('blur', iframeListener);
});
const iframeListener5 = addEventListener('blur', function() {
if (document.activeElement === document.getElementById('google-docs-3-loader')) {
$('#outer-layer-card').stop().fadeOut('fast');
}
removeEventListener('blur', iframeListener);
});
const iframeListener6 = addEventListener('blur', function() {
if (document.activeElement === document.getElementById('google-docs-4-loader')) {
$('#outer-layer-card').stop().fadeOut('fast');
}
removeEventListener('blur', iframeListener);
});
How can I trigger a function (to hide one specific div) whenever I click on any iframe?
Thanks in advance for any suggestions or help
Can save event listeners into a object and have a function to add them dynamically. That would mean to have some sort of html element which would have data-target attribute or similar. Additionaly can move the id_target to function parameter.
var iframe_listeners = [];
function add_iframe_event(){
const id_target = $('data-target element').data('target');
iframe_listeners[id_target] = addEventListener('blur', function() {
if (document.activeElement === document.getElementById(id_target)) {
$('#outer-layer-card').stop().fadeOut('fast');
}
removeEventListener('blur', iframe_listeners[id_target]);
});
}
Edit:
loop method
var iframe_listeners = [];
const ids = [ '1', '2' ];
for(const id of ids){
// skip if element doesnt exist
if($(`#${id}`).length == 0) continue;
add_iframe_event(id);
}
function add_iframe_event(id_target){
iframe_listeners[id_target] = addEventListener('blur', function() {
if (document.activeElement === document.getElementById(id_target)) {
$('#outer-layer-card').stop().fadeOut('fast');
}
removeEventListener('blur', iframe_listeners[id_target]);
});
}

jQuery checkbox trigger change not working

I have the following JS function:
const bindSwitches = function() {
$(document).on("click", ".lever", function() {
var checkbox = $(this).siblings("input[type=checkbox]");
var hiddenField = $(this).siblings("input[type=hidden]");
if (checkbox.prop("checked") === true) {
checkbox.prop("value", 0);
hiddenField.prop("value", 0);
} else if (checkbox.prop("checked") === false) {
checkbox.prop("value", 1);
hiddenField.prop("value", 1);
}
$(checkbox).trigger("change");
});
};
It interacts with a switch component provided by the Materialize library. I have just added the final line, as there is some behaviour that needs to occur whenever a checkbox is triggered. But that change event never fires. I also have this function in my app:
const bindAllChecks = function() {
$(document).on("change", ".select-all-check", function() {
var checks = $(this).closest(".table, table").find(".multiple-check:visible");
if (this.checked) {
$.each( checks, function( index, checkbox ){
if ($(checkbox).prop("checked") === false) {
$(checkbox).prop("checked", true);
$(checkbox).trigger("change");
}
});
} else {
$.each( checks, function( index, checkbox ){
if ($(checkbox).prop("checked") === true) {
$(checkbox).prop("checked", false);
$(checkbox).trigger("change");
}
});
}
});
};
Notice how I use the exact same $(checkbox).trigger("change"). In this function it works perfectly.
I've tried changing the order in which I bind the events, to make sure the change event is definitely defined beforehand. I've made sure that the rest of the function is being triggered correctly and that there are no issues in that regard. I've also tried different variations of alternative syntax, nothing has worked.
Here is the code it is supposed to trigger:
const bindCheckboxOverride = function() {
$(document).on("change", ".checkbox-collection input[type=checkbox]:not(.select-all-check)", function() {
var hiddenField = $(this).prev();
if(hiddenField.attr("disabled") === "disabled") {
hiddenField.removeAttr("disabled");
} else {
hiddenField.attr("disabled", "disabled");
}
});
};
I still don't have an exact solution to the question I asked, but I have come up with an alternate method. Instead of trying the trigger a change, I have pulled out the functionality I want from the change even into its own function:
const bindCheckboxOverride = function() {
$(document).on("change", ".checkbox-collection input[type=checkbox]:not(.select-all-check)", function() {
handleCheckboxDisable(this);
});
};
const handleCheckboxDisable = function(checkbox) {
var hiddenField = $(checkbox).prev();
if(hiddenField.attr("disabled") === "disabled") {
hiddenField.removeAttr("disabled");
} else {
hiddenField.attr("disabled", "disabled");
}
};
So now I'm able to call this function directly from my other function:
const bindSwitches = function() {
$(document).on("click", ".lever", function() {
var checkbox = $(this).siblings("input[type=checkbox]");
var hiddenField = $(this).siblings("input[type=hidden]");
if (checkbox.prop("checked") === true) {
checkbox.prop("value", 0);
hiddenField.prop("value", 0);
} else if (checkbox.prop("checked") === false) {
checkbox.prop("value", 1);
hiddenField.prop("value", 1);
}
handleCheckboxDisable(checkbox);
});
};
It doesn't answer the question but I thought that may be of help to somebody. Would still like to know why the original code doesn't work if anybody has any insights.

How to deactivate a function after being activated

I can activate a function on a certain click event but I want to stop that function whenever I do a click event on another div.
This is my function so far :
$('#text-tab').click(function() {
writeOnCanvas(true);
});
$('#paint-tab, #sticker-tab, #done-tab').click(function() {
writeOnCanvas(false);
});
function writeOnCanvas(bool) {
if(bool) {
$('body').click(function(e) {
var clickedOnCanvas = e.target.id == "canvas" || $(e.target).parents('#canvas').length ? true : false;
var alreadyTextArea = $('textarea.textarea_editable')[0];
if(clickedOnCanvas) {
if(alreadyTextArea) {
drawSentence();
} else {
createTextArea(e);
}
}
});
$('#text > div > .color_choice').click(function() {
var textColor = $(this).css('background-color');
$('.textarea_editable').css('color', textColor);
});
$('#text > div > div:not(".color_choice")').click(function() {
var textSize = $(this).css('font-size');
$('.textarea_editable').css('font-size', textSize);
$('canvas').attr('data-textSize', textSize);
});
} else {
console.log('stop working');
return false;
}
}
As you can see, when I click on #text-tab, I put my function to "true", this is working perfectly. However, even if I click on #paint-tab, #sticker-tab or even #done-tab, the function is still working even thought I see the console.log('stop working');
EDIT :
I tried to put a global variable but now my function refuse to work even if I click on #text-tab and the global variable is set to true.
var WRITEONCANVAS = false;
writeOnCanvas();
$('#text-tab').click(function() {
WRITEONCANVAS = true;
});
$('#paint-tab, #sticker-tab, #done-tab').click(function() {
WRITEONCANVAS = false;
});
function writeOnCanvas() {
if(WRITEONCANVAS) {
$('body').click(function(e) {
var clickedOnCanvas = e.target.id == "canvas" || $(e.target).parents('#canvas').length ? true : false;
var alreadyTextArea = $('textarea.textarea_editable')[0];
if(clickedOnCanvas) {
if(alreadyTextArea) {
drawSentence();
} else {
createTextArea(e);
}
}
});
$('#text > div > .color_choice').click(function() {
var textColor = $(this).css('background-color');
$('.textarea_editable').css('color', textColor);
});
$('#text > div > div:not(".color_choice")').click(function() {
var textSize = $(this).css('font-size');
$('.textarea_editable').css('font-size', textSize);
$('canvas').attr('data-textSize', textSize);
});
} else {
return false;
}
}
Use unbind to remove a bound function such as click
See this fiddle https://jsfiddle.net/jc4wzerf/1/
The key line is:
$('.body-text').unbind( "click" )
In your case, you would use:
$('body').unbind( "click" )
EDIT
My fault, unbind is deprecated in 3.0. As an alternative, you can just use off as suggested by charlietfl
https://jsfiddle.net/jc4wzerf/3/
$('body').off( "click" )
or
Just use a flag and single handler
https://jsfiddle.net/jc4wzerf/2

Show/Hide div with checkboxes using classes multiple times on a page

I am having trouble getting my script to work here. I am trying to target the show me span when the checkboxes are checked and it's not working.
Here is the code and link to fiddle: http://jsfiddle.net/dalond/nonyg6sm/
$('.single').live('change', ':checkbox', function() {
var target = $(this).closest('.single').prev().find('.showMe');
if ($(this).find('input:checked').length == 0) {
target.hide();
} else {
target.show();
}
});
I got it worked : http://jsfiddle.net/nonyg6sm/3/
$('input[type=checkbox]').click(function() {
var target = $(this).closest('.NoEd').prevAll(".Subs:first").find(".showMe");
if (this.checked) {
target.show();
} else {
target.hide();
}
});
You can modify it to feet your need.
UPDATE
http://jsfiddle.net/nonyg6sm/4/
$('input[type=checkbox]').click(function() {
var target = $(this).closest('.NoEd').prevAll(".Subs:first").find(".showMe");
if ($(this).closest('.NoEd').find("input[type=checkbox]:checked").length == 0) {
target.hide();
} else {
target.show();
}
});

Remove class onclick anything else

This may seem like a really simple question, but I'm having a lot of trouble trying to get it to work.
I have a series of elements spread across different parts of a page.
<span class="click-element"><span>
---
<span class="click-element"><span>
--
<span class="click-element"><span>
I want to toggle a class ("active") on/off on each of them when they are clicked individually, this should also remove the class from all the others.
To do this, my function looks like this:
var targets = document.querySelectorAll('.click-element');
for (i = 0; i < targets.length; i++) {
targets[i].addEventListener('click', function () {
var clicked = this;
if (this.classList.contains("active")) {
[].forEach.call(targets, function (a) {a.classList['remove']('active');});
}
else {
[].forEach.call(targets, function (a) {a.classList[a == clicked ? 'add' : 'remove']('active');});
}
});
}
But what I'm trying to do, is then remove the class when anything else is clicked in the document:
document.addEventListener('click', function () {
document.querySelector('.click-element.active').classList.remove("active");
});
However, the problem I'm having is the second event seems to just override the first. How can I fix this? Or is there a cleaner approach to do what I want?
No jQuery thanks
try to cancle the event bubbling like this:
for (i = 0; i < targets.length; i++) {
targets[i].addEventListener('click', function(e) {
var clicked = this;
if (this.classList.contains("active")) {
[].forEach.call(targets, function(a) {
a.classList['remove']('active');
});
}
else {
[].forEach.call(targets, function(a) {
a.classList[a == clicked ? 'add' : 'remove']('active');
});
}
e.stopPropagation();
});
}
Keys:
targets[i].addEventListener('click', function(e) {...
e.stopPropagation();...
Try this :
var targets = document.querySelectorAll('.click-element');
var activeElement; // this should be some global variable
for (i = 0; i < targets.length; i++) {
targets[i].addEventListener('click', function () {
if(activeElement){
activeElement.classList['remove']('active');
}
var clicked = this;
activeElement = this;
if (this.classList.contains("active")) {
[].forEach.call(targets, function (a) {a.classList['remove']('active');});
}
else {
[].forEach.call(targets, function (a) {a.classList[a == clicked ? 'add' : 'remove']('active');});
}
});
}
I think better solution will be to use event bubbling.
If you have a common container:
document.getElementById('#containerId').addEventListener('click', function(evt){
var element = evt.target;
if(element.classList.contains('click-element'){
//toggle active
element.classList[element.classList.contains('active') ? 'add' : 'remove']('active');
} else{
//remove the active from all elements
document.querySelectorAll('.click-element.active').forEach(
function (clickElement, index) {clickElement.classList[remove]('active')}
);
}
});
In your case you don't have child elements in the spans, but if you had you need to check if the clicked element is a descendant of the span.
try jQuery libraries it will make it easy
$( "span" ).removeClass( "yourClass" );
http://api.jquery.com/removeclass/

Categories

Resources