[{"data":1,"prerenderedAt":311},["ShallowReactive",2],{"project-15274211":3},{"id":4,"name":5,"line":6,"line_source":7,"title":8,"url":9,"domain":10,"maker":11,"posted_at":12,"year":13,"points":14,"comments":15,"rank_in_year":16,"shown_in_year":17,"top":18,"tier":19,"category":20,"subcategory":21,"format":22,"keywords":23,"reception":29,"sentiment":30,"stance_mix":31,"scored_comments":35,"aspects":36,"strip":45,"post_text":46,"what":47,"said":59,"maker_in_thread":145,"shape":156,"grid":160,"attempts":272,"same_week":273,"maker_shows":243,"maker_hidden":303,"reader_version":304,"card":305},"15274211","SentinelJS","Detect new DOM nodes using CSS selectors","title","Show HN: SentinelJS – Detect new DOM nodes using CSS selectors","https:\u002F\u002Fgithub.com\u002Fmuicss\u002Fsentineljs","github.com","andres",1505723200,2017,90,41,501,2242,23,"notable","dev_tools","dom utility library","library",[24,25,26,27,28],"dom mutation","css selector","animationstart","element detection","javascript","curious",-0.027,{"positive":32,"neutral":33,"mixed":34,"critical":32},5,16,0,26,{"idea":37,"execution":40,"performance":41,"docs":43,"design":44},{"positive":38,"critical":39},1,3,{"positive":38,"critical":38},{"positive":42,"critical":34},2,{"positive":34,"critical":34},{"positive":34,"critical":38},[32,34,34,38,39,39,39,34,34,39,39,39,32,32,38,39,39,34,39,34,34,34,38,32,34,34,38,39,39,39,34,39,39,34,39,34,39,34,32,38],null,{"problem":46,"audience":46,"pricing":46,"motivation":46,"time_to_build":46,"stack":48,"openness":57,"stage":58,"team_size":58},[49],{"value":50,"source":51,"evidence":52},"JavaScript","inferred",[53],{"id":54,"by":55,"text":56},"15274412","cheeaun","From the code, it adds `animationstart` event that will be fired for any newly injected DOM https:\u002F\u002Fgithub.com\u002Fmuicss\u002Fsentineljs\u002Fblob\u002Fmaster\u002Fsrc\u002Fsentinel.js#L14 It adds a faux…","open_source","unknown",{"praise":60,"objections":80,"requests":104,"questions":105,"alternatives":121},[61,73],{"value":62,"source":63,"evidence":64},"Clever use of CSS animation events to detect insertions","commenter",[65,69],{"id":66,"by":67,"text":68},"15274416","projectant","It adds a stylesheet to accept new stylerules. For every element set (CSS selector) you want to watch it adds a new stylerule that makes a no-op animation happen (transform:none…",{"id":70,"by":71,"text":72},"15274676","superasn","Wow that is just super clever and I'm guessing super fast also since it is triggered by the browser. I was thinking more on the lines of comparing nodes using setInterval which…",{"value":74,"source":63,"evidence":75},"Useful for managing behaviors on a page",[76],{"id":77,"by":78,"text":79},"15274457","rstacruz","Nice work! I've also done a similar thing (https:\u002F\u002Fgithub.com\u002Frstacruz\u002Fonmount), and it's really useful in managing behaviors in a page. For those wondering what this is for,…",[81,92],{"value":82,"source":63,"evidence":83},"Relies on a CSS animation hack that browsers may optimise away",[84,88],{"id":85,"by":86,"text":87},"15275307","gcb0","it will break when browser optimize a null animation, just like tons of code used to detect if some ad was in view in the past broke. edit: already happened once with this very…",{"id":89,"by":90,"text":91},"15274429","yeasayer","What's the difference between SentinelJS and DOM Mutation Observers? I glanced at the source code, it seems this lib is using some kind of hack based on CSS animations. Why not…",{"value":93,"source":63,"evidence":94},"MutationObserver is the standard API and makes this unnecessary",[95,99,100],{"id":96,"by":97,"text":98},"15274417","have_faith","Don't we have mutation observers for this exact purpose? or is there a benefit to this approach?",{"id":89,"by":90,"text":91},{"id":101,"by":102,"text":103},"15274857","paulirish","MutationObserver could handle this case instead of the animationstart hack yeah. Here's one impl I found:…",[],[106,111],{"value":107,"source":63,"evidence":108},"Why not use MutationObserver instead",[109,110],{"id":96,"by":97,"text":98},{"id":89,"by":90,"text":91},{"value":112,"source":63,"evidence":113},"Does it fire for elements present before DOMContentLoaded",[114,118],{"id":115,"by":116,"text":117},"15274426","spand","If the author is watching this thread or anyone else. Would this work for elements not yet loaded by the browser before DOMContentLoaded?",{"id":119,"by":116,"text":120},"15274552","Thanks for the response and sorry. Maybe I was not quite clear. I was attempting ask if it would trigger the event handler before DOMContentLoaded (relevant on big document where…",[122,130,134,141],{"value":123,"source":63,"evidence":124},"MutationObserver",[125,126],{"id":96,"by":97,"text":98},{"id":127,"by":128,"text":129},"15277923","moheeb","I have used mutation observers to do exactly this. They are very simple to use.",{"value":131,"source":63,"evidence":132},"onmount (rstacruz)",[133],{"id":77,"by":78,"text":79},{"value":135,"source":63,"evidence":136},"SelectorListener",[137],{"id":138,"by":139,"text":140},"15274527","atmin","And implementation by the same author: https:\u002F\u002Fgithub.com\u002Fcsuwildcat\u002FSelectorListener",{"value":142,"source":63,"evidence":143},"wait-for-element.js",[144],{"id":101,"by":102,"text":103},{"comments":32,"answered":42,"key":146},[147,150,153],{"id":148,"text":149},"15278016","Can you give an example of how you would do this with mutation observers?",{"id":151,"text":152},"15280436","Do you have an example of this technique? I just tried using your technique but I couldn't get it to work.",{"id":154,"text":155},"15274467","Yes. SentinelJS will trigger a watch for elements present when DOMContentLoaded fires and for elements added dynamically afterwards. In the Quickstart example, there's an element…",{"commenters":157,"max_depth":158,"maker_replies":32,"first_comment_mins":159,"lifespan_hours":157},31,4,46,[161,163,167,170,174,177,178,179,181,185,187,188,191,193,195,197,200,203,207,208,212,214,217,218,221,224,227,230,233,236,238,239,242,244,246,247,250,255,258,263,268],[77,34,32,162,78,34],"project\u002Fpositive\u002Fidea",[164,34,34,165,166,34],"15274568","other\u002Fpositive\u002Fdocs","skrebbel",[168,34,34,165,169,34],"15275094","aoeusnth1",[171,34,38,172,173,34],"15276277","project\u002Fcritical\u002Fidea","Lord_Zero",[175,34,39,176,78,34],"15281793","project\u002Fneutral\u002Fidea",[96,38,39,176,97,34],[127,38,39,176,128,34],[148,38,34,180,11,38],"project\u002Fneutral\u002Fexecution",[182,38,34,183,184,34],"15281928","other\u002Fneutral\u002Fdocs","mikerybka",[186,42,39,180,71,34],"15274391",[54,42,39,180,55,34],[189,42,39,180,190,34],"15274413","ry_ry",[66,42,32,192,67,34],"project\u002Fpositive\u002Fexecution",[70,42,32,194,71,34],"project\u002Fpositive\u002Fperformance",[85,42,38,196,86,34],"project\u002Fcritical\u002Fexecution",[198,39,39,176,199,34],"15274577","robocat",[201,39,39,176,202,34],"15274595","kccqzy",[204,39,34,205,206,34],"15274829","other\u002Fneutral\u002Fnone","mercer",[101,39,39,180,102,34],[209,158,34,210,211,34],"15279978","other\u002Fneutral\u002Fidea","c-smile",[151,158,34,213,11,38],"maker\u002Fneutral\u002Fdocs",[215,158,34,205,216,34],"15285550","wiredearp",[89,32,38,172,90,34],[219,32,32,194,220,34],"15274606","onion2k",[222,32,34,223,102,34],"15274833","other\u002Fneutral\u002Fperformance",[225,32,34,223,226,34],"15274834","nailer",[228,229,38,172,190,34],"15274390",6,[231,229,39,176,232,34],"15274405","Arnt",[234,229,39,176,235,34],"15274424","myhf",[237,229,39,176,190,34],"15274468",[138,229,34,205,139,34],[240,229,39,176,241,34],"15275221","daurnimator",[115,243,39,180,116,34],7,[154,243,34,245,11,38],"maker\u002Fneutral\u002Fexecution",[119,243,39,245,116,34],[248,243,34,249,11,38],"15274608","maker\u002Fpositive\u002Fexecution",[251,252,39,253,254,34],"15274525",8,"project\u002Fneutral\u002Fdocs","SimeVidas",[256,252,34,257,11,38],"15274531","maker\u002Fneutral\u002Fnone",[259,260,32,261,262,34],"15276077",9,"project\u002Fpositive\u002Fnone","ryanb23",[264,265,38,266,267,34],"15274669",10,"project\u002Fcritical\u002Fdesign","danhardman",[269,265,34,270,271,34],"15276785","commenter\u002Fneutral\u002Fdesign","wolfgang42",[],[274,278,283,288,293,298],{"id":275,"name":276,"points":277,"category":20},"15277351","Doogie",264,{"id":279,"name":280,"points":281,"category":282},"15270799","No Coin",254,"security_privacy",{"id":284,"name":285,"points":286,"category":287},"15290607","Redox Rust OS",232,"infrastructure",{"id":289,"name":290,"points":291,"category":292},"15256215","Nulis",231,"productivity",{"id":294,"name":295,"points":296,"category":297},"15264053","Hyperapp",216,"languages",{"id":299,"name":300,"points":301,"category":302},"15246145","Coinhive",212,"finance_crypto",false,"v2",{"id":306,"name":5,"line":6,"ai":303,"cat":20,"year":13,"points":14,"comments":15,"rec":29,"s":307,"top":18,"kw":308,"maker":11,"domain":10,"tier":19,"attempts":34,"strip":309,"url":9,"mix":310,"praise":62,"objection":82,"sub":21},15274211,-0.03,[24,25,26,27,28],"5001333003335513303000150013330330303051",[32,33,34,32],1793990964048]