I'm trying to remove an element from a page based on it's background attribute.
Something like:
if ( $('td').attr('background','backgroundimageurl')){this.remove();}
But this does not work any suggestions?
You can also use filter to filter the result set based on your operations:
$( 'td' ).filter( function(){
// return true of it matches, thus, keeping it in the object
return $(this).css( 'backgroundImage' ) === 'someUrlOrWhatever';
}).remove();
Demo per roXon's request: http://jsfiddle.net/danheberden/9rTZj/
However, it would be better to do a check like
return /someDomain\.com\/path\/to\/whatever/.test( $( this ).css( 'backgroundImage' ) );
in the filter function. Different browsers will return different formatting for css rules, as roXon pointed out about the === approach won't work in FF because the returned string will be url("thePath") instead of url(thePath) like in webkit. Thus, just testing for the url value would be most flexible.
The reason it's not working is that in your code snippet, "this" is the current context (most likely the window).
This might do what you want:
$('td').each(function (i, e) {
if (e.style.foo === "bar") {
$(e).remove();
}
});
each iterates through all of the elements that matched. i is the number of the loop, and e is the current element. So we test each element and then act when we find the one with the style we want.
Even shorter example:
$('td[background="backgroundimageurl"]').remove();
Do some reading on jQuery selectors. They can be really useful :)
http://api.jquery.com/category/selectors/
Try this. When you were doing attr("background","backgroundurl") this was trying to set the background attr rather than find elements matching. This will do the trick.
if($("body").find("td").css("background-image") == "backgroundimageurl"){this.detach()};
Related
I want to check if an element has this class or another class like this:
if ( $elem.hasClass("foo") || $elem.hasClass("bar") ) {
// do something
}
And I also want to check if an element has two classes:
if ( $elem.hasClass("foo") && $elem.hasClass("bar") ) {
// do something else
}
Is there a way to do this all within the hasClass() function? Something like:
if ( $elem.hasClass("foo bar") ) {
// do something when element has both classes
}
else if ( $elem.hasClass("foo","bar") ) {
// do something when element has either class
}
Strictly answering to your question: no, you can not.
hasClass() accepts a single argument.
As pointed out by others, you might use is(), but here is a test that shows that performances are very much penalized.
I suggest you to stay with your current code.
You could do something a little different to accomplish this. Not sure if this meets your needs though.
Use multiple selectors you can see if an element that matches exists on the page
Use each to execute the code you want
Example of something like this:
$("span.foo, span.bar").each( function() {
$(".test").html("foo or bar was found");
});
JS Fiddle: http://jsfiddle.net/s3gL5pwm/1/
A second solution that uses if would be to use .is() instead.
For example:
if ($("span").is(".foo, .bar")) {
$(".test").html("foo or bar exists");
};
JSfiddle: http://jsfiddle.net/eL2a8smt/
Background
As of jQuery 1.9 the .attr(..) method no longer returns property values, instead we now have to use .prop(..). Unfortunately this also applies to attributes specified via an attributes selector i.e. $("input[value=]")
See
http://jquery.com/upgrade-guide/1.9/#attr-versus-prop-
and a good SO discussion on the differences between .attr and .prop :
.prop() vs .attr()
My Situation
I'm currently using selectors like $("input[value=]") and $("select[value=]")
to select input elements that have no value set. However, this no longer works with jQuery 1.9, instead I'm now doing something like this:
var hasValue = function () { return !!($(this).val().length); };
var hasNoValue = function () { return !($(this).val().length); };
$("input").filter(hasValue);
$("select").filter(hasValue);
My actual selectors are a little larger, checking multiple elements with or without values so now I'm having to split my 1 selector string into multiple selectors with .filter(..) method calls in between.
Question
Is there an equivalent to $("[value=]"), $("[value!=]"), $("[value='abc']") which uses the property instead of the attribute? And if not, is there a cleaner way than using the .filter(hasValue) and .filter(hasNoValue) methods?
Thanks
Using .filter seems to be the only way, but it's not too bad and you can actually make it a little more accurate by using .val:
$(":input").filter(function () { return $(this).val() === ""; });
If this really is that reprehensible to you, you could create a custom selector.
$.expr[':'].emptyInput = function (elem) {
return $(elem).is(":input") && $(elem).val() === "";
};
http://jsfiddle.net/ExplosionPIlls/zaZPp/
EDIT: You may also be able to get away with using this.value instead of $(elem).val().
According to the upgrade guide:
However, when a selector like "input[value=abc]" is used, it should always select by the value attribute and not any change made to the property by the user, for example from them typing into a text input. As of jQuery 1.9, this behaves correctly and consistently. Earlier versions of jQuery would sometimes use the property when they should have used the attribute.
So this answers your first question - there is not a direct equivalent, the point is to use the attribute instead of the property.
Your code seems fine, but if you want to be more standardized and re-usable you could create an additional filter. Like so:
(function($) {
$.expr[':'].hasValue = function(element) {
var $element = $(element);
return element.is(':input') && element.val();
};
}(window.jQuery));
This will allow you to select stuff like that:
// Select input elements with value and select elements without value.
$('input:hasValue,select:not(:hasValue)');
And other various combinations you need.
I came across this and just wanted to post another solution I found that works in some situations where some of the other suggested solutions are not appropriate.
Simply add this event handler to your code
$('input').on('keyup', function(){
var value = $(this).val();
$(this).attr('value', value);
});
I've recently come across a code sample I had to use, and I was able to use it, but I didn't quite understand exactly what was going on.
Here's part of the code:
.sortElements(function(a, b){
return $.text([a]) > $.text([b]) ?
inverse ? -1 : 1
: inverse ? 1 : -1;
}
I know that this function is deciding which element should be sorted first out of a and b, and I know that inverse is deciding the sort order, but I don't know what $.text([a]) is doing. Is it parsing a as text kind of like parseInt(a) and Date.parse(a)?
Google could not help me. I've also looked into the jQuery site and all I've found is
$(selector).text(), $(selector).text(newText) function.
Here's the Fiddle I'm basing my code from http://jsfiddle.net/gFzCk/
jQuery.text does the heavy lifting for the implementation for the .text() method -- it seems to be an undocumented function with the core functionality for .text(), but missing some jQuery polish.
It's "imported" from Sizzle, where it appears as Sizzle.getText.
Inspecting the jQuery source will reveal that the $(selector).text() that you're familiar with, uses $.text internally:
jQuery.fn.extend({
text: function( value ) {
return jQuery.access( this, function( value ) {
return value === undefined ?
jQuery.text( this ) :
this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) );
}, null, value, arguments.length );
},
It is an undocumented function (which means further jQuery revisions may drop it at will, without notifying you). You'll find its definition as such:
jQuery.text = Sizzle.getText;
Sizzle.getText, in turn, is documented as "Utility function for retrieving the text value of an array of DOM nodes". Seeing as Sizzle.getText is a documented feature, I would recommend using that rather than the jQuery shorthand, as I don't expect jQuery to drop Sizzle any time soon.
This function, then, is the piece of code that yields the text content of a DOM node. Your sorting method is sorting DOM nodes by the alphabetical order of their text content. I don't know why the author has decided to get the text of an array containing only one element ([a]), rather than passing the element immediately (a), which would work equally well.
After looking at your jsfiddle it appears it's a function for getting the text from an element, simular to .text()
console.log(a) logged <td>28/02/2013</td>
While
console.log($.text[a]) logged 28/02/2013
If the code above does something useful (= there is no indication it does according to the jQuery documentation), then it probably calls .text() on a and b.
I'm wondering why the author didn't use $(a).text() because that should do the same. Maybe the code also works no matter whether a is a jquery wrapped node or not :-/
First of all, the brackets. if a is an element, [a] is a element array, so the calls to $.text(...) are passing an array as parameter.
I couldn't find any documentation about jQuery.text but only for jQuery.fn.text. However, you can see that the implementation of jQuery.text handles arrays as parameters as well as scalar values.
In this case, $.text([a]) is probably just the same as $.text(a).
If an element doesn't exist, how do I get a string of the selector that was searched?
For example:
$( 'parent child.class' ).plugin( )
In my plugin, I want to get the string "parent child.class", but $( 'parent child.class' ) doesn't exist.
I'm going to start digging through the jQuery source code, but I figured I'd ask in case someone with more intimate knowledge knows this.
You can't.
jQuery objects have a .selector property, which you could use within your plugin (though it seems to be intended for use interally with jQuery), but - and it's a big but - not all jQuery objects are created with a selector string. Consider this example use of .yourPlugin():
$('div.someClass').add(document.getElementById("test"))
.add("<div>Hello</div>")
.filter(function() {
return $(this).attr("data-test") == "blah";
})
.parents()
.yourPlugin();
It doesn't make sense to be thinking about what selector resulted in the jQuery object eventually passed to .yourPlugin(), regardless of whether it contains any elements.
(I suppose if you know your plugin will only ever be used by you and you'll only ever pass it jQuery objects created with a selector then you could use this.selector within your plugin...)
there is selector property:
$.fn.plugin = function() {
if (this.length == 0) {
return this.selector;
}
};
Let's say I've got a DOM element - how can I tell whether it matches a jQuery selector, such as p or .myclass? It's easy to use the selector to match children of the element, but I want a true/false answer to whether this particular element match?
The element may not have an ID (and I can't assign it a random one for reasons beyond this), so I can't apply my selector to the element's parent and look for children with the same ID as mine.
Will this work as intended? I can't figure out Javascript object comparisons.
$(selector, myElement.parentNode).each({
if (this == myElement) // Found it
});
Seems like there would be an easy way to see whether a DOM element matches a jQuery selector...
You can use the is() method:
if($(this).is("p")){
// ...
}
Without jQuery, using Element.matches():
var elements = document.querySelectorAll('div');
console.log(
elements[0].matches('.foo'), // true
elements[0].matches('.bar'), // false
elements[1].matches('[title=bar]'), // true
)
<div class='foo'></div>
<div title='bar'></div>
See supported browsers list
I believe the is() method is what you are looking for.
Otherwise, you might just try selecting the item directly, if that is what you mean.
So if it's an "a" with a class of "myclass", just do $("a.myclass")
I can't apply my selector to the
element's parent and look for children
with the same ID as mine.
You can't do that anyway - the id attribute must be unique.
Maybe you just want:
$(".complicated #selector p.with > div.manyParts").length
If there are no matches, length returns 0, which is falsy, so you can use it in an if statement, like:
if($(".doesThis #exist").length) {
// Do things
}
Probably would be worth storing it in a separate variable and THEN checking the length; that way, if you need to do anything with the matched elements, you don't have to execute the same selector again.
Try Element.matches()
Element.matches()
document.addEventListener("click", event => {
if (event.target.matches(".elementsClass")) {
// It matches
} else {
// Does not match
}
});