I am trying to hide two elements with classes notify-me and write-review, on click on anywhere on the page but not on those two elements.
How to do this using prototype?
Right now if I click on even the overlays, they are being closed.
PS: I am attaching the click event to body.
Try this :
$(document).on('click', function (e) {
var re = /(^|\s)(notify-me|write-preview)(\s|$)/;
if (re.test($(e.target).classNames())) return false;
$$('.notify-me', '.write-preview').invoke('hide');
});
Here is an improved version which bubbles up through the target element's ancestors :
$(document).on('click', function (e) {
var re, els, iterator;
re = /(^|\s)(notify-me|write-preview)(\s|$)/;
els = [$(e.target)].concat($(e.target).ancestors());
iterator = function (el) { return re.test(el.classNames()); };
if (els.find(iterator)) return false;
$$('.notify-me', '.write-preview').invoke('hide');
});
Here is a demo : http://jsfiddle.net/wared/U7E2a/.
Related
I am using this code:
document.addEventListener("DOMContentLoaded", function(event) {
document.getElementById("div#logo1").onclick = function(){
hideAllImages();
document.getElementById("01").style.display="block";
removeNavHighlight();
document.getElementById("div#logo1").classList.add("my_active");
};
document.getElementById("div#logo2").onclick = function(){
hideAllImages();
document.getElementById("02").style.display="block";
removeNavHighlight();
document.getElementById("div#logo2").classList.add("my_active");
};
document.getElementById("div#logo3").onclick = function(){
hideAllImages();
document.getElementById("03").style.display="block";
removeNavHighlight();
document.getElementById("div#logo3").classList.add("my_active");
};
function hideAllImages() {
var items = document.getElementsByClassName('changing_text');
var itemsLen = items.length;
for(var i = 0; i < itemsLen; i++) {
items[i].style.display="none";
}
}});
Which working fine with click event but I want to convert it to be functional when I hover to the element.
What this function must to: for example, when I hover on an image other element must appear and previous element must become hidden.
This is Vanilla Javascript code.
Any suggestions? tried to change .onclick to .onmouseover but not working.
It's not .mouseover it's .onmouseover
Is it working for you to replace .onclick by .onmouseover?
These functions are always in format on<event>. It should be .onmouseover as the other answers have already said. Note that you'd be using mouseover if you were adding an event listener using the addEventListener function.
$("input").on("keypress",function(e){
if(e.which===13){
$("ul").last().append("<li>"+$(this).val()+"</li>");
}
$("li").on("click",function(){
$(this).toggleClass("striked");
});
$("li").on("mouseenter",function(){
$(this).css("color","green");
});
});
$("li").on("click",function(){
$(this).toggleClass("striked");
});
$("li").on("mouseenter",function(){
$(this).css("color","green");
});
$("#slide").on("click",function(){
$("input").slideToggle();
});
Here, I have used the onClick event on<li> to apply the striked class two times just to make it work for both dynamic and non-dynamic elements on the page. But the code is replicated and seems long. Is there any way to shorten so that I can write it once and it gets activated for both types of elements?
Use event delegation instead, on the ul, so you only have to set up listeners once, rather than setting up multiple listeners for every element on load and on each .append. Also, save the ul and the input jQuery-wrapped elements in a variable once rather than selecting them and wrapping them with jQuery each time they're used:
const $ul = $("ul");
const $input = $("input");
$input.on("keypress", function(e) {
if (e.which === 13) {
$ul.last().append("<li>" + $(this).val() + "</li>");
}
});
$ul.on("click", 'li', function() {
$(this).toggleClass("striked");
});
$ul.on("mouseenter", 'li', function() {
$(this).css("color", "green");
});
$("#slide").on("click", function() {
$input.slideToggle();
});
A rather generic approach would be to capture the click event and check if it is from ul
document.body.onclick = function(e){
e = e || event;
var from = findParent('ul',e.target || e.srcElement);
if (from){
/* it's a link, actions here */
}
}
//find first parent with tagName [tagname]
function findParent(tagname,el){
while (el){
if ((el.nodeName || el.tagName).toLowerCase()===tagname.toLowerCase()){
return el;
}
el = el.parentNode;
}
return null;
}
now you can change the tagName passed to the findParent function and do accordingly
Read Here
You can try using the jquery all selector $('*'). For more information on this see
https://api.jquery.com/all-selector/.
Or you can add a specific class to every element you want to have an onClick action.
I am trying to let Jq listen to three buttons at the same onclick method
then trigger a function and call the clicked button by $(this);
here is a sample :
$("body").on('click', 'a.home:visible', 'a.mobile:visible', 'a.phone:visible', function () {
var attr = $(this).attr('attr');
$(this).parents('.dropdown-menu').prev().prev().text(attr);
});
You did it basically correct. Your approach is fine. But you have to combine it in one string, not as single parameters. And you don't need :visible, because you can't click on invisible elements. ;)
$("body").on('click', 'a.home, a.mobile, a.phone', function() {
var attr = $(this).attr('attr');
$(this).parents('.dropdown-menu').prev().prev().text(attr);
});
If the elements are static you should even use a normal event listener instead of a delegation.
$('a.home, a.mobile, a.phone').click(function() {
var attr = $(this).attr('attr');
$(this).parents('.dropdown-menu').prev().prev().text(attr);
});
Put them in one quotes
$("body").on('click', 'a.home:visible,a.mobile:visible,a.phone:visible', function() {
alert('Clicked')
});
JSFIDDLE
I'm writing a simple jQuery plugin that will dynamically place a div under a text box whenever it has focus. I've been able to get the position just about right in all the browsers.
I have to attach two event handlers as well on the focus and blur events of the textbox. And it works okay, but the problem is that the div that has been placed under the textbox closes even when we click on it. Now it makes sense why it would so happen, it's because the textbox loses focus, but is there a way I can stop it from happening?
I tried attaching this to the blur event handler -
if($(mainElem).is(":focus")) return;
where mainElem is the div that is shown below the textbox.
Here is a jsFiddle to illustrate the problem.
You are not going to be able to use the blur event if you want to place "clickable" elements in the div that shows. One way to solve this is to bind your event listener to a more global element like the document and then filter out the targets.
Here is a code sample:
$(document).on('click', function (e) {
var targetEl = e.target,
parent = $(e.target).parents()[0];
if (relElem[0] === targetEl || self[0] === targetEl || self[0] === parent) {
$(mainElem).show();
} else {
$(mainElem).hide();
}
});
Here is an update to your fiddle: http://jsfiddle.net/9YHKW/6/
This is a fiddle that I threw together for a project a while back: http://jsfiddle.net/MYcZx/4/
While it is not based off of your fiddle (and I do apologize) I believe that the functionality is much the same as what you're looking for. My example does not include input fields, but rather spans that hold the values. And while I'm not managing focus/blur, you could add a tabIndex attribute to the spans and then add a trigger on focus that would open the menu.
var $sub = $('.subscription');
$sub
.on('click', '.remove', function() {
$(this).parent().remove();
})
.on('click', 'li', function(e) {
var $this = $(this),
$parent = $this.parent(),
$options = $parent.children('li'),
$value = $parent.siblings('.value'),
isMulti = $parent.hasClass('multi'),
values = [];
if(!isMulti) {
$options.removeClass('active');
}
$this.toggleClass('active');
$options.filter('.active').each(function() {
values.push($(this).text());
});
$value.text(values.join(', ') || 'select');
$value[(values.length ? 'add' : 'remove') + 'Class']('set');
});
var $clone = $sub.clone(true);
$('.new')
.on('click', function() {
$(this).before($clone.clone(true));
});
Is it possible to have an alert pop up when any element on the page is clicked that tells you the tag name (or id or whatever other information) about that element?
I basically want to set up the following for every element:
$('#wrapper').click(function() {
alert($(this).prop('tagName'));
})
Except I don't want to write that code for every single element on the page as that would take forever and would be extremely impractical in every way.
Bind your listener on a global object with a selector.
$(document).on('click', '*', function() {
alert($(this).prop('tagName'));
});
should work.
document.body.addEventListener("click", function (e) {
e = e || window.event;
alert(e.toElement.getAttribute("id"));
});
How about this
$(document).on('click', '*', function() {
// Set clicked element's id to variable
var elementName = $(this).attr('id');
// Alert displaying id of clicked element
alert(elementName);
})
Here is an pure javascript method:
document.onclick = function(e) {
e = e || window.event;
var o = e.srcElement||e.target;
alert(o.id);
}