Javascript get the dom element a function was called from - javascript

HTML part:
foo
JS part:
function callme() {
var me = ?; //someway to get the dom element of the a-tag
$(me).toggle();
}
in the JS part can i somehow get the a-tag that this function was called from?
i know i could just pass it as a parameter, but this function is used many many times on a page and i want to avoid putting the parameter everywhere.
thanks!

Since you are using an onclick attribute (BAD!) you have to pass that into the function.
onclick="callme(this); return false;"
and the js:
function callme(el) {
var $me = $(el);
$me.doSomething();
}
Another option is to set the context of the function using .call().
onclick="callme.call(this,event)"
and the js
function callme(event) {
event.preventDefault();
$(this).doSomething();
}

I have a simple JS function for that
function getEventTarget(event) {
var targetElement = null;
try {
if (typeof event.target != "undefined") {
targetElement = event.target;
}
else {
targetElement = event.srcElement;
}
// just make sure this works as inteneded
if (targetElement != null && targetElement.nodeType && targetElement.parentNode) {
while (targetElement.nodeType == 3 && targetElement.parentNode != null) {
targetElement = targetElement.parentNode;
}
}
} catch (ex) { alert("getEventTarget failed: " + ex); }
return targetElement;
};
in your html
foo
in your function
function callme(event) {
var me = getEventTarget(event); //someway to get the dom element of the a-tag
$('#'+ me.id).toggle();
}
getEventTarget() will bring back the whole dom object which you can manipulate as you please, or has been said already by other users you can just use
function callme(event) {
$(this).toggle();
}

send this parameter to your function.
foo
function callme(me) {
$(me).toggle();
}

better dont use onlcick in html markup
$(document).ready(function() {
$("a").click(callme);
})
function callme() {
var me = this;
$(me).toggle();
}

Related

The meaning of this.$pop

The site Read-city uses the function function Popup (pop, name, html, handlers) in the file Read-city - online store of books_files\popup.js.Untitled, which creates a login/registration window (see https://ru.stackoverflow.com/questions/1194356/%d0%9e%d0%b1%d1%8a%d0%b5%d0%ba%d1%82-%d0%ba%d0%bb%d0%b0%d1%81%d1%81-popup )
function Popup (pop, name, html, handlers) {
if (html) {
$(document.body).append(html);
}
handlers = handlers || {};
this.$pop = $(pop);
this.selector = pop;
this.name = name;
this.$pop_wrapper = this.$pop.parent('.js__popup_main_wrapper');
Popup.instances[this.name] = this;
this.$pop.on('click', '.popup__close, .js__popup__close', this.hide.bind(this));
//Закрытие попапа при клике на маску и при нажатии Esc
if (this.$pop_wrapper) {
this.$pop_wrapper.on('click', function(event) {
var mask_wrapper = event.target;
if (mask_wrapper.classList.contains('js__popup_main_wrapper')) {
Popup.hideAll();
}
});
}
$(document).keyup(function(event) {
if (event.keyCode === 27) {
Popup.hideAll();
}
});
this.$body = this.$pop.find('.popup__body_text');
this.onshow = handlers.show || null;
this.onhide= handlers.hide || null;
this.events = {
closePopup: 'closePopup',
openPopup: 'openPopup'
}
}
Popup.instances = {};
Popup.getInstance = function(name, pop, html, handlers) {
if(Popup.instances[name]){
return Popup.instances[name];
}
if (pop){
return new Popup(pop, name, html, handlers);
}
return null;
};
Popup.hideAll = function() {
for (var popupName in Popup.instances) {
if(Popup.instances.hasOwnProperty(popupName)){
Popup.instances[popupName].hide();
}
}
};
Popup.prototype.show = function() {
Popup.hideAll();
//Скрываем скролл
$('body').css('overflow', 'hidden');
// временный костыль
// почему-то не всегда инициализируется dom-элемент попапа
if (!this.$pop.length) this.$pop = $(this.selector);
if (!this.$pop.length) return;
if (this.$pop_wrapper) {
this.$pop_wrapper.css("display", "flex");
}
this.$pop
.removeClass('hidden')
.addClass('shown')
.attr('data-opened', '');
this.onshow ? this.onshow() : null;
if (window.userCity && window.userCity.hideBlock) { //если открыт попап города(актуально для мобильной версии)
//то закрыть блок выбора города
window.userCity.hideBlock();
}
//создадим событие открытия попапа
eventEmitter.dispatch(this.events.openPopup, {
popupName: this.name,
popup: this.$pop
});
};
Popup.prototype.hide = function() {
this.$pop
.removeClass('shown')
.addClass('hidden')
.removeAttr('data-opened');
this.onhide ? this.onhide() : null;
if (this.$pop_wrapper) {
this.$pop_wrapper.fadeOut(50);
}
var opened = $('[data-opened]').length;
if (opened === 0) {
//Возвращаем скролл
$('body').css('overflow', 'auto');
}
eventEmitter.dispatch(this.events.closePopup, {
popupName: this.name,
popup: this.$pop
});
};
Popup.prototype.setBodyText = function (text){
if(!text){
return;
}
this.$body.html(text);
};
Explain
the meaning of the pop property
action of the operator this.$pop = $(pop)
and also the syntax of this.$pop.on ('click', '.popup__close, .js__popup__close', this.hide.bind (this)); is not clear.
1) the meaning of the pop property
It is whatever someone named a property to be. Sounds like it is the short name for pop up. But a variable name can be anything....
2) action of the operator this.$pop = $(pop)
It is taking a jQuery object return and puts it into a property. It is not uncommon for people to use $ in a variable name to denote it is a jQuery object and not a DOM reference.
3) and also the syntax of this.$pop.on ('click', '.popup__close, .js__popup__close', this.hide.bind (this)); is not clear.
It is the basic syntax of jQuery for attaching event listeners https://api.jquery.com/on
Very quickly, here is my take on this just looking at the code you provided.
I would say pop would be a html string selector / HTML element/ jQuery element.
That action should be creating an instance of a jQuery element. This element will help out interacting with pop HTML element under the jQuery "framework". A quick jQuery tutorial: https://www.w3schools.com/jquery/
It is part of the jQuery framework. Instead of addEventListener, it uses an on method to bind events. https://api.jquery.com/on/
Looking at the rest of the code, I'm pretty sure it is using jQuery.

