Run jQuery function only if CSS class is present - javascript

I made a simple jQuery function that trims text. I trigger it this way:
// JS
function truncate() {
<! – Stuff to do -->
}
truncate();
// ...
// HTML
<div class="Truncate" data-words="60">
<! – Text to Trim -->
</div>
The problem is that the function gives me an error every time I load a page that doesn't have a DIV with the class 'Truncate' on it.
So I'd like to trigger it only when that <div> is there.
Actually I'd like that the <div> itself triggers the function.
I know I can wrap it in an IF statement checking for the class, but I was wondering if with jQuery I can call it over a selector, something like:
$('.Truncate').myfunctionName() {
my stuff
};
That is creative syntax, just to make you understand.
...Thanks in advance.

Simple answer If I got it right.
function doStuff(elements) {
console.log('doing stuff...');
}
$(function() {
var truncates = $('.Truncate');
if (truncates.length) { // here you validate if there is any element with that class
doStuff(truncates);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="Truncate"></div>

Here is a js code with an IFEE function:
(function(){
var elmTranc=document.getElementsByClassName('Truncate');
if(elmTranc){
for(var i=0;i<elmTranc.length;i++){
elmTranc[i].innerHTML.trim();
}
}
})();

Another simple solution using querySelector https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector
if(document.querySelector(".Truncate")){ //if element with .Truncate exists
truncate();
}

You can create a mini jquery plugin:
// include jquery first
$.fn.truncate = function() {
return $(this).each(function() {
$(this).text($(this).text().substr(0, 2));
});
};
$(".truncate").truncate()
$(".someotherclass").truncate();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='truncate'>Abc</div>
<div class='truncate'>Xyz</div>
<div class='notruncate'>123</div>

I've done this in the end...
if( $('.Truncate').length ) {
(function() {
suff
})();
}
Is it ok?

Related

Invoke a custom method on a DOM element

I want to invoke a custom method on a DOM element
like this :
<div id="MyObject">
<!-- some elements -->
</div>
<script>
function doSomething() {
// do something with input DOM element
}
$("MyObject").doSomething();
</script>
How can I develop this problem? Is it necessary to use jQuery or not?
You do not need to use jQuery. You can use document.getElementById('MyObject') to get a reference to the DOM node.
To run your doSomething function on it, you would need to add a node parameter to it something like this:
function doSomething(input) {
// do something with input DOM element
}
doSomething(document.getElementById('MyObject'));
To have it chained, you would need to add to the Element interface which all DOM nodes implement (rereading, I meant inherit from). If you go that way, you could do:
Element.prototype.doSomething = function() {
alert(this);
}
document.getElementById('MyObject').doSomething();
JSFiddle: http://jsfiddle.net/6Lyb4b9p/
MDN: getElementById
Without jQuery, you could do something like
if (typeof $ != 'function') {
//create a function $ which will return the element with said id
window.$ = function(id) {
return document.getElementById(id);
}
}
//Add a method to the Elemen prototype so you can call it on any element object
Element.prototype.doSomething = function() {
this.innerHTML = 'hi from inner';
}
$('MyObject').doSomething();
<div id="MyObject">
<!-- some elements -->
</div>
I found the answer by myself.
I can practice in this way :
<script>
(function ($) {
$.fn.doSomething = function () {
// do something like this
$(this).append("Hello Object");
}
} (jQuery));
$("#MyDOMElement").doSomething();
</script>

Jquery hasClass issue

im trying to check if one of the DIV's has class "visible" which is being add by a jquery plugin, it seems not to work.
it works when i check the first element, but if i want to check next div, it doenst finds it.
help is appreciated.
My DIV
<div class="swiper-slide welcome" id="welcome"></div>
2nd DIV
<div class="swiper-slide intro-early-life" id="intro-early-life"></div>
MY JQUERY
<script type="text/javascript">
$(document).ready(function() {
if ($('.welcome').hasClass('swiper-slide-visible')) {
alert("working");
}
});
</script>
Im not using same ID, maybe it was my bad explanation. I can use the class as well, no difference.
$(document).ready(function() {
if ($('#welcome').hasClass('swiper-slide') && $('#welcome').hasClass('visible')) {
alert("working");
}
});
if ($('#welcome').is(":visible") && $('#welcome').hasClass("swiper-slide")) {
alert("Yeah!");
}
Perhaps that would work better?
Edit: Also swiper-slide-visible class doesn't exist on the page - perhaps this is the issue...?
You can use also as
$(document).ready(function() {
if ($('#welcome').hasClasses(['swiper-slide', 'visible']);) {
alert("working");
}
});
$.fn.extend({
hasClasses: function (selectors) {
var self = this;
for (var i in selectors) {
if ($(self).hasClass(selectors[i]))
return true;
}
return false;
}
});
Use .is()
if ($('#welcome').is('.swiper-slide, .visible'){
Id Must Be unique you can use classes instaed
Two HTML elements with same id attribute: How bad is it really?
You could use .is() instead:
$(document).ready(function() {
if ($('.welcome').is('.swiper-slide.visible')) {
alert("working");
}
});

How to write this Javascript code to show/hide for each personal elements?

How can I write this code in a loop?
Actually I am using some different links to show and hide box for each related link. I want to show/hide box for each link showing information related to that link.
function hidedetailbox1()
{document.getElementById("plc1").style.display="none";}
function showdetailbox1()
{document.getElementById("plc1").style.display="block";}
function hidedetailbox2()
{ document.getElementById("plc2").style.display="none";}
function showdetailbox2()
{document.getElementById("plc2").style.display="block"; }
function hidedetailbox3()
{document.getElementById("plc3").style.display="none";}
function showdetailbox3()
{document.getElementById("plc3").style.display="block"; }
function hidedetailbox4()
{document.getElementById("plc4").style.display="none";}
function showdetailbox4()
{document.getElementById("plc4").style.display="block";}
function hidedetailbox5()
{document.getElementById("plc5").style.display="none";}
function showdetailbox5()
{document.getElementById("plc5").style.display="block";}
function hidedetailbox6()
{document.getElementById("plc6").style.display="none";}
function showdetailbox6()
{document.getElementById("plc6").style.display="block";}
function hidedetailbox7()
{document.getElementById("plc7").style.display="none";}
function showdetailbox7()
{document.getElementById("plc7").style.display="block";}
function hidedetailbox8()
{document.getElementById("plc8").style.display="none";}
function showdetailbox8()
{document.getElementById("plc8").style.display="block";}
function hidedetailbox9()
{document.getElementById("plc9").style.display="none";}
function showdetailbox9()
{document.getElementById("plc9").style.display="block";}
function hidedetailbox10()
{document.getElementById("plc10").style.display="none";}
function showdetailbox10()
{document.getElementById("plc10").style.display="block";}
function hidedetailbox11()
{document.getElementById("plc11").style.display="none";}
function showdetailbox11()
{document.getElementById("plc11").style.display="block";}
function hidedetailbox12()
{document.getElementById("plc12").style.display="none";}
function showdetailbox12()
{document.getElementById("plc12").style.display="block";}
function hidedetailbox13()
{document.getElementById("plc13").style.display="none";}
function showdetailbox13()
{document.getElementById("plc13").style.display="block";}
You could use a function like this...
var toggleDisplay = function(i, hide) {
document.getElementById('plc' + i).style.display = hide ? 'none' : '';
}
You pass it the number (as i) and whether it should hide or reset (as hide) the display property.
function hidedetailbox(id){
....
Suppose you have 10 comments listed in the page,
when you display it from the server, in your server script keep a count like
<div id="1">comment1</div>
<div id="2">comment2</div>
<div id="3">comment3</div>
etc...
if it's any other content like a image, you can use
<...name="1"....>
now you can handle them in a loop like this,
for(i++){
getElementById(i); //handle it the way you want here.
}
further if you have a specific name for the element, you can concat with the "i"
like
getElementById("comment"+i);
Suggestion: you can use jquery to do this for you
.toggle() .show() .hide() can be a good thing to look at..
Good luck :)
Since you mentioned jquery. You can use toggle
$('.boxlink').click(function(e) {
$($(e.target).attr('href')).toggle();
return false;
});
Your links in HTML will look something like this:
Toggle PLC 1
Toggle PLC 2
toggle example:
<html>
<head>
<script type="text/javascript">
var toggleDisplay = function(id) {
if (document.getElementById(id).style.display == 'none'){
document.getElementById(id).style.display = '';
}
else {
document.getElementById(id).style.display = 'none';
}
}
</script>
</head>
<body>
<table>
<tr><td onmouseover="toggleDisplay(1);">Test toggle</td><td id=1 name=1 >Toggle me!</td></tr>
</table>
</body>
</html>

initialize jquery after append

I have a list of blocks, for each block their is a css change by jquery on mouseover/out.
I have a button that is job is to add one more block to the list.
It do it great! But the new block not respond to the mouseover/out jquery set.
This is my blocks and the add:
<div class='blocks'>
<div class='block'>
<div class='block-top'></div>
Default Text Here
</div>
<div class='block'>
<div class='block-top'></div>
Default Text Here
</div>
<div class='block'>
<div class='block-top'></div>
Default Text Here
</div>
</div>
<a href='#' id='addBlock'>Add Block</a>
And this is the javascipt:
$(document).ready(function() {
var inEdit=0;
$(".block").hoverIntent(function() {
if(inEdit==0) {
$(this).children('.block-top').delay(300).animate({opacity:1},600);
$(this).delay(300).animate({borderColor: '#8f8f8f'},600);
}
},function() {
if(inEdit==0) {
$(this).children('.block-top').animate({opacity:0},200);
$(this).animate({borderColor: '#ffffff'},200);
}
});
$('#addBlock').click(function() {
$('.blocks').append("<div class='block'><div class='block-top'></div>Default Text Here</div>");
});
});
I'm using this two scripts:
http://www.bitstorm.org/jquery/color-animation/
http://cherne.net/brian/resources/jquery.hoverIntent.html
What can I do?
Thanks
If you wish that future elements benefits from the event, you have to use on : http://api.jquery.com/on/
For instance :
$('#addBlock').on('click', function() {
$('.blocks').append("<div class='block'><div class='block-top'></div>Default Text Here</div>");
});
You are binding the hoverintent to the element which doesnt exist on load. Therefore the new element wont get the event handler. You have to use .Delegate() or .on()/.off() depending on your version of jQuery Information on how to use each can be found below
http://api.jquery.com/delegate/
http://api.jquery.com/on/
However as hoverIntent uses jquerys mouseover i dont know if it has a specific eventType you can use for delegate/on
This question is about using hoverIntent on new elements. There is exactly this other thread about the same thing, check out the answer :
help with understanding the logic behind how javascript executes on new dom elements being created on the fly
make use of jquery live() method, i.e) use below codes
$(".block").live('hoverIntent', function() { //this line is modified
if(inEdit==0) {
$(this).children('.block-top').delay(300).animate({opacity:1},600);
$(this).delay(300).animate({borderColor: '#8f8f8f'},600);
}
},function() {
if(inEdit==0) {
$(this).children('.block-top').animate({opacity:0},200);
$(this).animate({borderColor: '#ffffff'},200);
}
});
make some adjustments to add 2 functions for the event 'hoverIntent'. I mean this will work
$(".block").live('hoverIntent', function() { //this line is modified
if(inEdit==0) {
$(this).children('.block-top').delay(300).animate({opacity:1},600);
$(this).delay(300).animate({borderColor: '#8f8f8f'},600);
}
});
but to have 2 functions you can try like
$(".block").live('hoverIntent', function() { //this line is modified
if(inEdit==0) {
$(this).children('.block-top').delay(400).animate({opacity:1},600);
$(this).delay(400).animate({borderColor: '#8f8f8f'},600);
}
if(inEdit==0) {
$(this).children('.block-top').animate({opacity:0},200);
$(this).animate({borderColor: '#ffffff'},200);
}
});

Best way to modify an element that is not yet created

I have an <input> field in my web page, and I want to add a particular method on it, let say fooBar().
Here is what I do:
<input id="xxx" .../>
<script type="text/javascript">
$("xxx").fooBar = function() { ... };
</script>
This works well. However, for some reasons I will not detail here (in fact the HTML is generated by JSF components), the <script> will be declared before the <input> tag.
So in others words, I will have that in my HTML:
<script type="text/javascript">
$("xxx").fooBar = function() { ... };
</script>
<input id="xxx" .../>
So of course this code will not work correctly, as the script will try to get ($("xxx")) and modify an element that does not exist yet.
If I want to stick on the exact order of these two tags, what is the best way to accomplish what I want?
Edit
In my case, $ refers to prototype, but I am also using jQuery in my application. And I must be compatible with IE6 :o(
You need to run your script after the document is loaded. With jQuery you'd do that with:
$(document).ready(function () {
//do stuff here
});
I can't tell which library you're using here, but they all have an equivalent of jQuery's document ready.
Here's the prototype equivalent:
document.observe("dom:loaded", function() {
// do stuff
});
Try putting your code in load event:
$(window).load(function(){
$("#xxx").fooBar = function() { ... };
});
If the code has to be directly before the input, you can check if it has loaded after a certain period of time.
<script type="text/javascript">
//Sets up a function to execute once the input is loaded
f = function ()
{
//Checks if 'xxx' exists (may vary between frameworks)
if ($("xxx") !== undefined)
{
$("xxx").fooBar = function() { ... };
//Escapes the timer function, preventing it from running again
return true;
}
//If still not loaded check again in half a second (0.5s or 500ms)
setTimeout(f,500);
return false;
}
f();//Initialize the timer function
</script>
<input id="xxx" .../>
Instead of adding a method to the dom node, why not make it a separate function, so instead of
$("xxx").fooBar = function() {
doStuff(this);
};
you would have something like
function xxx_fooBar () {
var me = document.getElementById('xxx');
doStuff(me);
};
Another suggestion: If you can add attributes to the <input> element, you could do something like this...
<script>
function xxx_init (e) {
e.fooBar = function () {
doStuff(this);
};
}
</script>
<input onload="xxx_init(this)" id="xxx" .../>
Or you could do as others suggest and attach the scripts to the window.onload event.

Categories