Jquery attribute selector - javascript

I have a variable (div element) which contains some table html.
I can use this javascript to add a class to each cell that has a background set.
var tds = tempDiv.getElementsByTagName("TD");
for (var j = 0; j < tds.length; j++) {
var oTd = tds[j];
if (oTd.style.background.length > 0) {
oTd.className = 'faketh';
oTd.setAttribute('style', 'Clear');
} //if
}//for
what i'd like to do is do the same in jquery. Below is what i've come up with, and the second line works fine, but the first doesn't....
$(tempDiv).find("td[style*='background:']").addClass("faketh");
$(tempDiv).find("td").removeAttr('style');
Any help would be appreciated.
Edit:
Just to add; I'm using the code below without issue.
$(tempDiv).find("tr:odd").addClass('row0');
$(tempDiv).find("tr:even").addClass("row1");
So its not the adding of the class thats the problem... The issue is that i'm not finding any matching elements. Here is one of the td elements;
<td valign="top" class="faketd" style="border: 1pt solid windowtext; padding: 0cm 5.4pt; background: silver none repeat scroll 0% 0%; width: 131.4pt; -moz-background-clip: border; -moz-background-origin: padding; -moz-background-inline-policy: continuous;">
<p style="margin: 0cm 0cm 0pt; text-align: justify;"><strong>VPN Name/Description:</strong></p>
</td>

I don't think you can do this using selectors natively in jQuery. The style attribute is not stored as a string by the browser, it's an object.
It has been implemented, however: http://code.google.com/p/aost/wiki/CustomJQuerySelectorInTellurium#:styles
Or you can use $.each in something like this:
$("img").each(function() {
if($(this).css('background').length > 0) {
$(this).addClass('faketh');
}
});
Or you can use the jQuery filter:
var x = $("#tempDiv td").filter(function(i){
return $(this).css("background").length > 0;
});

try this
$(tempDiv).find("td[style*=background]").addClass("faketh");
EDIT
to prevent selection of elements that have some kind of "background-" you could also do following
$(tempDiv).find("td[style*=background]:not(td[style*=background-])").addClass("faketh");
but if an element has both "background:blabla" and "background-color:#FFF", it won't be selected

A few warnings:
The contents of the style selector should be quoted (check the samples in the Jquery docs), as you have them in the question, not unquoted as others recommend.
Be careful with checking the style attribute in jQuery attribute selectors. The browser may modify the contents of the string (re-ordering, the spacing around the colon, etc.) for it's internal representation, and each browser does this slightly differently.
The most important bit:
Are you using Firefox? I've had trouble with attribute selectors in Firefox once or twice, so if you've only tested in Firefox, check Chrome/IE/Safari/Opera/etc. It won't solve the problem, but may give you a different scope for it.

Depending on what tempDiv is, you should also be able to shorten it up by doing:
$(tempDiv + " td[style*=background:]").addClass("faketh");

You are searching for the string 'background:' but in the example you gave, it's using 'background-color:'
So change it to either:
$(tempDiv).find("td[style*=background-color:]").addClass("faketh");
or:
$(tempDiv).find("td[style*=background]").addClass("faketh");

Related

Javascript/JQuery: How do I select the link inside a <td> element when it has a certain style

There is a website with multiple td elements. I need to a way to click on all the href links inside the td element if it matches a certain style.
Here is what the td element typically looks like
<td style="font-size: 12px; text-align: center; font-weight: bold;"><a class="theclass" href="https://youtube.com" target="_blank">Link</a></td>
Can someone please help guide me on how to do this properly? I tried an if statement to see if the td style matches "font-size: 12px; text-align: center; font-weight: bold;", but it didn't work at all.
Edit: This isn't my website. Sorry, I didn't include this.
It sounds like you are going to have to do a Javascript loop.
function clickCertainStyles() {
$('td').each(function(i, td) {
var $td = $(td);
if ($td.css('font-size') == '12px' && $td.css('text-align') == 'center')
$td.find('a').trigger('click')
})
}
You can make it faster if you pass in a table container, so you aren't searching the whole page for every TD reference.
This will select the td element above:
$('td[style*="font-weight:bold"]')
You'll have to experiment with what works and what doesn't. I tried things like width: 100px and it wouldn't work; presumably anything with a pixel value in it is in some way ambiguous. However, if I used just width it worked for any element that had a width specified.
Note that this only works with inline styles.

How to find all css classes and its css attributes inside a certain div?