Liferay/AlloyUI: Overriding util.js or disabling scrolling on form focus

How can I override (or hook) the function Liferay.Util.focusFormField in Liferay 7.0?
The method is defined in frontend-js-aui-web (portal-src\modules\apps\foundation\frontend-js\frontend-js-aui-web\src\main\resources\META-INF\resources\liferay\util.js).
The only way I could think of is to just overwrite it somewhere in a js-file, like so:
Liferay.Util.focusFormField = function(el) {
var doc = $(document);
var interacting = false;
el = Util.getDOM(el);
el = $(el);
doc.on(
'click.focusFormField',
function (event) {
interacting = true;
doc.off('click.focusFormField');
}
);
if (!interacting && Util.inBrowserView(el)) {
var form = el.closest('form');
var focusable = !el.is(':disabled') && !el.is(':hidden') && !el.parents(':disabled').length;
if (!form.length || focusable) {
el.focus(false); // modified
}
else {
var portletName = form.data('fm-namespace');
Liferay.once(
portletName + 'formReady',
function () {
el.focus(false); // modified
}
);
}
}
}
All I actually want is to disable the scrolling that happens whenever a form is submitted.
Does someone know what to do best to achieve this?
Another thing I found on the web is this: https://alloyui.com/api/files/alloy-ui_src_aui-form-validator_js_aui-form-validator.js.html#l216
But I cannot find it in liferay-7.0-source-files and no explanation how to override it.

How to get current object you working with

