how can I target separately elements from a multitude of elements with the same classes or other properties. I cannot add different classes on each element so I need to target each element when I'm working on.
I have tried this so far but it is targeting all elements with input:text because my wrong condition of targeting each separately element working on.
var selector = $('input:radio').prop("checked", true);
var element = $ ('input:text');
$(selector).on('change', function( event ) {
if(this){
$(element).prop('disabled', true);
alert('disable only this element when radio is selected');
}
else{
alert('others input:text not disabled');
$('input:text').prop("disabled", false);
}
})
Fiddle:
By using DOM navigation method, you can do it really easily. Just use this :
var selector = $('input:radio').prop("checked", true);
var element = $ ('input:text');
$(selector).on('change', function( event ) {
var el = $(this).closest('.input-group').find('input:text');
element.prop('disabled', function(){
return !el.is(this);
})
});
Fiddle : http://jsfiddle.net/D2RLR/5874/
For dynamic input, you'll need to use Event delegation (read more here):
//document should be closest static element
$(document).on('change', 'input:radio', function(){
var el = $(this).closest('.input-group').find('input:text');
$('input:text').prop('disabled', function(){
return !el.is(this);
})
})
I don't understand exactly what you're trying to do, but you can use $(this) to target the element that triggered the event instead of trying to use a selector.
I think something like this is what you want:
$(selector).on('change', function( event ) {
$("input:text").prop("disabled", true);
$(this).parent().siblings("input:text").prop("disabled", false);
})
It disables all of the input:text and then enables the one whose radio button was selected.
Try this:
$(selector).on('change', function( event ) {
$('input:text').prop("disabled", false);
$(this).closest('.input-group').find(element).prop('disabled', true);
})
http://jsfiddle.net/D2RLR/5869/
Why not simplify?
Demo Fiddle
$('input:radio').on('change', function (event) {
$('input[type=text]').prop('disabled', false);
$(this).parent().next('input[type=text]').prop('disabled', 'false');
})
As others said, its not exactly clear what you're trying to do, or how general is your question. If the elements matching your selector have exactly the same attributes (including class), you may need to base on the context they are embedded on, or as a last resource, you may be able to base on the order of these elements.
Context: If you're looking for "p.many_like_me" , and you know the element you're trying to match is inside of #parent_id, you just refine your selector as "#parent_id p.many_like_me"
Order: If you know you're looking for the third element on the DOM matching your selector, you can use get() to select it: $("p.many_like_me").get(2) (get takes an index zero-based).
If you need to select them based on an event triggered by a nearby or somehow-related element, then some of the other answers given here are ok.
Related
I have a dynamic hover that gets activated based on whether a hidden element exists or not. I'm updating my code to incorporate dynamically created elements but have ran into an issue and don't know how to select a parent.
Previously I used $(".infotip").parent().hover but have updated to:
$(document).on("mouseenter", ".parent-selector", function() {
$(this).find(".infotip").addClass("active");
});
$(document).on("mouseleave", ".parent-selector", function() {
$(this).find(".infotip").removeClass("active");
});
So what needs to happen is I need ".parent-selector" to behave like $(".infotip").parent()
Since the content is dynamic and you mentioned you can't add a class to the parent when it's created, the only way I can think to do this would be to watch for any new elements that have been added and then bind your events.
This function will periodically look for any elements with the .infotip class that does not have our custom events_bound attribute already. If it finds one, it'll add the attribute and then bind the mouse events to the parent. I've included a fiddle illustrating this with dynamic content.
//check for changes in the dom
setInterval(function() {
$('.infotip:not([events_bound])').each(function() {
//add attribute so that we don't re-bind to this element
$(this).attr('events_bound', true);
//now bind the events to the parent
$(this).parent().mouseenter(function() {
$(this).find(".infotip").addClass("active");
})
$(this).parent().mouseleave(function() {
$(this).find(".infotip").removeClass("active");
})
});
}, 500);
https://jsfiddle.net/ybrwv0c8/1/
Of course if there is anything identifiable about the parent, then the best way would be to use a selector for your on. For instance, if there's a dynamically generated ID with a standard structure like parent_13835723, you could do a partial attribute selector like $('[id^=parent_]')
You might also be able to use use the jquery :has pseudoselector like so. However, this searches all descendants for an element, which may not work correctly depending on how your DOM is structured.
$(document).on("mouseenter", ":has('.infotip')", function() {
$(this).children('.infotip').addClass("active");
});
$(document).on("mouseleave", ":has('.infotip')", function() {
$(this).children('.infotip').removeClass("active");
});
However, according to the jquery docs here http://api.jquery.com/has-selector/:
The expression $( "div:has(p)" ) matches a <div> if a <p> exists anywhere
among its descendants, not just as a direct child.
Because :has() is a jQuery extension and not part of the CSS
specification, queries using :has() cannot take advantage of the
performance boost provided by the native DOM querySelectorAll()
method. For better performance in modern browsers, use $(
"your-pure-css-selector" ).has( selector/DOMElement ) instead.
I'm not sure whether the :has or setInterval method would have better performance.
How about
$(".infotip").parent().mouseleave(function() {
$(this).find(".infotip").addClass("active");
}
and
$(".infotip").parent().mouseleave(function() {
$(this).find(".infotip").addClass("active");
}
Reference : https://api.jquery.com/mouseleave/
You can use jQuery's custom :has selector:
$('document').on('mouseenter', ':has(.infotip)', function () {
$(this).find(".infotip").addClass("active");
});
$('document').on('mouseleave', ':has(.infotip)', function () {
$(this).find(".infotip").addClass("active");
});
I haven't tested this, as there is no HTML provided in the question, but the documentation seems to indicate it will do what you want.
As simple as
jQuery(".child").parent().on('mouseenter', function(){
jQuery(this).css('background', '#f00');
});
jQuery(".child").parent().on('mouseleave', function(){
jQuery(this).css('background', '#0ff');
});
DEMO
Edit:- Based on further clarification,
You can attach events to objects when you create them. If you are binding the same events to multiple objects at different times, just create a named function.
OR
A really dirty hack would be to to unbind and rebind the events everytime a hirerchy of elements is added to the DOM.
Something like
var init = function() {
jQuery(".child").parent().off().on('mouseenter', function(){
jQuery(this).css('background', '#f00');
});
jQuery(".child").parent().off().on('mouseleave', function(){
jQuery(this).css('background', '#0ff');
});
};
Just call the method init everytime you add something to the DOM.
I'm working with Prototype on a script to detect all Select Tags under a Div and then add an event/observer on each one!
Here is the code to find the Elements I need:
Event.observe(window, 'load', function() {
var tab=$("product-options-wrapper").descendants();
var attCode=[];
var j=0;
for (i=0;i<tab.length;i++) {
if (tab [i].tagName =="SELECT") {
attCode[j++]=tab[i].id
}
}
});
I have all the Ids I need.
How can I add an observer (on change) for each one?
$(id).on("change", function(event) {
alert(id+"__"+$(id).value);
});
Prototype supports event delegation out of the box. Event.on takes on optional second selector parameter. So in your case:
$("product-options-wrapper").on('click', 'select', function(event, element) {
// This callback will only get fired if you've clicked on a select element that's a descendant of #product-options-wrapper
// 'element' is the item that matched the second selector parameter, in our case, the select.
....
});
That parameter can be any CSS selector string:
$('my-element').on('click', '.some-class', function(event, element) { ... });
Check out Element.select, too. That will condense the code in your original question down to essentially one line:
$("product-options-wrapper").select('select');
This one seems kind of confusing because your selector string is 'select' (you want all SELECT elements under #product-options-wrapper). You could also do:
$$('#product-options-wrapper select');
These both return an array of matched elements.
HTH
You only need a click handler on the div (in other words, use event delegation)
var tab = $("product-options-wrapper");
tab.on('click',function(e){
e = e || event;
if ( /^select$/i.test((e.target || e.srcElement || {}).tagName) ){
//do stuff
}
});
That should do. Please post your html or even better a jsfiddle if you need more help.
$(function(){
$('#product-options-wrapper select').on("change", function(e) {
alert(id+"__"+$(this).val());
});
});
I guess you forgot the . at the beginning of product-options-wrapper to indicate its a class? Or is it really a tag?
I've been struggling with what seems to be a simple problem for a few hours now. I've written a REGEX expression that works however I was hoping for a more elegant approach for dealing with the HTML. The string would be passed in to the function, rather than dealing with the content directly in the page. After looking at many examples I feel like I must be doing something wrong. I'm attempting to take a string and clean it of client Events before saving it to our Database, I thought jQuery would be perfect for this.
I Want:
Some random text click here and a link with any event type
//to become:
Some random text click here and a link with any event type
Here's my code
function RemoveEvilScripts(){
var myDiv = $('<div>').html('testing this Do it! out');
//remove all the different types of events
$(myDiv).find('a').unbind();
return $(myDiv).html();
}
My results are, the onClick remains in the anchor tag.
Here's a pure Javascript solution that removes any attribute from any DOM element (and its children) that starts with "on":
function cleanHandlers(el) {
// only do DOM elements
if (!('tagName' in el)) return;
// attributes is a live node map, so don't increment
// the counter when removing the current node
var a = el.attributes;
for (var i = 0; i < a.length; ) {
if (a[i].name.match(/^on/i)) {
el.removeAttribute(a[i].name);
} else {
++i;
}
}
// recursively test the children
var child = el.firstChild;
while (child) {
cleanHandlers(child);
child = child.nextSibling;
}
}
cleanHandlers(document.body);
working demo at http://jsfiddle.net/alnitak/dqV5k/
unbind() doesn't work because you are using inline onclick event handler. If you were binding your click event using jquery/javascript the you can unbind the event using unbind(). To remove any inline events you can just use removeAttr('onclick')
$('a').click(function(){ //<-- bound using script
alert('clicked');
$('a').unbind(); //<-- will unbind all events that aren't inline on all anchors once one link is clicked
});
http://jsfiddle.net/LZgjF/1/
I ended up with this solution, which removes all events on any item.
function RemoveEvilScripts(){
var myDiv = $('<div>').html('testing this Do it! out');
//remove all the different types of events
$(myDiv)
.find('*')
.removeAttr('onload')
.removeAttr('onunload')
.removeAttr('onblur')
.removeAttr('onchange')
.removeAttr('onfocus')
.removeAttr('onreset')
.removeAttr('onselect')
.removeAttr('onsubmit')
.removeAttr('onabort')
.removeAttr('onkeydown')
.removeAttr('onkeypress')
.removeAttr('onkeyup')
.removeAttr('onclick')
.removeAttr('ondblclick')
.removeAttr('onmousedown')
.removeAttr('onmousemove')
.removeAttr('onmouseout')
.removeAttr('onmouseover')
.removeAttr('onmouseup');
return $(myDiv).html();
}
I want to obtain the exact details for the item on a web page that has been clicked on, using jquery.
That item can be a form item (like a checkbox, text box, text area etc) or section of text (in a paragraph or div or other) or list or image ...
What I figured out is the following--
$(function(){
$('*')
.bind('click', function(event) {
//now obtain details of item that has been clicked on...
});
});
Now, I want the exact details- viz the div id/form id/paragraph #, ie all details for that particular item. How do i get this data? I understand that this data is available in the DOM but I just dont know how to get it in this particular case...
Probably the best way to do to use the target property of the event. By default, this returns a non-jQuery object, which isn't particularly useful, however wrapping it in $() solves this issue:
$(function() {
$(document).bind('click', function(event) {
var element = $(event.target);
alert(element.height()); // Get height
alert(element.attr('id')); // Get ID attribute
// ...
});
});
If you want to fix your current method, inside your click() handler, you can access the properties of that element using .attr(), and friends:
$(function() {
$('*').bind('click', function(event) {
alert($(this).height()); // Get height
alert($(this).attr('id')); // Get ID attribute
// ...
});
});
$(this) in the scope of the function references the element that was clicked. There is a list of functions that will return attributes here and here in the jQuery docs. $.attr('id') will return the element's ID, among other things, and $.data() will return data-* attributes.
To get attributes of parent elements, simply use $(this).parent(). For example, to get the ID of the form that contains the clicked element, use $(this).closest('form').attr('id');. Everything is relative to the clicked element ($(this)), so you can just use the DOM traversal functions.
However, using $('*').bind() is incredibly inefficient; you're binding an event handler to every element on the page, when really you should delegate events with .on() (jQuery 1.7+):
$(function() {
$('body').on('click', '*', function(event) {
alert($(this).height()); // Get height
alert($(this).attr('id')); // Get ID attribute
// ...
});
});
This approach only binds one event to <body> instead of an event to every element on the page.
Use the target of click event on page
$(document).click(function(event){
/* store native dom node*/
var tgt=event.target;
/* store jQuery object of dom node*/
var $tgt=$(tgt);
/* example element details*/
var details={ id : tgt.id, height: $tgt.height(), tag : tgt.tagName}
console.log( details)
})
Look at the event.target, and then you can use jQuery's .parents() method to look at every ancestor:
$(document).on('click', function(event) {
var $t = $(event.target); // the element that was actually clicked
var $p = $t.parents(); // the target's parents
var $form = $p.filter('form').first(); // the enclosing form, if it exists
});
my code and my problem is:
<script type="text/javascript">
$(document).ready(function() {
// this variable is used to set the dynamic elements
tagFlag = '';
$("#a1").click(function(event) {
event.preventDefault();
tagFlag = 'me'; // setting the element which I want to trigger later
});
$('#'+tagFlag).click(function(e) {
// do sthing here
});
});
</script>
</head>
<body>
make the element
<p id="me">some words here</p>
</body>
</html>
but.when I set the tagFlag,and click the "p" nothing is happen.BTW.there is error when tagFlag had been set nothing.So.How can I get what I want?
Thank you very much!!
Maybe you should look at the jQuery live() method that will assign event to all existing and future elements.
http://api.jquery.com/live/
There is no element wit the ID "a1". If you want the first anchor element use
$.("a:eq(0)")
instead.
If that's not it, report back please.
use a jquery object and add the clicked elements to it:
$(document).ready(function() {
$tagFlag = $("");
$("#a1").click(function(event) {
event.preventDefault();
$tagFlag.add($(this));
});
$tagFlag.click(function(e) {
// do sthing here
});
});
You can attach a .click() handler to document and check if the target of the click was the element you cared about, similar to how .live() behaves internally, like this:
$(function() {
var tagFlag = '';
$("#a1").click(function(event) {
event.preventDefault();
tagFlag = 'me';
});
$(document).click(function(e) {
if(tagFlag && //is it even set?
(e.target.id == tagFlag || $(e.target).closest('#'+tagFlag).length)) {
//do work here
}
});
});
You can give it a try here, the only change to your markup is the addition of a child element (to show click bubbling/handling working) and giving the anchor that a1 ID I think you intended for it to have in the question.
Alternatively if you know the set of elements that may be clicked, give them a class and bind a handler to them, checking the ID like I have above...or unbind the class and rebind to the specific ID each time, there's a few ways to go about this :)