How can I disable certain alert on the page and allow others?
I tried With this code:
window.alert = function ( text ) {
console.log(text);
if(!text.includes("rambo"))
alert("rambo");
};
This won't work because it calls alert again and not the alert.
I need to use javascript alert( not any other libraries)
Save a reference to the old window.alert first.
const oldAlert = window.alert;
window.alert = function ( text ) {
console.log(text);
if(!text.includes("rambo"))
oldAlert(text);
return true;
};
window.alert('ram');
window.alert('rambo');
The other two answers are mostly correct, but they pollute the global namespace by creating a new reference to window.alert. So I would suggest wrapping this in an IIFE:
(function() {
var nativeAlert = window.alert;
window.alert = function(message) {
if (message.includes("test")) {
nativeAlert(message);
}
};
}());
alert("Hello"); // Doesn't show up.
alert("Hello test"); // Works.
nativeAlert("test"); // Throws an error.
You could go a step further an create an alert function generator that creates an alert object using a predicate:
function alertGenerator(predicate) {
if (typeof predicate === "function") {
return function(message) {
if (predicate(message) === true) {
window.alert(message);
}
}
} else {
return undefined;
}
}
// Create an alert generator that requires the word "test" in it:
var testAlert = alertGenerator(t => t.includes("test"));
testAlert("Hello"); // Doesn't show up.
testAlert("Hello test"); // Works.
// Create an alert generator that requires the word "Hello" in it:
var helloAlert = alertGenerator(t => t.includes("Hello"));
helloAlert("Hello"); // Works.
helloAlert("Hello test"); // Works.
helloAlert("Test"); // Doesn't work.
You can store old alter in variable
var ar = alert;
window.alert = function(text) {
console.log(text);
if (!text.includes("rambo"))
ar("rambo");
return true;
};
alert('dfs');
If you don't wan't to pollute global namespace or use an IIFE, why don't you simply wrap window.alert in another function like this:
function myCustomAlert(message) {
return message.includes('rambo') ?
window.alert(message)
: false;
}
myCustomAlert("This message won't be shown!");
myCustomAlert("This message will be shown because it contains rambo");
Related
Trying to do something that in pseudo code would look like this:
(function(scope) {
scope.doSomenthin = function() {
if (x === y && this.onfinish) {
// If exists, run onfinish, should return 'fin'
this.onfinish();
}
}
})(scope);
window.scope = window.scope || (window.scope = {});
scope.doSomenthin().onfinish = function(){return 'fin'}
At run time if onfinish exists, run that function. Tried using getters/setter but at that point it will return undefined. Setting a timeout works but its not something I wish to do.
Any other ideas? Thanks.
I'm not sure if I completely understand the question, but I think what you want comes down to setting the context for the functions you are calling. Is this what you are after?
//create a function that accesses an object's properties and methods with 'this'
var doSomethin = function() {
var result = "nonfinish";
if (this.onfinish) {
// If exists, run onfinish, should return 'fin'
result = this.onfinish();
}
return result;
}
//add an 'onfinish' method to the 'scope' object
scope = {
onfinish: function(){return 'fin'}
}
//run the accessor function in the window context
alert(doSomethin());
//run the accessor function in scope's context
alert(doSomethin.call(scope));
I see several mistakes with your code. This may be the results you are trying to achieve..
window.scope = window.scope || (window.scope = {});
scope.onfinish = function(){return 'fin'};
(function(scope) {
scope.doSomenthin = function() {
if (this.onfinish) {
// If exists, run onfinish, should return 'fin'
return this.onfinish();
}
}
})(scope);
alert(scope.doSomenthin());
When you create the temporary scope here you give scope as a
parameter. But scope is not defined yet.
(function(scope) {
scope.doSomenthin = function() {
if (x === y && this.onfinish) {
// If exists, run onfinish, should return 'fin'
this.onfinish();
}
}
})(scope);
Your scope.doSomenthin function doesn't return any value. Because
of that the value of scope.doSomenthin() is undifined. Therefore
with scope.doSomenthin().onfinish = function(){return 'fin'} you
are trying to set a property of undifined.
What you want to approach is similar to event-driven programming. Don't just call the function right away, register it as an event handler instead. The following pseudo-code only shows my idea. It's not complete
//register the function here, instead of calling it immediately
event = document.createEvent("HTMLEvents");
event.initEvent("myEvent", true, true);
document.addEventListener("myEvent", function(e) {
e.scope.doSomenthin = function() {
if (this.onfinish) {
// If exists, run onfinish, should return 'fin'
return this.onfinish();
}
}
});
......
//call the handler to handle the below event
window.scope = window.scope || (window.scope = {});
scope.doSomenthin().onfinish = function(){return 'fin'}
event.scope = scope;
document.body.dispatchEvent(event);
The above code is kind of silly. You have to design where to put and trigger the events.
Ok, so I'm a complete newbie to OOP in Javascript, apparently. I thought I understood it, but it appears I only know a small portion. Anyway, what I'm trying to do is setup an object to store and return data from an XML input by using a fairly simple string to retrieve data. I'd like to retrieve the data with a string similar to reader.getItem().getSubItem() or something like that.
Below is an example of what I attempted, but I get the error anonymous is not a function each time I try to do a call to fr.getType().isTexture() so obviously, I need to change something.
//Create the object by passing an XML element containing sub-elements
var fr = new FeatureReader(test.child(i));
alert(fr.getName()); //returns the object's name
alert(fr.getType().isTexture()); //"anonymous is not a function" error
function FeatureReader(feature) {
var feat = feature;
this.getName = function() {
return feat.name;
};
this.getType = new function() {
this.isTexture = new function() {
if (feat.type.texture == "yes") {
return true;
}
return false;
};
this.isModel = new function() {
if (feat.type.model == "yes") {
return true;
}
return false;
};
};
}
Now, obviously I could just remove the surrounding this.getType = function() {} around the this.isTexture and this.isModel to get my data, but for the sake of learning something, I'd like to see how it is recommended that I set this object up to get the returned values using a string similar to what I mentioned in the first and second paragraphs.
When you do this:
this.isTexture = new function() {
if (feat.type.texture == "yes") {
return true;
}
return false;
};
you're setting the "isTexture" property to the object constructed, not to that function. If you drop the new keyword from the statement, you'll be setting "isTexture" to be a function.
An expression of the form new <some-function> evaluates to an object, in other words.
edit — your "getType" property will also be an object, for the same reason. However, I think this would work:
alert( fr.getType.isTexture() );
Also note that your if statement can be simplified:
return feat.type.texture == "yes";
What you can do is simply assign an object instead of using new:
function FeatureReader(feature) {
var feat = feature;
this.getName = function() {
return feat.name;
};
this.getType = {
isTexture: function() {
return feat.type.texture == "yes";
},
isModel: function() {
return feat.type.model == "yes";
}
};
}
Then use the method like:
instance.getType.isTexture()
Note that you don't need to return true or false, as returning an expression that evaluates to boolean like a == b
returns a boolean value.
I was reading through fluent api I got a doubt.
I want to take in a string upon which a jQuery function or example is called upon
Function
function compareThis(newString) {
function compare(newString) {
if (this == newString) {
alert("same string");
} else {
alert("differnt string");
}
}
}
Where it is called as
("alerting").compareThis("alerted").compare(); //alert 'different string'
I want to pass the data/string not as parameter but as called upon.
JSFiddle
Note: I would like to call the function in similar cases like finding date interval etc
You can use prototype to add function to String class:
String.prototype.compare = function(newString){
if (this == newString) {
alert("same string");
} else {
alert("differnt string");
}
};
I think you should adapt the code for your function, but it's the idea.
Maybe I missed interpreted however, it looks as it you required a form of method chaining to compare string. To do this you can create a variable and create functions inside it.
var compare = (function(){
var thisString;
var stringToCompare;
var create = function(sVal) {
thisString = sVal;
return this;
};
// Public
var compareThis = function(sVal) {
stringToCompare = sVal;
return this;
};
var compare = function(anotherString) {
return thisString == stringToCompare;
};
return {
create: create,
compareThis: compareThis,
compare: compare
};
}());
var b = compare.create('test').compareThis('test').compare();
alert(b);
Example fiddle
there are several function will have to get the dom $$('.box')[0] ,
I don't want to let box to be a glabal var, and I don't want to let js seek the
dom every time . and I don't want to run $$('.box')[0] when user not run these functions.
how to store the box var?
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/mootools/1.4.5/mootools-yui-compressed.js"></script>
<script type="text/javascript">
/* -------
there are several function will have to get the dom $$('.box')[0] ,
I don't want to let box to be a glabal var, and I don't want to let js seek the
dom every time . and I don't want to run $$('.box')[0] when user not run these functions.
how to store the box var?
------- */
function a(){
var box = $$('.box')[0];
//...
}
function b(){
var box = $$('.box')[0];
//...
}
//...
</script>
<div class="box"></div>
I don't know if this would help, but you could separate the getting of it into a function and only allow it to be executed once. I forget where I got this function from, but it's useful for only allowing a function to run once (and every other time it's called, just return the value):
function once(func) {
// Function wrapper to only allow a function, *func*, to be called once.
var ran = false, ret = undefined;
return function () {
if (ran) {
return ret;
}
ran = true;
ret = func.apply(this, arguments);
return ret;
};
}
So I would use it like:
var getBox = once(function () {
return $$('.box')[0];
});
And just always use getBox() when you want to get the element. Only the first time you call it will the DOM be searched. Every time after that, it'll just return the box.
While this might "help", it is just as good as creating a global variable, so I'm not exactly sure what you expect as a solution.
try creating a pseusdo namespace, and within it, an application cache
var mySpace = (function(){
var appcache = {};
function a(){
var box = appcache.box0
|| (appcache.box0 = $$('.box')[0], appcache.box0);
//...
}
function b(){
var box = appcache.box0
|| (appcache.box0 = $$('.box')[0], appcache.box0);
//...
}
return {a: a, b: b};
}());
// usage: you can call a or b like
mySpace.a();
mySpace.b();
you should really use a closure then.
(function(scope){
var box = box document.getElement('.box'); // same as $$()[0], returns first match
scope.a = function(){
return box;
};
scope.b = function(){
box;
};
}(this)); // whatever object, eg, window or a namespace
box; // reference error.
this.a(); // box element object
box will remain private and also static, i.e. it wont get refreshed anymore.
you can do it so it's referenced and cached once when needed:
(function(scope){
var box;
scope.a = function(){
box = box || document.getElement('.box');
return box;
};
scope.b = function(){
// alt syntax;
box || (box = document.getElement('.box'));
return box;
};
}(this)); // whatever object, eg, window or a namespace
this way, calling either method will cache box and make it available for any of the methods in the closure.
declare your box variable out of the scope of functions
var box = "";
function a(){
if(box != "" || box != undefined || box != 'undefined')
alert(box +" from a");
else
box = $$('.box')[0];
}
function b(){
if(box != "" || box != undefined || box != 'undefined')
alert(box + " from b");
else
box = $$('.box')[0];
}
If you are worried about performance, just give your box an id and call it using
var element = null;
function myFun(){
if(!element)
element = $('#myId');
//Do logic
}
I want to write some log class that can be used like the following code.
// short-hand for logging.
log('log message', [other parameter]);
// full path for writing log.
log.write('log message', [other parameter]);
// print all log
log.print([optional parameter]);
Moreover, it must able to be written as fluent pattern.
log.write('log message').print();
Finally, it should be resetted by using the following code.
log = new log();
Thanks,
Let's implement it as a normal object first, then add some other syntaxes after:
var log = {};
log.write = function() {
// stuff...
return this;
};
log.print = function() {
// stuff...
return this;
};
log.reset = function() {
// stuff
return this;
};
As function is also an object, it can have properties, so you can replace var log = {};, with a function that redirects to log.write instead.
function log() {
return log.write.apply(log, arguments);
}
Finally, for the self-reset syntax, you can detect for a new instance, but instead of creating a new object, you reset the log and hand the same object back!
So now the log function will look like this:
function log() {
if (this instanceof log) {
return log.reset.apply(log, arguments);
}
return log.write.apply(log, arguments);
}
You can look at jsFiddle to see that it works. Warning: lot of alert()s on that page!
var Logger = function(msg,p){
this.msg = typeof msg != 'undefined' ? msg : '';
this.p = typeof p != 'undefined' ? p : '';
}
Logger.prototype = {
write : function(msg,p){
this.msg = typeof msg != 'undefined' ? msg : '';
this.p = typeof p != 'undefined' ? p : '';
},
print : function(p){
this.p = typeof p == 'undefined' ? this.p : p;
if(this.p)
alert(this.msg);
else
console.log(this.msg);
return this;
},
reset : function(){
return new Logger();
}
}
function log(msg,p){
return new Logger(msg,p).print();
}
And then you can use :
log("alert me",true);
log("log me in console!");
log().write("a msg",false).print();
var l = log();
l.write().print().reset();
Doesn't console.log in firebug serve the purpose of logging? Though, one can write their own logger implementation. But the question is when should the logger to be used? Implementation similar like you have proposed could be useful in javascript running in server side like Rhino
But i have written some code, pls try this
<html>
<head>
<script>
var log = function() {
var p_this = this;
this.write = function(p_msg){
p_this.msg = p_msg;
return this.write;
},
this.write.print = function(){
alert(p_this.msg);
}
};
var log1 = new log();
log1.write('test_message').print();
</script>
</head>
<body>
</body>
</html>
This may be helpful. This a conceptual code for the pattern u are looking for. You have to modify this or improve this. You may provide the logic for resetting and all.
You could try this glorious masterpiece:
var log = (function(out){
var msgs = [];
function log(msg){
if (typeof msg == 'string'){
msgs.push(msg);
return log;}
else{
msgs = [];
return log;}}
log.write = function(msg){
log(msg);
return log;};
log.print = function(){
for(var i=0, l=msgs.length; i<l; i++){
out(msgs[i]);}};
return log;})(function(s){console.log(s);});
The real output function is injected at the end. You should test for console.log to exist, and use an alternative otherwise (I do not know what you would prefer).
I tried the following things:
log('First message');
log.write('Second message')('Third message').write('Fourth message');
log.write('Fifth message').print();
log.print(); // Prints all messages again.
log = new log(); // Reset.
log('Lonely!').print(); // Prints only 'Lonely!'.
Beware: log(); or log(undefined); (with undefined undefined) will reset the thing as well, while new log('Foobar'); will add the message 'Foobar'. But this was not in your test cases, so I ignored it.
This is also possible:
(new log()).write('Message');
(new log())('Message');
(new log()).print(); // Prints empty log.
Try to look at JSLog javascript logging framework:
https://github.com/dingyonglaw/JSLog
It supports all browser, and also firebug-lite;
==============
Example Usage:
==============
Logging:
--------
// Register a module logger, p is now logger for 'App.Login'
var p = JSLog.Register('App.Login');
// Log something, and it will display "[App.Login] something" in your console;
p.log('something');
// You can do something as usual:
p.warn('warning!');
p.info('info msg');
Log Level:
----------
The Logger comes with 5 level of logging access: 1-5
which coresponding to: 'error', 'warn', 'info', 'debug', 'log'
// You can set your level like this, to display only info message in console
p.SetLevel(3);
// You can get your current logging level with:
p.GetLevel();
Logging History:
----------------
The logger records your logs and you can Dump it later!
// Dump by Module Name
JSLog.Dump('App.Login');
// Dump all modules in nested view
JSLog.Dump();
// Selective Dump by filtering module name:
JSLog.SetFilter('module-name');
JSLog.Dump(); // Will exclude 'module-name' module
// Clear filter by module name:
JSLog.UnsetFilter('module-name');
// Get assigned filters
JSLog.GetFilter();