I need to process an AJAX request twice, first, when the site has been opened first time, and second, when a button is clicked. I dont want to write 2 similar functions. So I created an ajaxPost function. I wonder how to detect what event has called the ajaxPost function? opening the browser or clicking a button?
function ajaxPost() {
url = "post.php";
if (this!=Window) {
button = $(this).attr("class");
} else {
button = "";
}
var posting = $.post(url,{"button": button});
posting.done(function(data) {
$(".word").html(data);
});
}
$(document).ready(function() {
ajaxPost();
$("input[type=button]").click(ajaxPost);
});
Check for the jQuery event that you're passing with a click.
function ajaxPost(event) {
url = "post.php";
if (event == undefined || event == null) { //Was not generated by a user click
button = $(this).attr("class");
} else {
button = "";
}
var posting = $.post(url,{"button": button});
posting.done(function(data) {
$(".word").html(data);
});
}
$(document).ready(function() {
ajaxPost();
$("input[type=button]").click(ajaxPost);
});
A simple solution would be to include an additional parameter when calling the function:
function ajaxPost( caller ) {
switch( caller ){
case "initial_load":
// called on page load
break;
case "button_click":
// called on button click
break;
}
...
}
Now you would need to pass this parameter from the two different types of calls:
$(document).ready(function() {
ajaxPost( "initial_load" );
$("input[type=button]").on( "click", function(){
ajaxPost( "button_click" );
});
});

Uncaught ReferenceError: X is not defined