i would like to find all classes and ids inside a certain div ! and these css attributes!
Example :
<div class="demo">
<div class="new_class">
<p id="para">This is Demo Paragraph</p>
<a style="background:#ccc">HyperLink</a>
</div>
</div>
<style>
.demo{
height:100px; width:100px; background:#FF0;
}
.new_class{height:40px; width:40px; background:#999;}
#para{color:#E1E1E1;}
</style>
Now The question is that: i would like to find all classes and ids which are used inside demo class ! and Their css values too(which style applying now. ).
I would like to find result as below :
<style>
.demo{
height:100px; width:100px; background:#FF0;
}
.new_class{height:40px; width:40px; background:#999;}
#para{color:#E1E1E1;}
a{background:#ccc;}
</style>
OP, not sure what your purpose is, but in general, this can be useful. I had a project where I needed to embed a fancy template from one site onto a page on a different site with a very different, and conflicting stylesheet. I used some code similar to the following to grab every applied style from the original content, via document.styleSheets, then reapplied them all as inline styles, so I could put it onto the "parent" site without the stylesheets conflicting.
Fiddle
JS
var selector,rule;
var result=[];
var sheets = document.styleSheets;
for (var i in sheets) {
//rules or cssRules, depending on the browser
var rules = sheets[i].rules || sheets[i].cssRules;
//iterate over every css rule in the document
for (var r in rules)
{
selector=rules[r].selectorText;
rule=rules[r].cssText;
//select demo itself, as well as all of its children
$('.demo, .demo *').each(function () {
//console.log($(this),selector);
//for each element, see if it matches the current rule. add if it does
if ($(this).is(selector))
{
result.push(rule);
}
});
}
}
console.log(result);
//result[0] .demo { height: 100px; width: 100px; background: none repeat scroll 0% 0% rgb(255, 255, 0); }
//result[1] .new_class { height: 40px; width: 40px; background: none repeat scroll 0% 0% rgb(153, 153, 153); }
//result[2] #para { color: rgb(225, 225, 225); }
Granted, you will have to tweak this on your own to do things like, removing duplicate styles that would occur if you were to apply this to a larger block of HTML, and for dealing with inline styles (which this does not attempt to do, but you can get them from the style attribute and work from there...), and possibly the computed style, which you can get with getComputedStyle, as indicated by the #Derek's answer. but this should get you started.
To find all existing id, try:
var ids = [];
$(".demo *").each(function(){ this.id && ids.push(this.id); });
console.log(ids);
Do the same thing for class or anything else.
However, to get your expected output, you must first acquire the defined CSS style for each element. Which one should be included? p by default gets margins and paddings. Do you include those too? You will also need to dig into all the CSS declarations just to find the style that are applied, which is almost impossible to do.
For example,
<div class="yellow"></div>
<style>
div.yellow:not(.blue){
background: yellow;
}
</style>
How do you get the background of the <div> tag? .style.background? Nah, it returns "". Well now you will have to reach into the CSS declaration with document.styleSheets to see which one applied. How do you even check if the rule div.yellow:not(.blue) matches your element? Good luck doing that. (There might be libraries that does this kind of thing, or maybe you can even utilize jQuery's internal selector engine with .is, though it will not be the same as in CSS) Another thing you can do is try getComputedStyle. It gives you every single computed styles that aren't even in your declaration. So what you are trying to do is not possible to do. (I don't even know what you are doing something like this.)

How to make css-menu independent of the number of menu items?

I want css-menu width would be 100% of parent element.
But, sometimes menu has 4 items, sometimes it has 5 items and I want menu would be independent of this.
Look images. 1 & 3 are ok. Now menu has 100% width, ok for 4 items:
Now too, but -_-:
Now all fine for 5 items too (I edited css manualy):
I tried to do this next way:
1) I check if user is authorised
2) I calculate li width (perl),
2) I try to change li width parameter (js)
Perl
if ($authorised eq true)
{
$width = 100/5;
}
else
{
$width = 100/4;
}
$widthString = $width."%";
JavaScript code in perl print( java here );
<SCRIPT LANGUAGE="JavaScript">
var li = this.document.getElementsByTagName("li");
for (var i = 0; i < li.length; i++) {
var status = li[i].style.width="'.$widthString.'";
console.log(li[i]);
}
</SCRIPT>
css for li: width: 25%; float: left;
css for ul: width: 100%;
But it not worked for me.
Can anybody explain me why? And for "css" tag followers. I had doubts. Perhaps it is easier to do via css I just do not know.
Thank you.
p.s.: sorry about non-english menu-items, but it's not neccessary for solving problem :)
You can use flexbox! Its part of CSS3 and it's supported in all major browsers!
Working example: http://jsfiddle.net/976eh/3/
the HTML:
<nav>
<a>Hello</a>
<a>World</a>
<a>Hello</a>
<a>World</a>
</nav>
the CSS:
nav {
display: -webkit-flex;
display: -ms-flex;
display: flex;
}
nav>a {
-webkit-flex: 1;
-ms-flex: 1;
flex: 1;
text-align: center;
background: #dadada
}
nav>a:nth-child(odd) {
background: #e5e5e5
}
This is best solved inside the CSS. Consider a table with n columns:
<table>
<tr>
<td> 1 </td>
<td> 2 </td>
<td> 3 </td>
...
<td> n </td>
</tr>
</table>
You can provide the table with a maximum width. Then with table-layout: fixed, the horizontal space is divided equally among all cells. See the jsfiddle here – insert more cells into the row and see how the space is divided.
But do not (mis-)use tables for this! Instead, you can use the CSS display property to assign other elements the behavior of the table, the table-row and the table-cell. Semantic markup is important, after all.
One caveat with this: You should also make sure that you don't insert so many cells that their content overflows. Set minimum widths and control the overflow to guard against this. However, the Flexbox model has better ways to deal with this (e.g. starting another row). See devian's answer for that.
A note on your Perl code: $authorized eq true does not make any sense: Perl does not have a true keyword. This will therefore fail to compile if you put use strict; use warnings; at the top of each Perl source file – consider using this safety net in the future. To test whether a variable contains a true value, simply use it in a condition: if ($authorized) { ... }. To test whether it actually contains the string true, use quotes: if ($authorized eq "true") { ... } (this is how your code is currently interpreted by the compiler).
Make sure your li element is getting the correct width percentage for the quantity of elements you are showing.
If you have 5 elements the li width must be 20% (Example #1). If it's taking 25% instead, it creates an overflow and you end up with image #2 (Example #2).
So, your error must be in your perl code. When you check if it's authorized...
Hope this helps.

Is it possible to subtract a number from inline style injected by JavaScript?

I have an inline style added to the HTML, like style="left: 10px;". Can I add/subtract to that number?
I would like to create a rule where I can remove 8px from that number no matter what that number is.
I tried using the ugly !important hack to override it, but that doesn't help when the initial value is changed.
From 1.6 onwards, you can use the convenient:
$('#myelem').css('left','-=8px')
If for some strange reason you are stuck in the past, use:
$('#myelem').css('left', function(i,v) {
return v - 8;
});
for jQuery 1.4 up.
Maybe you can use margin-left -8px instead. I don't know what you are looking for, but it might do the trick without JavaScript.
There is no CSS rule for such. However, you can do the same using JavaScript.
Assume you have,
.my_left {
left: 10px;
}
And HTML elements like below,
<div class="my_left">My Div</div>
<div class="my_left">My Div</div>
Then using the below script, you can remove 8px from its current left value:
$(function () {
$('.my_left').css('left', function (i, ov) {
return ov - 8;
});
});
You can use a variable for it, in order to be able to add or subtract:
var x=10;
x=x-parseInt(5);
x=x+parseInt(5);
<div id='something' style="left: "+x+"px"></div>
I've recently found on css-tricks that you can override inline css with
.myClassName[style] {
left:5px!important;
}
http://css-tricks.com/override-inline-styles-with-css/

Making line numbers uncopyable

I'm working on adding line number support to Rainbow, a syntax highlighter, but I can't figure out how to make the line numbers uncopyable.
Disabling selection via user-select: none; makes an element unhighlightable, but you can still copy its text by highlighting around it and then copying, which ends up copying the line numbers along with code.
Here is a working example of the problem: http://jsfiddle.net/CjJLv/8/
Any help would be appreciated. Thanks!
Okay, the easiest way in compliant browsers, and, sadly, not reliable cross-browser, is to use generated content (I've removed the various parts where index was being added to textual content in the plug-in, and used the following (at the end of the CSS) to implement un-copyable text:
table.rainbow {
counter-reset: line;
}
table.rainbow tbody tr td:first-child {
counter-increment: line;
}
table.rainbow tr td:first-child::before {
content: counter(line);
}
JS Fiddle demo.
This does, though, have some rather large flaws (the cross-browser unfriendly approach being the biggest), so I'll try for something better...
I would just add a regular list.
if (window.Rainbow) window.Rainbow.linecount = (function(Rainbow) {
Rainbow.onHighlight(function(block) {
var lines = $(block).text().split('\n');
var $lines = $('<ul class="lines"/>');
for (var i = 0, len = lines.length; i < len; i++) {
$lines.append('<li class="line"'+ i +'>'+ i +'</li>');
}
$(block).before($lines);
});
})(window.Rainbow);​
And CSS:
.lines {
float: left;
padding-right: 1.5em;
padding-left: .5em;
}
So now you can select just the code if you highlight carefully.
Demo: http://jsfiddle.net/elclanrs/CjJLv/18/
David Thomas's answer is perfect for line numbers. More generally, if you have other text you don't want to be copied, you can have it as generated content:
<style>#uniqueid::before { content: 'TEXT GOES HERE'; }</style>
<span id="uniqueid"></span>
But it's ugly to have to embed text in your CSS, so you can refine this using CSS attr() to read the text from an attribute in the HTML (as suggested by pimvdb):
<style>[data-nocopy]::before { content: attr(data-nocopy); }</style>
<span data-nocopy="TEXT GOES HERE"></span>
<span data-nocopy="AND HERE"></span>
Demo: http://jsbin.com/fob/1/edit
This works in Firefox, Safari, and Chrome due to 21-year-old(!) bugs in selecting generated content:
https://bugzilla.mozilla.org/show_bug.cgi?id=12460
https://bugs.webkit.org/show_bug.cgi?id=7562
https://bugs.chromium.org/p/chromium/issues/detail?id=80466
But in old IE (< 8) the text will be completely invisible; in newer IE it should be visible but may well be copyable. In general don't use this technique for anything critical, as these bugs might get fixed one day...
And use sparingly, as this can be very user-hostile.
You could display each line number as a sequence of <img>s.

Categories

Resources