This code is being used on a Chrome Extension.
When I call the "showOrHideYT()" function, I get a
"Uncaught ReferenceError: showOrHideYT is not defined | (anonymous
function) | onclick"
This code will search for youtube links in a page, and it will add a button (it's really a div with an event) next to the link to show the iframe with the embedded video, pretty much like Reddit Enhancement Suite. Consider the code, per se, incomplete. I just want to know what am i missing when i call the "showOrHideYT(frameZES12345)" function.
if needed, i can provide manifest.json.
Thanks
function showOrHideYT(id)
{
var YTvidWidth = 420;
var YTvidHeight = 315;
frameYT=getElementById(id);
console.log(frameYT.style.visibility);
if (frameYT.style.visibility == "hidden")
{
frameYT.style.width = YTvidWidth+"px";
frameYT.style.height = YTvidHeight+"px";
frameYT.style.visibility = "visible";
}
if (frameYT.style.visibility == "visible")
{
frameYT.style.width = "0px";
frameYT.style.height = "0px";
frameYT.style.visibility = "hidden";
}
};
// DOM utility functions
function insertAfter( referenceNode, newNode ) {
if ((typeof(referenceNode) == 'undefined') || (referenceNode == null)) {
console.log(arguments.callee.caller);
} else if ((typeof(referenceNode.parentNode) != 'undefined') && (typeof(referenceNode.nextSibling) != 'undefined')) {
if (referenceNode.parentNode == null) {
console.log(arguments.callee.caller);
} else {
referenceNode.parentNode.insertBefore( newNode, referenceNode.nextSibling );
}
}
};
function createElementWithID(elementType, id, classname) {
obj = document.createElement(elementType);
if (id != null) {
obj.setAttribute('id', id);
}
if ((typeof(classname) != 'undefined') && (classname != '')) {
obj.setAttribute('class', classname);
}
return obj;
};
///////////////////////////////////////
$(document).ready(function() {
var vidWidth = 420;
var vidHeight = 315;
var linksSemID = document.getElementsByTagName("a") ;
for (var i = 0; i < linksSemID.length; i++){
if (/id=$/.test(linksSemID[i].href)) links[i].href += "1";
}
i=0;
var youTubeRegExp = /(?:v=)([\w\-]+)/g;
var forEach = Array.prototype.forEach;
var linkArray = document.getElementsByTagName('a');
forEach.call(linkArray, function(link){
linkArray.id="zes" + i++;
var linkTarget = link.getAttribute('href');
if (linkTarget!=null)
{
if (linkTarget.search(youTubeRegExp) !=-1)
{
console.log (linkTarget);
idVideo=linkTarget.match(/(?:v=)([\w\-]+)/g);
//idVideo = idVideo.replace("v=", "");
//add buton
botaoMais = document.createElement('DIV');
botaoMais.setAttribute('class','expando-button collapsed video');
botaoMais.setAttribute('onclick','showOrHideYT(frameZES'+ i +')');
insertAfter(link, botaoMais);
//add iframe
ifrm = document.createElement('IFRAME');
ifrm.setAttribute('src', 'http://www.youtube.com/embed/'+ idVideo);
ifrm.style.width = '0px';
ifrm.style.height = '0px';
ifrm.style.frameborder='0px';
ifrm.style.visibility = 'hidden';
ifrm.setAttribute('id', 'frameZES' + i);
insertAfter(link, ifrm);
}
}
});
});
When you use setAttribute with a string, the event will be executed in the context of the page. The functions which are defined in a Content script are executed in a sandboxed scope. So, you have to pass a function reference, instead of a string:
Replace:
botaoMais.setAttribute('onclick','showOrHideYT(frameZES'+ i +')');
With:
botaoMais.addEventListener('click', (function(i) {
return function() {
showOrHideYT("frameZES"+ i);
};
})(i));
Explanation of code:
(function(i) { ..})(i) is used to preserve the value of i for each event.
Inside this self-invoking function, another function is returned, used as an event listener to click.
I see that you are using jQuery in your code. I personally think if we are using a library like jQuery, then we should not mix the native javascript code and jQuery code.
You can use jQuery bind to bind your the functions you need to call on dom ready.
Read below to know more.
suppose you want to call a javascript function on a button click, Here is the HTML for the same.
<div id="clickme">
<input id= "clickmebutton" type="button" value = "clickme" />
</div>
suppose "test" is the function you need to call, here is the code for test function.
function test() {
alert("hello");
}
you now need to bind the test function on the button click.
$(document).ready(function() {
$("#clickmebutton").bind("click", function(){
// do what ever you want to do here
test();
});
});

How to detect if some text box is changed via external script?

I have some jQuery plugin that changes some elements, i need some event or jQuery plugin that trigger an event when some text input value changed.
I've downloaded jquery.textchange plugin, it is a good plugin but doesn't detect changes via external source.
#MSS -- Alright, this is a kludge but it works:
When I call boxWatcher() I set the value to 3,000 but you'd need to do it much more often, like maybe 100 or 300.
http://jsfiddle.net/N9zBA/8/
var theOldContent = $('#theID').val().trim();
var theNewContent = "";
function boxWatcher(milSecondsBetweenChecks) {
var theLoop = setInterval(function() {
theNewContent = $('#theID').val().trim();
if (theOldContent == theNewContent) {
return; //no change
}
clearInterval(theLoop);//stop looping
handleContentChange();
}, milSecondsBetweenChecks);
};
function handleContentChange() {
alert('content has changed');
//restart boxWatcher
theOldContent = theNewContent;//reset theOldContent
boxWatcher(3000);//3000 is about 3 seconds
}
function buttonClick() {
$('#theID').value = 'asd;lfikjasd;fkj';
}
$(document).ready(function() {
boxWatcher(3000);
})
try to set the old value into a global variable then fire onkeypress event on your text input and compare between old and new values of it. some thing like that
var oldvlaue = $('#myInput').val();
$('#myInput').keyup(function(){
if(oldvlaue!=$('#myInput').val().trim())
{
alert('text has been changed');
}
});
you test this example here
Edit
try to add an EventListner to your text input, I don't know more about it but you can check this Post it may help
Thanks to #Darin because of his/her solution I've marked as the answer, but i have made some small jQuery plugin to achieve the same work named 'txtChgMon'.
(function ($) {
$.fn.txtChgMon = function (func) {
var res = this.each(function () {
txts[0] = { t: this, f: func, oldT: $(this).val(), newT: '' };
});
if (!watchStarted) {
boxWatcher(200);
}
return res;
};
})(jQuery);
var txts = [];
var watchStarted = false;
function boxWatcher(milSecondsBetweenChecks) {
watchStarted = true;
var theLoop = setInterval(function () {
for (var i = 0; i < txts.length; i++) {
txts[i].newT = $(txts[i].t).val();
if (txts[i].newT == txts[i].oldT) {
return; //no change
}
clearInterval(theLoop); //stop looping
txts[i].f(txts[i], txts[i].oldT, txts[i].newT);
txts[i].oldT = $(txts[i].t).val();
boxWatcher(milSecondsBetweenChecks);
return;
}
}, milSecondsBetweenChecks);
}

Categories